~james-w/+junk/fuse-debian-upstream

« back to all changes in this revision

Viewing changes to kernel/inode.c

  • Committer: James Westby
  • Date: 2008-05-16 12:57:40 UTC
  • Revision ID: jw+debian@jameswestby.net-20080516125740-fn2iqsxtfd3olmib
Tags: upstream-debian-2.2.1
Import upstream from fuse_2.2.1.orig.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  FUSE: Filesystem in Userspace
 
3
  Copyright (C) 2001-2005  Miklos Szeredi <miklos@szeredi.hu>
 
4
 
 
5
  This program can be distributed under the terms of the GNU GPL.
 
6
  See the file COPYING.
 
7
*/
 
8
 
 
9
#include "fuse_i.h"
 
10
 
 
11
#include <linux/pagemap.h>
 
12
#include <linux/slab.h>
 
13
#include <linux/file.h>
 
14
#include <linux/mount.h>
 
15
#include <linux/seq_file.h>
 
16
#include <linux/init.h>
 
17
#include <linux/module.h>
 
18
#ifdef KERNEL_2_6
 
19
#include <linux/parser.h>
 
20
#include <linux/statfs.h>
 
21
#else
 
22
#include "compat/parser.h"
 
23
#endif
 
24
 
 
25
MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
 
26
MODULE_DESCRIPTION("Filesystem in Userspace");
 
27
#ifdef MODULE_LICENSE
 
28
MODULE_LICENSE("GPL");
 
29
#endif
 
30
 
 
31
spinlock_t fuse_lock;
 
32
static kmem_cache_t *fuse_inode_cachep;
 
33
 
 
34
#define FUSE_SUPER_MAGIC 0x65735546
 
35
 
 
36
#ifndef KERNEL_2_6
 
37
#define kstatfs statfs
 
38
#endif
 
39
#ifndef MAX_LFS_FILESIZE
 
40
#define MAX_LFS_FILESIZE (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
 
41
#endif
 
42
struct fuse_mount_data {
 
43
        int fd;
 
44
        unsigned rootmode;
 
45
        unsigned user_id;
 
46
        unsigned flags;
 
47
        unsigned max_read;
 
48
};
 
49
 
 
50
static struct inode *fuse_alloc_inode(struct super_block *sb)
 
51
{
 
52
        struct inode *inode;
 
53
        struct fuse_inode *fi;
 
54
 
 
55
        inode = kmem_cache_alloc(fuse_inode_cachep, SLAB_KERNEL);
 
56
        if (!inode)
 
57
                return NULL;
 
58
 
 
59
#ifndef KERNEL_2_6
 
60
        inode->u.generic_ip = NULL;
 
61
#endif
 
62
        fi = get_fuse_inode(inode);
 
63
        fi->i_time = jiffies - 1;
 
64
        fi->nodeid = 0;
 
65
        fi->forget_req = fuse_request_alloc();
 
66
        if (!fi->forget_req) {
 
67
                kmem_cache_free(fuse_inode_cachep, inode);
 
68
                return NULL;
 
69
        }
 
70
 
 
71
        return inode;
 
72
}
 
73
 
 
74
static void fuse_destroy_inode(struct inode *inode)
 
75
{
 
76
        struct fuse_inode *fi = get_fuse_inode(inode);
 
77
        if (fi->forget_req)
 
78
                fuse_request_free(fi->forget_req);
 
79
        kmem_cache_free(fuse_inode_cachep, inode);
 
80
}
 
81
 
 
82
static void fuse_read_inode(struct inode *inode)
 
83
{
 
84
        /* No op */
 
85
}
 
86
 
 
87
void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
 
88
                      unsigned long nodeid, int version)
 
