diff options
author | Wang Shilong <wangsl.fnst@cn.fujitsu.com> | 2013-10-25 07:12:02 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-11-11 22:10:13 -0500 |
commit | 9b011adfe14977fcda977234609d43ca52463a3d (patch) | |
tree | a96feceecabdc4bb71d8ff099a4317d3f8f1d9fe | |
parent | 7fdf4b608dda5eea114cb23623b52e34dd5972f5 (diff) |
Btrfs: remove scrub_super_lock holding in btrfs_sync_log()
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>
-rw-r--r-- | fs/btrfs/ctree.h | 3 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 1 | ||||
-rw-r--r-- | fs/btrfs/scrub.c | 18 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 2 | ||||
-rw-r--r-- | fs/btrfs/volumes.h | 4 |
5 files changed, 8 insertions, 20 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 9f5e1cfb0209..34279665fd69 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1586,7 +1586,6 @@ struct btrfs_fs_info { | |||
1586 | atomic_t scrubs_paused; | 1586 | atomic_t scrubs_paused; |
1587 | atomic_t scrub_cancel_req; | 1587 | atomic_t scrub_cancel_req; |
1588 | wait_queue_head_t scrub_pause_wait; | 1588 | wait_queue_head_t scrub_pause_wait; |
1589 | struct rw_semaphore scrub_super_lock; | ||
1590 | int scrub_workers_refcnt; | 1589 | int scrub_workers_refcnt; |
1591 | struct btrfs_workers scrub_workers; | 1590 | struct btrfs_workers scrub_workers; |
1592 | struct btrfs_workers scrub_wr_completion_workers; | 1591 | 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, | |||
3950 | u64 end, struct btrfs_scrub_progress *progress, | 3949 | u64 end, struct btrfs_scrub_progress *progress, |
3951 | int readonly, int is_dev_replace); | 3950 | int readonly, int is_dev_replace); |
3952 | void btrfs_scrub_pause(struct btrfs_root *root); | 3951 | void btrfs_scrub_pause(struct btrfs_root *root); |
3953 | void btrfs_scrub_pause_super(struct btrfs_root *root); | ||
3954 | void btrfs_scrub_continue(struct btrfs_root *root); | 3952 | void btrfs_scrub_continue(struct btrfs_root *root); |
3955 | void btrfs_scrub_continue_super(struct btrfs_root *root); | ||
3956 | int btrfs_scrub_cancel(struct btrfs_fs_info *info); | 3953 | int btrfs_scrub_cancel(struct btrfs_fs_info *info); |
3957 | int btrfs_scrub_cancel_dev(struct btrfs_fs_info *info, | 3954 | int btrfs_scrub_cancel_dev(struct btrfs_fs_info *info, |
3958 | struct btrfs_device *dev); | 3955 | struct btrfs_device *dev); |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 62c4aba221bb..a3ad3a27944d 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -2250,7 +2250,6 @@ int open_ctree(struct super_block *sb, | |||
2250 | atomic_set(&fs_info->scrubs_paused, 0); | 2250 | atomic_set(&fs_info->scrubs_paused, 0); |
2251 | atomic_set(&fs_info->scrub_cancel_req, 0); | 2251 | atomic_set(&fs_info->scrub_cancel_req, 0); |
2252 | init_waitqueue_head(&fs_info->scrub_pause_wait); | 2252 | init_waitqueue_head(&fs_info->scrub_pause_wait); |
2253 | init_rwsem(&fs_info->scrub_super_lock); | ||
2254 | fs_info->scrub_workers_refcnt = 0; | 2253 | fs_info->scrub_workers_refcnt = 0; |
2255 | #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY | 2254 | #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY |
2256 | fs_info->check_integrity_print_mask = 0; | 2255 | fs_info->check_integrity_print_mask = 0; |
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index f21e2df89bc2..12009b4279ad 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -2932,13 +2932,15 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, | |||
2932 | 2932 | ||
2933 | atomic_inc(&fs_info->scrubs_running); | 2933 | atomic_inc(&fs_info->scrubs_running); |
2934 | mutex_unlock(&fs_info->scrub_lock); | 2934 | mutex_unlock(&fs_info->scrub_lock); |
2935 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); | ||
2936 | 2935 | ||
2937 | if (!is_dev_replace) { | 2936 | if (!is_dev_replace) { |
2938 | down_read(&fs_info->scrub_super_lock); | 2937 | /* |
2938 | * by holding device list mutex, we can | ||
2939 | * kick off writing super in log tree sync. | ||
2940 | */ | ||
2939 | ret = scrub_supers(sctx, dev); | 2941 | ret = scrub_supers(sctx, dev); |
2940 | up_read(&fs_info->scrub_super_lock); | ||
2941 | } | 2942 | } |
2943 | mutex_unlock(&fs_info->fs_devices->device_list_mutex); | ||
2942 | 2944 | ||
2943 | if (!ret) | 2945 | if (!ret) |
2944 | ret = scrub_enumerate_chunks(sctx, dev, start, end, | 2946 | ret = scrub_enumerate_chunks(sctx, dev, start, end, |
@@ -2988,16 +2990,6 @@ void btrfs_scrub_continue(struct btrfs_root *root) | |||
2988 | wake_up(&fs_info->scrub_pause_wait); | 2990 | wake_up(&fs_info->scrub_pause_wait); |
2989 | } | 2991 | } |
2990 | 2992 | ||
2991 | void btrfs_scrub_pause_super(struct btrfs_root *root) | ||
2992 | { | ||
2993 | down_write(&root->fs_info->scrub_super_lock); | ||
2994 | } | ||
2995 | |||
2996 | void btrfs_scrub_continue_super(struct btrfs_root *root) | ||
2997 | { | ||
2998 | up_write(&root->fs_info->scrub_super_lock); | ||
2999 | } | ||
3000 | |||
3001 | int btrfs_scrub_cancel(struct btrfs_fs_info *fs_info) | 2993 | int btrfs_scrub_cancel(struct btrfs_fs_info *fs_info) |
3002 | { | 2994 | { |
3003 | mutex_lock(&fs_info->scrub_lock); | 2995 | mutex_lock(&fs_info->scrub_lock); |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index f98002ed32b1..257cbae8c948 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -2586,9 +2586,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
2586 | * the running transaction open, so a full commit can't hop | 2586 | * the running transaction open, so a full commit can't hop |
2587 | * in and cause problems either. | 2587 | * in and cause problems either. |
2588 | */ | 2588 | */ |
2589 | btrfs_scrub_pause_super(root); | ||
2590 | ret = write_ctree_super(trans, root->fs_info->tree_root, 1); | 2589 | ret = write_ctree_super(trans, root->fs_info->tree_root, 1); |
2591 | btrfs_scrub_continue_super(root); | ||
2592 | if (ret) { | 2590 | if (ret) { |
2593 | btrfs_abort_transaction(trans, root, ret); | 2591 | btrfs_abort_transaction(trans, root, ret); |
2594 | goto out_wake_log_root; | 2592 | goto out_wake_log_root; |
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index b72f540c8b29..49e0ff01143f 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
@@ -132,7 +132,9 @@ struct btrfs_fs_devices { | |||
132 | 132 | ||
133 | /* all of the devices in the FS, protected by a mutex | 133 | /* all of the devices in the FS, protected by a mutex |
134 | * so we can safely walk it to write out the supers without | 134 | * so we can safely walk it to write out the supers without |
135 | * worrying about add/remove by the multi-device code | 135 | * worrying about add/remove by the multi-device code. |
136 | * Scrubbing super can kick off supers writing by holding | ||
137 | * this mutex lock. | ||
136 | */ | 138 | */ |
137 | struct mutex device_list_mutex; | 139 | struct mutex device_list_mutex; |
138 | struct list_head devices; | 140 | struct list_head devices; |