fuse: update fuse_conn_init() and separate out fuse_conn_kill()
authorTejun Heo <tj@kernel.org>
Tue, 14 Apr 2009 01:54:52 +0000 (10:54 +0900)
committerMiklos Szeredi <mszeredi@suse.cz>
Tue, 28 Apr 2009 14:56:41 +0000 (16:56 +0200)
Update fuse_conn_init() such that it doesn't take @sb and move bdi
registration into a separate function.  Also separate out
fuse_conn_kill() from fuse_put_super().

These will be used to implement cuse.

Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
fs/fuse/dev.c
fs/fuse/fuse_i.h
fs/fuse/inode.c

index ba76b68c52ffe2d127178d71ca5b5ab2ecc6a353..368189fd4056a8f2e2bb73f15baeccabeba3c059 100644 (file)
@@ -282,7 +282,7 @@ __releases(&fc->lock)
                        wake_up_all(&fc->blocked_waitq);
                }
                if (fc->num_background == FUSE_CONGESTION_THRESHOLD &&
-                   fc->connected) {
+                   fc->connected && fc->bdi_initialized) {
                        clear_bdi_congested(&fc->bdi, READ);
                        clear_bdi_congested(&fc->bdi, WRITE);
                }
@@ -408,7 +408,8 @@ static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
        fc->num_background++;
        if (fc->num_background == FUSE_MAX_BACKGROUND)
                fc->blocked = 1;
-       if (fc->num_background == FUSE_CONGESTION_THRESHOLD) {
+       if (fc->num_background == FUSE_CONGESTION_THRESHOLD &&
+           fc->bdi_initialized) {
                set_bdi_congested(&fc->bdi, READ);
                set_bdi_congested(&fc->bdi, WRITE);
        }
index ef2e1f3780b5c0c54616367c3800499717a9f4d3..2efcf12b763aff19cc094c014e91c11badf5cdc9 100644 (file)
@@ -394,6 +394,9 @@ struct fuse_conn {
        /** Filesystem supports NFS exporting.  Only set in INIT */
        unsigned export_support:1;
 
+       /** Set if bdi is valid */
+       unsigned bdi_initialized:1;
+
        /*
         * The following bitfields are only for optimization purposes
         * and hence races in setting them will not cause malfunction
@@ -662,7 +665,7 @@ struct fuse_conn *fuse_conn_get(struct fuse_conn *fc);
 /**
  * Initialize fuse_conn
  */
-int fuse_conn_init(struct fuse_conn *fc, struct super_block *sb);
+void fuse_conn_init(struct fuse_conn *fc);
 
 /**
  * Release reference to fuse_conn
index 75ca5ac603aedf71f2705effcdddfa4c11445b1d..fea7c1064d30a2cea15f45987f3a8dd8d606e37e 100644 (file)
@@ -274,11 +274,14 @@ static void fuse_send_destroy(struct fuse_conn *fc)
        }
 }
 
-static void fuse_put_super(struct super_block *sb)
+static void fuse_bdi_destroy(struct fuse_conn *fc)
 {
-       struct fuse_conn *fc = get_fuse_conn_super(sb);
+       if (fc->bdi_initialized)
+               bdi_destroy(&fc->bdi);
+}
 
-       fuse_send_destroy(fc);
+static void fuse_conn_kill(struct fuse_conn *fc)
+{
        spin_lock(&fc->lock);
        fc->connected = 0;
        fc->blocked = 0;
@@ -292,7 +295,15 @@ static void fuse_put_super(struct super_block *sb)
        list_del(&fc->entry);
        fuse_ctl_remove_conn(fc);
        mutex_unlock(&fuse_mutex);
-       bdi_destroy(&fc->bdi);
+       fuse_bdi_destroy(fc);
+}
+
+static void fuse_put_super(struct super_block *sb)
+{
+       struct fuse_conn *fc = get_fuse_conn_super(sb);
+
+       fuse_send_destroy(fc);
+       fuse_conn_kill(fc);
        fuse_conn_put(fc);
 }
 
@@ -463,10 +474,8 @@ static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt)
        return 0;
 }
 
-int fuse_conn_init(struct fuse_conn *fc, struct super_block *sb)
+void fuse_conn_init(struct fuse_conn *fc)
 {
-       int err;
-
        memset(fc, 0, sizeof(*fc));
        spin_lock_init(&fc->lock);
        mutex_init(&fc->inst_mutex);
@@ -481,49 +490,12 @@ int fuse_conn_init(struct fuse_conn *fc, struct super_block *sb)
        INIT_LIST_HEAD(&fc->bg_queue);
        INIT_LIST_HEAD(&fc->entry);
        atomic_set(&fc->num_waiting, 0);
-       fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
-       fc->bdi.unplug_io_fn = default_unplug_io_fn;
-       /* fuse does it's own writeback accounting */
-       fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB;
        fc->khctr = 0;
        fc->polled_files = RB_ROOT;
-       fc->dev = sb->s_dev;
-       err = bdi_init(&fc->bdi);
-       if (err)
-               goto error_mutex_destroy;
-       if (sb->s_bdev) {
-               err = bdi_register(&fc->bdi, NULL, "%u:%u-fuseblk",
-                                  MAJOR(fc->dev), MINOR(fc->dev));
-       } else {
-               err = bdi_register_dev(&fc->bdi, fc->dev);
-       }
-       if (err)
-               goto error_bdi_destroy;
-       /*
-        * For a single fuse filesystem use max 1% of dirty +
-        * writeback threshold.
-        *
-        * This gives about 1M of write buffer for memory maps on a
-        * machine with 1G and 10% dirty_ratio, which should be more
-        * than enough.
-        *
-        * Privileged users can raise it by writing to
-        *
-        *    /sys/class/bdi/<bdi>/max_ratio
-        */
-       bdi_set_max_ratio(&fc->bdi, 1);
        fc->reqctr = 0;
        fc->blocked = 1;
        fc->attr_version = 1;
        get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
-
-       return 0;
-
- error_bdi_destroy:
-       bdi_destroy(&fc->bdi);
- error_mutex_destroy:
-       mutex_destroy(&fc->inst_mutex);
-       return err;
 }
 EXPORT_SYMBOL_GPL(fuse_conn_init);
 
@@ -794,6 +766,48 @@ static void fuse_free_conn(struct fuse_conn *fc)
        kfree(fc);
 }
 