89
{
 
90
        struct fuse_forget_in *inarg = &req->misc.forget_in;
 
91
        inarg->version = version;
 
92
        req->in.h.opcode = FUSE_FORGET;
 
93
        req->in.h.nodeid = nodeid;
 
94
        req->in.numargs = 1;
 
95
        req->in.args[0].size = sizeof(struct fuse_forget_in);
 
96
        req->in.args[0].value = inarg;
 
97
        request_send_noreply(fc, req);
 
98
}
 
99
 
 
100
static void fuse_clear_inode(struct inode *inode)
 
101
{
 
102
        struct fuse_conn *fc = get_fuse_conn(inode);
 
103
        if (fc) {
 
104
                struct fuse_inode *fi = get_fuse_inode(inode);
 
105
                fuse_send_forget(fc, fi->forget_req, fi->nodeid, inode->i_version);
 
106
                fi->forget_req = NULL;
 
107
        }
 
108
}
 
109
 
 
110
void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
 
111
{
 
112
        if (S_ISREG(inode->i_mode) && i_size_read(inode) != attr->size)
 
113
#ifdef KERNEL_2_6
 
114
                invalidate_inode_pages(inode->i_mapping);
 
115
#else
 
116
                invalidate_inode_pages(inode);
 
117
#endif
 
118
 
 
119
        inode->i_ino     = attr->ino;
 
120
        inode->i_mode    = (inode->i_mode & S_IFMT) + (attr->mode & 07777);
 
121
        inode->i_nlink   = attr->nlink;
 
122
        inode->i_uid     = attr->uid;
 
123
        inode->i_gid     = attr->gid;
 
124
        i_size_write(inode, attr->size);
 
125
        inode->i_blksize = PAGE_CACHE_SIZE;
 
126
        inode->i_blocks  = attr->blocks;
 
127
#ifdef KERNEL_2_6
 
128
        inode->i_atime.tv_sec   = attr->atime;
 
129
        inode->i_atime.tv_nsec  = attr->atimensec;
 
130
        inode->i_mtime.tv_sec   = attr->mtime;
 
131
        inode->i_mtime.tv_nsec  = attr->mtimensec;
 
132
        inode->i_ctime.tv_sec   = attr->ctime;
 
133
        inode->i_ctime.tv_nsec  = attr->ctimensec;
 
134
#else
 
135
        inode->i_atime   = attr->atime;
 
136
        inode->i_mtime   = attr->mtime;
 
137
        inode->i_ctime   = attr->ctime;
 
138
#endif
 
139
}
 
140
 
 
141
static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
 
142
{
 
143
        inode->i_mode = attr->mode & S_IFMT;
 
144
        i_size_write(inode, attr->size);
 
145
        if (S_ISREG(inode->i_mode)) {
 
146
                fuse_init_common(inode);
 
147
                fuse_init_file_inode(inode);
 
148
        } else if (S_ISDIR(inode->i_mode))
 
149
                fuse_init_dir(inode);
 
150
        else if (S_ISLNK(inode->i_mode))
 
151
                fuse_init_symlink(inode);
 
152
        else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
 
153
                 S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
 
154
                fuse_init_common(inode);
 
155
                init_special_inode(inode, inode->i_mode,
 
156
                                   new_decode_dev(attr->rdev));
 
157
        } else {
 
158
                /* Don't let user create weird files */
 
159
                inode->i_mode = S_IFREG;
 
160
                fuse_init_common(inode);
 
161
                fuse_init_file_inode(inode);
 
162
        }
 
163
}
 
164
 
 
165
#ifdef KERNEL_2_6
 
166
static int fuse_inode_eq(struct inode *inode, void *_nodeidp)
 
167
{
 
168
        unsigned long nodeid = *(unsigned long *) _nodeidp;
 
169
        if (get_node_id(inode) == nodeid)
 
170
                return 1;
 
171
        else
 
172
                return 0;
 
173
}
 
174
 
 
175
static int fuse_inode_set(struct inode *inode, void *_nodeidp)
 
