diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/dev.c | 15 | ||||
-rw-r--r-- | kernel/dir.c | 2 | ||||
-rw-r--r-- | kernel/fuse_i.h | 30 | ||||
-rw-r--r-- | kernel/inode.c | 17 | ||||
-rw-r--r-- | kernel/linux/fuse.h | 6 |
5 files changed, 46 insertions, 24 deletions
diff --git a/kernel/dev.c b/kernel/dev.c index 7261770..da41e59 100644 --- a/kernel/dev.c +++ b/kernel/dev.c @@ -8,6 +8,7 @@ #include "fuse_i.h" +#include <linux/init.h> #include <linux/module.h> #include <linux/poll.h> #ifdef KERNEL_2_6 @@ -261,7 +262,6 @@ static ssize_t fuse_dev_read(struct file *file, char __user *buf, else if (!list_empty(&fc->pending)) { req = list_entry(fc->pending.next, struct fuse_req, list); list_del_init(&req->list); - req->locked = 1; } spin_unlock(&fuse_lock); if (!fc) @@ -275,12 +275,9 @@ static ssize_t fuse_dev_read(struct file *file, char __user *buf, if (ret < 0) { req->out.h.error = -EPROTO; req->finished = 1; - } else { + } else list_add_tail(&req->list, &fc->processing); - req->sent = 1; - } - req->locked = 0; - if (ret < 0 || req->interrupted) + if (ret < 0) /* Unlocks fuse_lock: */ request_end(fc, req); else @@ -471,10 +468,8 @@ static ssize_t fuse_dev_write(struct file *file, const char __user *buf, spin_lock(&fuse_lock); req = request_find(fc, oh.unique); - if (req != NULL) { + if (req != NULL) list_del_init(&req->list); - req->locked = 1; - } spin_unlock(&fuse_lock); if (!req) return -ENOENT; @@ -491,7 +486,6 @@ static ssize_t fuse_dev_write(struct file *file, const char __user *buf, process_getdir(req); } req->finished = 1; - req->locked = 0; /* Unlocks fuse_lock: */ request_end(fc, req); @@ -565,7 +559,6 @@ struct file_operations fuse_dev_operations = { }; #ifdef KERNEL_2_6 -#define FUSE_MINOR MISC_DYNAMIC_MINOR #ifndef FUSE_MAINLINE static decl_subsys(fs, NULL, NULL); diff --git a/kernel/dir.c b/kernel/dir.c index 124bf86..fe8e803 100644 --- a/kernel/dir.c +++ b/kernel/dir.c @@ -111,6 +111,7 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, int generation, struct fuse_attr *attr, int version) { struct inode *inode; + struct fuse_conn *fc = SB_FC(sb); inode = iget5_locked(sb, nodeid, fuse_inode_eq, fuse_inode_set, &nodeid); if (!inode) @@ -118,6 +119,7 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, if ((inode->i_state & I_NEW)) { inode->i_generation = generation; + inode->i_data.backing_dev_info = &fc->bdi; fuse_init_inode(inode, attr); unlock_new_inode(inode); } else if (inode->i_generation != generation) diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h index e454fd0..c5b8e23 100644 --- a/kernel/fuse_i.h +++ b/kernel/fuse_i.h @@ -42,6 +42,10 @@ #include <linux/wait.h> #include <linux/list.h> #include <linux/spinlock.h> +#ifdef KERNEL_2_6 +#include <linux/mm.h> +#include <linux/backing-dev.h> +#endif #include <asm/semaphore.h> #ifndef BUG_ON @@ -152,15 +156,6 @@ struct fuse_req { /** True if the request has reply */ unsigned int isreply:1; - /** The request is locked */ - unsigned int locked:1; - - /** The request has been interrupted while it was locked */ - unsigned int interrupted:1; - - /* The request has been sent to the client */ - unsigned int sent:1; - /* The request is preallocated */ unsigned int preallocated:1; @@ -264,6 +259,11 @@ struct fuse_conn { /** Is removexattr not implemented by fs? */ unsigned int no_removexattr : 1; + +#ifdef KERNEL_2_6 + /** Backing dev info */ + struct backing_dev_info bdi; +#endif }; struct fuse_getdir_out_i { @@ -283,7 +283,16 @@ struct fuse_getdir_out_i { extern struct file_operations fuse_dev_operations; /** - * The lock to protect fuses structures + * This is the single global spinlock which protects FUSE's structures + * + * The following data is protected by this lock: + * + * - the private_data field of the device file + * - the s_fs_info field of the super block + * - unused_list, pending, processing lists in fuse_conn + * - the unique request ID counter reqctr in fuse_conn + * - the sb (super_block) field in fuse_conn + * - the file (device file) field in fuse_conn */ extern spinlock_t fuse_lock; @@ -336,7 +345,6 @@ int fuse_fs_init(void); */ void fuse_fs_cleanup(void); - /** * Allocate a request */ diff --git a/kernel/inode.c b/kernel/inode.c index 55a283b..8cae834 100644 --- a/kernel/inode.c +++ b/kernel/inode.c @@ -178,7 +178,9 @@ enum { OPT_ALLOW_OTHER, OPT_ALLOW_ROOT, OPT_KERNEL_CACHE, +#ifndef FUSE_MAINLINE OPT_LARGE_READ, +#endif OPT_DIRECT_IO, OPT_MAX_READ, OPT_ERR @@ -192,7 +194,9 @@ static match_table_t tokens = { {OPT_ALLOW_OTHER, "allow_other"}, {OPT_ALLOW_ROOT, "allow_root"}, {OPT_KERNEL_CACHE, "kernel_cache"}, +#ifndef FUSE_MAINLINE {OPT_LARGE_READ, "large_read"}, +#endif {OPT_DIRECT_IO, "direct_io"}, {OPT_MAX_READ, "max_read=%u"}, {OPT_ERR, NULL} @@ -247,7 +251,8 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d) case OPT_KERNEL_CACHE: d->flags |= FUSE_KERNEL_CACHE; break; - + +#ifndef FUSE_MAINLINE case OPT_LARGE_READ: #ifndef KERNEL_2_6 d->flags |= FUSE_LARGE_READ; @@ -261,7 +266,7 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d) } #endif break; - +#endif case OPT_DIRECT_IO: d->flags |= FUSE_DIRECT_IO; break; @@ -351,6 +356,10 @@ static struct fuse_conn *new_conn(void) req->preallocated = 1; list_add(&req->list, &fc->unused_list); } +#ifdef KERNEL_2_6 + fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; + fc->bdi.unplug_io_fn = default_unplug_io_fn; +#endif fc->reqctr = 1; } return fc; @@ -502,6 +511,10 @@ static int fuse_read_super(struct super_block *sb, void *data, int silent) fc->flags = d.flags; fc->uid = d.uid; fc->max_read = d.max_read; +#ifdef KERNEL_2_6 + if (fc->max_read / PAGE_CACHE_SIZE < fc->bdi.ra_pages) + fc->bdi.ra_pages = fc->max_read / PAGE_CACHE_SIZE; +#endif fc->max_write = FUSE_MAX_IN / 2; SB_FC(sb) = fc; diff --git a/kernel/linux/fuse.h b/kernel/linux/fuse.h index f5f7405..ea640e9 100644 --- a/kernel/linux/fuse.h +++ b/kernel/linux/fuse.h @@ -17,6 +17,12 @@ /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 +/** The major number of the fuse character device */ +#define FUSE_MAJOR 10 + +/** The minor number of the fuse character device */ +#define FUSE_MINOR 229 + /** Opening this will yield a new control file */ #define FUSE_DEV "/dev/fuse" |