+static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb)
+{
+       int err;
+
+       fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
+       fc->bdi.unplug_io_fn = default_unplug_io_fn;
+       /* fuse does it's own writeback accounting */
+       fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB;
+
+       err = bdi_init(&fc->bdi);
+       if (err)
+               return err;
+
+       fc->bdi_initialized = 1;
+
+       if (sb->s_bdev) {
+               err =  bdi_register(&fc->bdi, NULL, "%u:%u-fuseblk",
+                                   MAJOR(fc->dev), MINOR(fc->dev));
+       } else {
+               err = bdi_register_dev(&fc->bdi, fc->dev);
+       }
+
+       if (err)
+               return err;
+
+       /*
+        * For a single fuse filesystem use max 1% of dirty +
+        * writeback threshold.
+        *
+        * This gives about 1M of write buffer for memory maps on a
+        * machine with 1G and 10% dirty_ratio, which should be more
+        * than enough.
+        *
+        * Privileged users can raise it by writing to
+        *
+        *    /sys/class/bdi/<bdi>/max_ratio
+        */
+       bdi_set_max_ratio(&fc->bdi, 1);
+
+       return 0;
+}
+
 static int fuse_fill_super(struct super_block *sb, void *data, int silent)
 {
        struct fuse_conn *fc;
@@ -840,11 +854,12 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
        if (!fc)
                goto err_fput;
 
-       err = fuse_conn_init(fc, sb);
-       if (err) {
-               kfree(fc);
-               goto err_fput;
-       }
+       fuse_conn_init(fc);
+
+       fc->dev = sb->s_dev;
+       err = fuse_bdi_init(fc, sb);
+       if (err)
+               goto err_put_conn;
 
        fc->release = fuse_free_conn;
        fc->flags = d.flags;
@@ -908,7 +923,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
  err_put_root:
        dput(root_dentry);
  err_put_conn:
-       bdi_destroy(&fc->bdi);
+       fuse_bdi_destroy(fc);
        fuse_conn_put(fc);
  err_fput:
        fput(file);