176
{
 
177
        unsigned long nodeid = *(unsigned long *) _nodeidp;
 
178
        get_fuse_inode(inode)->nodeid = nodeid;
 
179
        return 0;
 
180
}
 
181
 
 
182
struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
 
183
                        int generation, struct fuse_attr *attr, int version)
 
184
{
 
185
        struct inode *inode;
 
186
        struct fuse_conn *fc = get_fuse_conn_super(sb);
 
187
        int retried = 0;
 
188
 
 
189
 retry:
 
190
        inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set, &nodeid);
 
191
        if (!inode)
 
192
                return NULL;
 
193
 
 
194
        if ((inode->i_state & I_NEW)) {
 
195
                inode->i_generation = generation;
 
196
                inode->i_data.backing_dev_info = &fc->bdi;
 
197
                fuse_init_inode(inode, attr);
 
198
                unlock_new_inode(inode);
 
199
        } else if ((inode->i_mode ^ attr->mode) & S_IFMT) {
 
200
                BUG_ON(retried);
 
201
                /* Inode has changed type, any I/O on the old should fail */
 
202
                make_bad_inode(inode);
 
203
                iput(inode);
 
204
                retried = 1;
 
205
                goto retry;
 
206
        }
 
207
 
 
208
        fuse_change_attributes(inode, attr);
 
209
        inode->i_version = version;
 
210
        return inode;
 
211
}
 
212
#else
 
213
static int fuse_inode_eq(struct inode *inode, unsigned long ino, void *_nodeidp){
 
214
        unsigned long nodeid = *(unsigned long *) _nodeidp;
 
215
        if (inode->u.generic_ip && get_node_id(inode) == nodeid)
 
216
                return 1;
 
217
        else
 
218
                return 0;
 
219
}
 
220
 
 
221
struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
 
222
                        int generation, struct fuse_attr *attr, int version)
 
223
{
 
224
        struct inode *inode;
 
225
        int retried = 0;
 
226
 
 
227
 retry:
 
228
        inode = iget4(sb, attr->ino, fuse_inode_eq, &nodeid);
 
229
        if (!inode)
 
230
                return NULL;
 
231
 
 
232
        if (!inode->u.generic_ip) {
 
233
                get_fuse_inode(inode)->nodeid = nodeid;
 
234
                inode->u.generic_ip = inode;
 
235
                inode->i_generation = generation;
 
236
                fuse_init_inode(inode, attr);
 
237
        } else if ((inode->i_mode ^ attr->mode) & S_IFMT) {
 
238
                BUG_ON(retried);
 
239
                /* Inode has changed type, any I/O on the old should fail */
 
240
                remove_inode_hash(inode);
 
241
                make_bad_inode(inode);
 
242
                iput(inode);
 
243
                retried = 1;
 
244
                goto retry;
 
245
        }
 
246
 
 
247
        fuse_change_attributes(inode, attr);
 
248
        inode->i_version = version;
 
249
        return inode;
 
250
}
 
251
#endif
 
252
 
 
253
static void fuse_put_super(struct super_block *sb)
 
254
{
 
255
        struct fuse_conn *fc = get_fuse_conn_super(sb);
 
256
 
 
257
        spin_lock(&fuse_lock);
 
258
        fc->sb = NULL;
 
259
        fc->user_id = 0;
 
260
        fc->flags = 0;
 
261
        /* Flush all readers on this fs */
 
262
        wake_up_all(&fc->waitq);
 
263
        fuse_release_conn(fc);
 
264
        *get_fuse_conn_super_p(sb) = NULL;
 
265
        spin_unlock(&fuse_lock);
 
266
}
 
267
 
 
268
static void convert_fuse_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr)
 
