Btrfs: remove scrub_super_lock holding in btrfs_sync_log()
authorWang Shilong <wangsl.fnst@cn.fujitsu.com>
Fri, 25 Oct 2013 11:12:02 +0000 (19:12 +0800)
committerChris Mason <chris.mason@fusionio.com>
Tue, 12 Nov 2013 03:10:13 +0000 (22:10 -0500)
Originally, we introduced scrub_super_lock to synchronize
tree log code with scrubbing super.

However we can replace scrub_super_lock with device_list_mutex,
because writing super will hold this mutex, this will reduce an extra
lock holding when writing supers in sync log code.

Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/scrub.c
fs/btrfs/tree-log.c
fs/btrfs/volumes.h

index 9f5e1cfb02093427fb7ea385d96883c3b5b89db3..34279665fd699601b8b4aefa44661527435a2648 100644 (file)
@@ -1586,7 +1586,6 @@ struct btrfs_fs_info {
        atomic_t scrubs_paused;
        atomic_t scrub_cancel_req;
        wait_queue_head_t scrub_pause_wait;
-       struct rw_semaphore scrub_super_lock;
        int scrub_workers_refcnt;
        struct btrfs_workers scrub_workers;
        struct btrfs_workers scrub_wr_completion_workers;
@@ -3950,9 +3949,7 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
                    u64 end, struct btrfs_scrub_progress *progress,
                    int readonly, int is_dev_replace);
 void btrfs_scrub_pause(struct btrfs_root *root);
-void btrfs_scrub_pause_super(struct btrfs_root *root);
 void btrfs_scrub_continue(struct btrfs_root *root);
-void btrfs_scrub_continue_super(struct btrfs_root *root);
 int btrfs_scrub_cancel(struct btrfs_fs_info *info);
 int btrfs_scrub_cancel_dev(struct btrfs_fs_info *info,
                           struct btrfs_device *dev);
index 62c4aba221bb6f4e625bed09c9c13614238feb0d..a3ad3a27944d2c4b429161c0efcdd8f73b172bc4 100644 (file)
@@ -2250,7 +2250,6 @@ int open_ctree(struct super_block *sb,
        atomic_set(&fs_info->scrubs_paused, 0);
        atomic_set(&fs_info->scrub_cancel_req, 0);
        init_waitqueue_head(&fs_info->scrub_pause_wait);
-       init_rwsem(&fs_info->scrub_super_lock);
        fs_info->scrub_workers_refcnt = 0;
 #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY
        fs_info->check_integrity_print_mask = 0;
index f21e2df89bc26b0259b570a17b1f801d826c43e3..12009b4279ad1c1e3faad9e5353de1f86a0a4c9a 100644 (file)
@@ -2932,13 +2932,15 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
 
        atomic_inc(&fs_info->scrubs_running);
        mutex_unlock(&fs_info->scrub_lock);
-       mutex_unlock(&fs_info->fs_devices->device_list_mutex);
 
        if (!is_dev_replace) {
-               down_read(&fs_info->scrub_super_lock);
+               /*
+                * by holding device list mutex, we can
+                * kick off writing super in log tree sync.
+                */
                ret = scrub_supers(sctx, dev);
-               up_read(&fs_info->scrub_super_lock);
        }
+       mutex_unlock(&fs_info->fs_devices->device_list_mutex);
 
        if (!ret)
                ret = scrub_enumerate_chunks(sctx, dev, start, end,
@@ -2988,16 +2990,6 @@ void btrfs_scrub_continue(struct btrfs_root *root)
        wake_up(&fs_info->scrub_pause_wait);
 }
 
-void btrfs_scrub_pause_super(struct btrfs_root *root)
-{
-       down_write(&root->fs_info->scrub_super_lock);
-}
-
-void btrfs_scrub_continue_super(struct btrfs_root *root)
-{
-       up_write(&root->fs_info->scrub_super_lock);
-}
-
 int btrfs_scrub_cancel(struct btrfs_fs_info *fs_info)
 {
        mutex_lock(&fs_info->scrub_lock);
index f98002ed32b1890b9446cd9a0a47edf08a1eee2c..257cbae8c9488a9246fba22f199e72f1b6827647 100644 (file)
@@ -2586,9 +2586,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
         * the running transaction open, so a full commit can't hop
         * in and cause problems either.
         */
-       btrfs_scrub_pause_super(root);
        ret = write_ctree_super(trans, root->fs_info->tree_root, 1);
-       btrfs_scrub_continue_super(root);
        if (ret) {
                btrfs_abort_transaction(trans, root, ret);
                goto out_wake_log_root;
index b72f540c8b295d1be0b3642d695ee0b8b75ebed1..49e0ff01143f7c2ca9c0e170be911c62a8081c26 100644 (file)
@@ -132,7 +132,9 @@ struct btrfs_fs_devices {
 
        /* all of the devices in the FS, protected by a mutex
         * so we can safely walk it to write out the supers without
-        * worrying about add/remove by the multi-device code
+        * worrying about add/remove by the multi-device code.
+        * Scrubbing super can kick off supers writing by holding
+        * this mutex lock.
         */
        struct mutex device_list_mutex;
        struct list_head devices;