269
{
 
270
        stbuf->f_type    = FUSE_SUPER_MAGIC;
 
271
        stbuf->f_bsize   = attr->bsize;
 
272
        stbuf->f_blocks  = attr->blocks;
 
273
        stbuf->f_bfree   = attr->bfree;
 
274
        stbuf->f_bavail  = attr->bavail;
 
275
        stbuf->f_files   = attr->files;
 
276
        stbuf->f_ffree   = attr->ffree;
 
277
        stbuf->f_namelen = attr->namelen;
 
278
        /* fsid is left zero */
 
279
}
 
280
 
 
281
static int fuse_statfs(struct super_block *sb, struct kstatfs *buf)
 
282
{
 
283
        struct fuse_conn *fc = get_fuse_conn_super(sb);
 
284
        struct fuse_req *req;
 
285
        struct fuse_statfs_out outarg;
 
286
        int err;
 
287
 
 
288
        req = fuse_get_request(fc);
 
289
        if (!req)
 
290
                return -ERESTARTSYS;
 
291
 
 
292
        req->in.numargs = 0;
 
293
        req->in.h.opcode = FUSE_STATFS;
 
294
        req->out.numargs = 1;
 
295
        req->out.args[0].size = sizeof(outarg);
 
296
        req->out.args[0].value = &outarg;
 
297
        request_send(fc, req);
 
298
        err = req->out.h.error;
 
299
        if (!err)
 
300
                convert_fuse_statfs(buf, &outarg.st);
 
301
        fuse_put_request(fc, req);
 
302
        return err;
 
303
}
 
304
 
 
305
enum {
 
306
        OPT_FD,
 
307
        OPT_ROOTMODE,
 
308
        OPT_USER_ID,
 
309
        OPT_DEFAULT_PERMISSIONS,
 
310
        OPT_ALLOW_OTHER,
 
311
        OPT_ALLOW_ROOT,
 
312
        OPT_KERNEL_CACHE,
 
313
#ifndef KERNEL_2_6
 
314
        OPT_LARGE_READ,
 
315
#endif
 
316
        OPT_DIRECT_IO,
 
317
        OPT_MAX_READ,
 
318
        OPT_ERR
 
319
};
 
320
 
 
321
static match_table_t tokens = {
 
322
        {OPT_FD,                        "fd=%u"},
 
323
        {OPT_ROOTMODE,                  "rootmode=%o"},
 
324
        {OPT_USER_ID,                   "user_id=%u"},
 
325
        {OPT_DEFAULT_PERMISSIONS,       "default_permissions"},
 
326
        {OPT_ALLOW_OTHER,               "allow_other"},
 
327
        {OPT_ALLOW_ROOT,                "allow_root"},
 
328
        {OPT_KERNEL_CACHE,              "kernel_cache"},
 
329
#ifndef KERNEL_2_6
 
330
        {OPT_LARGE_READ,                "large_read"},
 
331
#endif
 
332
        {OPT_DIRECT_IO,                 "direct_io"},
 
333
        {OPT_MAX_READ,                  "max_read=%u"},
 
334
        {OPT_ERR,                       NULL}
 
335
};
 
336
 
 
337
static int parse_fuse_opt(char *opt, struct fuse_mount_data *d)
 
338
{
 
339
        char *p;
 
340
        memset(d, 0, sizeof(struct fuse_mount_data));
 
341
        d->fd = -1;
 
342
        d->max_read = ~0;
 
343
 
 
344
        while ((p = strsep(&opt, ",")) != NULL) {
 
345
                int token;
 
346
                int value;
 
347
                substring_t args[MAX_OPT_ARGS];
 
348
                if (!*p)
 
349
                        continue;
 
350
 
 
351
                token = match_token(p, tokens, args);
 
352
                switch (token) {
 
353
                case OPT_FD:
 
354
                        if (match_int(&args[0], &value))
 
355
                                return 0;
 
356
                        d->fd = value;
 
357
                        break;
 
358
 
 
359
                case OPT_ROOTMODE:
 
360
                        if (match_octal(&args[0], &value))
 
361
                                return 0;
 
362
                        d->rootmode = value;
 
363
                        break;
 
364
 
 
365
                case OPT_USER_ID:
 
366
                        if (match_int(&args[0], &value))
 
367
                                return 0;
 
368
                        d->user_id = value;
 
369
                        break;
 
370
 
 
371
                case OPT_DEFAULT_PERMISSIONS:
 
372
                        d->flags |= FUSE_DEFAULT_PERMISSIONS;
 
373
                        break;
 
374
 
 
375
                case OPT_ALLOW_OTHER:
 
376
                        d->flags |= FUSE_ALLOW_OTHER;
 
377
                        break;
 
378
 
 
379
                case OPT_ALLOW_ROOT:
 
380
                        d->flags |= FUSE_ALLOW_ROOT;
 
381
                        break;
 
382
 
 
383
                case OPT_KERNEL_CACHE:
 
384
                        d->flags |= FUSE_KERNEL_CACHE;
 
385
                        break;
 
386
 
 
387
#ifndef KERNEL_2_6
 
388
                case OPT_LARGE_READ:
 
389
                        d->flags |= FUSE_LARGE_READ;
 
390
                        break;
 
391
#endif
 
392
                case OPT_DIRECT_IO:
 
393
                        d->flags |= FUSE_DIRECT_IO;
 
394
                        break;
 
395
 
 
396
                case OPT_MAX_READ:
 
397
                        if (match_int(&args[0], &value))
 
398
                                return 0;
 
399
                        d->max_read = value;
 
400
                        break;
 
401
 
 
402
                default:
 
403
                        return 0;
 
404
                }
 
405
        }
 
406
        if (d->fd == -1)
 
407
                return 0;
 
408
 
 
409
        return 1;
 
410
}
 
411
 
 
412
static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt)
 
413
{
 
414
        struct fuse_conn *fc = get_fuse_conn_super(mnt->mnt_sb);
 
415
 
 
416
        seq_printf(m, ",user_id=%u", fc->user_id);
 
417
        if (fc->flags & FUSE_DEFAULT_PERMISSIONS)
 
418
                seq_puts(m, ",default_permissions");
 
419
        if (fc->flags & FUSE_ALLOW_OTHER)
 
420
                seq_puts(m, ",allow_other");
 
421
        if (fc->flags & FUSE_ALLOW_ROOT)
 
422
                seq_puts(m, ",allow_root");
 
423
        if (fc->flags & FUSE_KERNEL_CACHE)
 
424
                seq_puts(m, ",kernel_cache");
 
425
#ifndef KERNEL_2_6
 
426
        if (fc->flags & FUSE_LARGE_READ)
 
427
                seq_puts(m, ",large_read");
 
428
#endif
 
429
        if (fc->flags & FUSE_DIRECT_IO)
 
430
                seq_puts(m, ",direct_io");
 
431
        if (fc->max_read != ~0)
 
432
                seq_printf(m, ",max_read=%u", fc->max_read);
 
433
        return 0;
 
434
}
 
435
 
 
436
static void free_conn(struct fuse_conn *fc)
 
437
{
 
438
        while (!list_empty(&fc->unused_list)) {
 
439
                struct fuse_req *req;
 
440
                req = list_entry(fc->unused_list.next, struct fuse_req, list);
 
441
                list_del(&req->list);
 
442
                fuse_request_free(req);
 
443
        }
 
444
        kfree(fc);
 
445
}
 
446
 
 
447
/* Must be called with the fuse lock held */
 
448
void fuse_release_conn(struct fuse_conn *fc)
 
449
{
 
450
        if (!fc->sb && !fc->file)
 
451
                free_conn(fc);
 
452
}
 
453
 
 
454
static struct fuse_conn *new_conn(void)
 
455
{
 
456
        struct fuse_conn *fc;
 
457
 
 
458
        fc = kmalloc(sizeof(*fc), GFP_KERNEL);
 
459
        if (fc != NULL) {
 
460
                int i;
 
461
                memset(fc, 0, sizeof(*fc));
 
462
                fc->sb = NULL;
 
463
                fc->file = NULL;
 
464
                fc->flags = 0;
 
465
                fc->user_id = 0;
 
466
                init_waitqueue_head(&fc->waitq);
 
467
                INIT_LIST_HEAD(&fc->pending);
 
468
                INIT_LIST_HEAD(&fc->processing);
 
469
                INIT_LIST_HEAD(&fc->unused_list);
 
470
                sema_init(&fc->outstanding_sem, 0);
 
471
                for (i = 0; i < FUSE_MAX_OUTSTANDING; i++) {
 
472
                        struct fuse_req *req = fuse_request_alloc();
 
473
                        if (!req) {
 
474
                                free_conn(fc);
 
475
                                return NULL;
 
476
                        }
 
477
                        list_add(&req->list, &fc->unused_list);
 
478
                }
 
479
#ifdef KERNEL_2_6_6_PLUS
 
480
                fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
 
481
                fc->bdi.unplug_io_fn = default_unplug_io_fn;
 
482
#endif
 
483
                fc->reqctr = 1;
 
484
        }
 
485
        return fc;
 
486
}
 
487
 
 
488
static struct fuse_conn *get_conn(struct file *file, struct super_block *sb)
 
489
{
 
490
        struct fuse_conn *fc;
 
491
 
 
492
        if (file->f_op != &fuse_dev_operations)
 
493
                return ERR_PTR(-EINVAL);
 
494
        fc = new_conn();
 
495
        if (fc == NULL)
 
496
                return ERR_PTR(-ENOMEM);
 
497
        spin_lock(&fuse_lock);
 
498
        if (file->private_data) {
 
499
                free_conn(fc);
 
500
                fc = ERR_PTR(-EINVAL);
 
501
        } else {
 
502
                file->private_data = fc;
 
503
                fc->sb = sb;
 
504
                fc->file = file;
 
505
        }
 
506
        spin_unlock(&fuse_lock);
 
507
        return fc;
 
508
}
 
509
 
 
510
static struct inode *get_root_inode(struct super_block *sb, unsigned mode)
 
511
{
 
512
        struct fuse_attr attr;
 
513
        memset(&attr, 0, sizeof(attr));
 
514
 
 
515
        attr.mode = mode;
 
516
        attr.ino = FUSE_ROOT_ID;
 
517
        return fuse_iget(sb, 1, 0, &attr, 0);
 
518
}
 
519
 
 
520
#ifdef KERNEL_2_6
 
521
static struct dentry *fuse_get_dentry(struct super_block *sb, void *vobjp)
 
522
{
 
523
        __u32 *objp = vobjp;
 
524
        unsigned long nodeid = objp[0];
 
525
        __u32 generation = objp[1];
 
526
        struct inode *inode;
 
527
        struct dentry *entry;
 
528
 
 
529
        if (nodeid == 0)
 
530
                return ERR_PTR(-ESTALE);
 
531
 
 
532
        inode = ilookup5(sb, nodeid, fuse_inode_eq, &nodeid);
 
533
        if (!inode)
 
534
                return ERR_PTR(-ESTALE);
 
535
        if (inode->i_generation != generation) {
 
536
                iput(inode);
 
537
                return ERR_PTR(-ESTALE);
 
538
        }
 
539
 
 
540
        entry = d_alloc_anon(inode);
 
541
        if (!entry) {
 
542
                iput(inode);
 
543
                return ERR_PTR(-ENOMEM);
 
544
        }
 
545
 
 
546
        return entry;
 
547
}
 
548
 
 
549
static int fuse_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
 
550
                          int connectable)
 
551
{
 
552
        struct inode *inode = dentry->d_inode;
 
553
        int len = *max_len;
 
554
        int type = 1;
 
555
 
 
556
        if (len < 2 || (connectable && len < 4))
 
557
                return 255;
 
558
 
 
559
        len = 2;
 
560
        fh[0] = get_fuse_inode(inode)->nodeid;
 
561
        fh[1] = inode->i_generation;
 
562
        if (connectable && !S_ISDIR(inode->i_mode)) {
 
563
                struct inode *parent;
 
564
 
 
565
                spin_lock(&dentry->d_lock);
 
566
                parent = dentry->d_parent->d_inode;
 
567
                fh[2] = get_fuse_inode(parent)->nodeid;
 
568
                fh[3] = parent->i_generation;
 
569
                spin_unlock(&dentry->d_lock);
 
570
                len = 4;
 
571
                type = 2;
 
572
        }
 
573
        *max_len = len;
 
574
        return type;
 
575
}
 
576
 
 
577
static struct export_operations fuse_export_operations = {
 
578
        .get_dentry     = fuse_get_dentry,
 
579
        .encode_fh      = fuse_encode_fh,
 
580
};
 
581
#endif
 
582
 
 
583
static struct super_operations fuse_super_operations = {
 
584
        .alloc_inode    = fuse_alloc_inode,
 
585
        .destroy_inode  = fuse_destroy_inode,
 
586
        .read_inode     = fuse_read_inode,
 
587
        .clear_inode    = fuse_clear_inode,
 
588
        .put_super      = fuse_put_super,
 
589
        .statfs         = fuse_statfs,
 
590
        .show_options   = fuse_show_options,
 
591
};
 
592
 
 
593
static int fuse_fill_super(struct super_block *sb, void *data, int silent)
 
594
{
 
595
        struct fuse_conn *fc;
 
596
        struct inode *root;
 
597
        struct fuse_mount_data d;
 
598
        struct file *file;
 
599
        int err;
 
600
 
 
601
        if (!parse_fuse_opt((char *) data, &d))
 
602
                return -EINVAL;
 
603
 
 
604
        sb->s_blocksize = PAGE_CACHE_SIZE;
 
605
        sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 
606
        sb->s_magic = FUSE_SUPER_MAGIC;
 
607
        sb->s_op = &fuse_super_operations;
 
608
        sb->s_maxbytes = MAX_LFS_FILESIZE;
 
609
#ifdef KERNEL_2_6
 
610
        sb->s_export_op = &fuse_export_operations;
 
611
#endif
 
612
 
 
613
        file = fget(d.fd);
 
614
        if (!file)
 
615
                return -EINVAL;
 
616
 
 
617
        fc = get_conn(file, sb);
 
618
        fput(file);
 
619
        if (IS_ERR(fc))
 
620
                return PTR_ERR(fc);
 
621
 
 
622
        fc->flags = d.flags;
 
623
        fc->user_id = d.user_id;
 
624
        fc->max_read = d.max_read;
 
625
#ifdef KERNEL_2_6
 
626
        if (fc->max_read / PAGE_CACHE_SIZE < fc->bdi.ra_pages)
 
627
                fc->bdi.ra_pages = fc->max_read / PAGE_CACHE_SIZE;
 
628
#endif
 
629
        fc->max_write = FUSE_MAX_IN / 2;
 
630
 
 
631
        *get_fuse_conn_super_p(sb) = fc;
 
632
 
 
633
        err = -ENOMEM;
 
634
        root = get_root_inode(sb, d.rootmode);
 
635
        if (root == NULL)
 
636
                goto err;
 
637
 
 
638
        sb->s_root = d_alloc_root(root);
 
639
        if (!sb->s_root) {
 
640
                iput(root);
 
641
                goto err;
 
642
        }
 
643
        fuse_send_init(fc);
 
644
        return 0;
 
645
 
 
646
 err:
 
647
        spin_lock(&fuse_lock);
 
648
        fc->sb = NULL;
 
649
        fuse_release_conn(fc);
 
650
        spin_unlock(&fuse_lock);
 
651
        *get_fuse_conn_super_p(sb) = NULL;
 
652
        return err;
 
653
}
 
654
 
 
655
#ifdef KERNEL_2_6
 
656
static struct super_block *fuse_get_sb(struct file_system_type *fs_type,
 
657
                                       int flags, const char *dev_name,
 
658
                                       void *raw_data)
 
659
{
 
660
        return get_sb_nodev(fs_type, flags, raw_data, fuse_fill_super);
 
661
}
 
662
 
 
663
static struct file_system_type fuse_fs_type = {
 
664
        .owner          = THIS_MODULE,
 
665
        .name           = "fuse",
 
666
        .get_sb         = fuse_get_sb,
 
667
        .kill_sb        = kill_anon_super,
 
668
};
 
669
#else
 
670
static struct super_block *fuse_read_super_compat(struct super_block *sb,
 
671
                                                  void *data, int silent)
 
672
{
 
673
        int err = fuse_fill_super(sb, data, silent);
 
674
        if (err)
 
675
                return NULL;
 
676
        else
 
677
                return sb;
 
678
}
 
679
 
 
680
static DECLARE_FSTYPE(fuse_fs_type, "fuse", fuse_read_super_compat, 0);
 
681
#endif
 
682
 
 
683
static void fuse_inode_init_once(void *foo, kmem_cache_t *cachep,
 
684
                                 unsigned long flags)
 
685
{
 
686
        struct inode * inode = foo;
 
687
 
 
688
        if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
 
689
            SLAB_CTOR_CONSTRUCTOR)
 
690
                inode_init_once(inode);
 
691
}
 
692
 
 
693
static int __init fuse_fs_init(void)
 
694
{
 
695
        int err;
 
696
 
 
697
        err = register_filesystem(&fuse_fs_type);
 
698
        if (err)
 
699
                printk("fuse: failed to register filesystem\n");
 
700
        else {
 
701
                fuse_inode_cachep = kmem_cache_create("fuse_inode",
 
702
                                                      sizeof(struct fuse_inode),
 
703
                                                      0, SLAB_HWCACHE_ALIGN,
 
704
                                                      fuse_inode_init_once, NULL);
 
705
                if (!fuse_inode_cachep) {
 
706
                        unregister_filesystem(&fuse_fs_type);
 
707
                        err = -ENOMEM;
 
708
                }
 
709
        }
 
710
 
 
711
        return err;
 
712
}
 
713
 
 
714
static void fuse_fs_cleanup(void)
 
715
{
 
716
        unregister_filesystem(&fuse_fs_type);
 
717
        kmem_cache_destroy(fuse_inode_cachep);
 
718
}
 
719
 
 
720
static int __init fuse_init(void)
 
721
{
 
722
        int res;
 
723
 
 
724
        printk("fuse init (API version %i.%i)\n",
 
725
               FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
 
726
#ifndef FUSE_MAINLINE
 
727
        printk("fuse distribution version: %s\n", FUSE_VERSION);
 
728
#endif
 
729
 
 
730
        spin_lock_init(&fuse_lock);
 
731
        res = fuse_fs_init();
 
732
        if (res)
 
733
                goto err;
 
734
 
 
735
        res = fuse_dev_init();
 
736
        if (res)
 
737
                goto err_fs_cleanup;
 
738
 
 
739
        return 0;
 
740
 
 
741
 err_fs_cleanup:
 
742
        fuse_fs_cleanup();
 
743
 err:
 
744
        return res;
 
745
}
 
746
 
 
747
static void __exit fuse_exit(void)
 
748
{
 
749
        printk(KERN_DEBUG "fuse exit\n");
 
750
 
 
751
        fuse_fs_cleanup();
 
752
        fuse_dev_cleanup();
 
753
}
 
754
 
 
755
module_init(fuse_init);
 
756
module_exit(fuse_exit);