Commit 7e79cb86 authored by David Sterba's avatar David Sterba

btrfs: split dev-replace locking helpers for read and write

The current calls are unclear in what way btrfs_dev_replace_lock takes
the locks, so drop the argument, split the helpers and use similar
naming as for read and write locks.
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent e7ab0af6
...@@ -205,13 +205,13 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans, ...@@ -205,13 +205,13 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans,
struct btrfs_dev_replace_item *ptr; struct btrfs_dev_replace_item *ptr;
struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
btrfs_dev_replace_lock(dev_replace, 0); btrfs_dev_replace_read_lock(dev_replace);
if (!dev_replace->is_valid || if (!dev_replace->is_valid ||
!dev_replace->item_needs_writeback) { !dev_replace->item_needs_writeback) {
btrfs_dev_replace_unlock(dev_replace, 0); btrfs_dev_replace_read_unlock(dev_replace);
return 0; return 0;
} }
btrfs_dev_replace_unlock(dev_replace, 0); btrfs_dev_replace_read_unlock(dev_replace);
key.objectid = 0; key.objectid = 0;
key.type = BTRFS_DEV_REPLACE_KEY; key.type = BTRFS_DEV_REPLACE_KEY;
...@@ -269,7 +269,7 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans, ...@@ -269,7 +269,7 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans,
ptr = btrfs_item_ptr(eb, path->slots[0], ptr = btrfs_item_ptr(eb, path->slots[0],
struct btrfs_dev_replace_item); struct btrfs_dev_replace_item);
btrfs_dev_replace_lock(dev_replace, 1); btrfs_dev_replace_write_lock(dev_replace);
if (dev_replace->srcdev) if (dev_replace->srcdev)
btrfs_set_dev_replace_src_devid(eb, ptr, btrfs_set_dev_replace_src_devid(eb, ptr,
dev_replace->srcdev->devid); dev_replace->srcdev->devid);
...@@ -292,7 +292,7 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans, ...@@ -292,7 +292,7 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans,
btrfs_set_dev_replace_cursor_right(eb, ptr, btrfs_set_dev_replace_cursor_right(eb, ptr,
dev_replace->cursor_right); dev_replace->cursor_right);
dev_replace->item_needs_writeback = 0; dev_replace->item_needs_writeback = 0;
btrfs_dev_replace_unlock(dev_replace, 1); btrfs_dev_replace_write_unlock(dev_replace);
btrfs_mark_buffer_dirty(eb); btrfs_mark_buffer_dirty(eb);
...@@ -357,7 +357,7 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info, ...@@ -357,7 +357,7 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
return PTR_ERR(trans); return PTR_ERR(trans);
} }
btrfs_dev_replace_lock(dev_replace, 1); btrfs_dev_replace_write_lock(dev_replace);
switch (dev_replace->replace_state) { switch (dev_replace->replace_state) {
case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED: case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED: case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
...@@ -395,7 +395,7 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info, ...@@ -395,7 +395,7 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
dev_replace->item_needs_writeback = 1; dev_replace->item_needs_writeback = 1;
atomic64_set(&dev_replace->num_write_errors, 0); atomic64_set(&dev_replace->num_write_errors, 0);
atomic64_set(&dev_replace->num_uncorrectable_read_errors, 0); atomic64_set(&dev_replace->num_uncorrectable_read_errors, 0);
btrfs_dev_replace_unlock(dev_replace, 1); btrfs_dev_replace_write_unlock(dev_replace);
ret = btrfs_sysfs_add_device_link(tgt_device->fs_devices, tgt_device); ret = btrfs_sysfs_add_device_link(tgt_device->fs_devices, tgt_device);
if (ret) if (ret)
...@@ -407,7 +407,7 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info, ...@@ -407,7 +407,7 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
trans = btrfs_start_transaction(root, 0); trans = btrfs_start_transaction(root, 0);
if (IS_ERR(trans)) { if (IS_ERR(trans)) {
ret = PTR_ERR(trans); ret = PTR_ERR(trans);
btrfs_dev_replace_lock(dev_replace, 1); btrfs_dev_replace_write_lock(dev_replace);
goto leave; goto leave;
} }
...@@ -431,7 +431,7 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info, ...@@ -431,7 +431,7 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
leave: leave:
dev_replace->srcdev = NULL; dev_replace->srcdev = NULL;
dev_replace->tgtdev = NULL; dev_replace->tgtdev = NULL;
btrfs_dev_replace_unlock(dev_replace, 1); btrfs_dev_replace_write_unlock(dev_replace);
btrfs_destroy_dev_replace_tgtdev(fs_info, tgt_device); btrfs_destroy_dev_replace_tgtdev(fs_info, tgt_device);
return ret; return ret;
} }
...@@ -498,18 +498,18 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, ...@@ -498,18 +498,18 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
/* don't allow cancel or unmount to disturb the finishing procedure */ /* don't allow cancel or unmount to disturb the finishing procedure */
mutex_lock(&dev_replace->lock_finishing_cancel_unmount); mutex_lock(&dev_replace->lock_finishing_cancel_unmount);
btrfs_dev_replace_lock(dev_replace, 0); btrfs_dev_replace_read_lock(dev_replace);
/* was the operation canceled, or is it finished? */ /* was the operation canceled, or is it finished? */
if (dev_replace->replace_state != if (dev_replace->replace_state !=
BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED) { BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED) {
btrfs_dev_replace_unlock(dev_replace, 0); btrfs_dev_replace_read_unlock(dev_replace);
mutex_unlock(&dev_replace->lock_finishing_cancel_unmount); mutex_unlock(&dev_replace->lock_finishing_cancel_unmount);
return 0; return 0;
} }
tgt_device = dev_replace->tgtdev; tgt_device = dev_replace->tgtdev;
src_device = dev_replace->srcdev; src_device = dev_replace->srcdev;
btrfs_dev_replace_unlock(dev_replace, 0); btrfs_dev_replace_read_unlock(dev_replace);
/* /*
* flush all outstanding I/O and inode extent mappings before the * flush all outstanding I/O and inode extent mappings before the
...@@ -534,7 +534,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, ...@@ -534,7 +534,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
/* keep away write_all_supers() during the finishing procedure */ /* keep away write_all_supers() during the finishing procedure */
mutex_lock(&fs_info->fs_devices->device_list_mutex); mutex_lock(&fs_info->fs_devices->device_list_mutex);
mutex_lock(&fs_info->chunk_mutex); mutex_lock(&fs_info->chunk_mutex);
btrfs_dev_replace_lock(dev_replace, 1); btrfs_dev_replace_write_lock(dev_replace);
dev_replace->replace_state = dev_replace->replace_state =
scrub_ret ? BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED scrub_ret ? BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED
: BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED; : BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED;
...@@ -554,7 +554,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, ...@@ -554,7 +554,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
btrfs_dev_name(src_device), btrfs_dev_name(src_device),
src_device->devid, src_device->devid,
rcu_str_deref(tgt_device->name), scrub_ret); rcu_str_deref(tgt_device->name), scrub_ret);
btrfs_dev_replace_unlock(dev_replace, 1); btrfs_dev_replace_write_unlock(dev_replace);
mutex_unlock(&fs_info->chunk_mutex); mutex_unlock(&fs_info->chunk_mutex);
mutex_unlock(&fs_info->fs_devices->device_list_mutex); mutex_unlock(&fs_info->fs_devices->device_list_mutex);
mutex_unlock(&uuid_mutex); mutex_unlock(&uuid_mutex);
...@@ -591,7 +591,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, ...@@ -591,7 +591,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list); list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list);
fs_info->fs_devices->rw_devices++; fs_info->fs_devices->rw_devices++;
btrfs_dev_replace_unlock(dev_replace, 1); btrfs_dev_replace_write_unlock(dev_replace);
btrfs_rm_dev_replace_blocked(fs_info); btrfs_rm_dev_replace_blocked(fs_info);
...@@ -684,7 +684,7 @@ void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info, ...@@ -684,7 +684,7 @@ void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info,
{ {
struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
btrfs_dev_replace_lock(dev_replace, 0); btrfs_dev_replace_read_lock(dev_replace);
/* even if !dev_replace_is_valid, the values are good enough for /* even if !dev_replace_is_valid, the values are good enough for
* the replace_status ioctl */ * the replace_status ioctl */
args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR; args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR;
...@@ -696,7 +696,7 @@ void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info, ...@@ -696,7 +696,7 @@ void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info,
args->status.num_uncorrectable_read_errors = args->status.num_uncorrectable_read_errors =
atomic64_read(&dev_replace->num_uncorrectable_read_errors); atomic64_read(&dev_replace->num_uncorrectable_read_errors);
args->status.progress_1000 = btrfs_dev_replace_progress(fs_info); args->status.progress_1000 = btrfs_dev_replace_progress(fs_info);
btrfs_dev_replace_unlock(dev_replace, 0); btrfs_dev_replace_read_unlock(dev_replace);
} }
int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info) int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info)
...@@ -713,13 +713,13 @@ int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info) ...@@ -713,13 +713,13 @@ int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info)
return -EROFS; return -EROFS;
mutex_lock(&dev_replace->lock_finishing_cancel_unmount); mutex_lock(&dev_replace->lock_finishing_cancel_unmount);
btrfs_dev_replace_lock(dev_replace, 1); btrfs_dev_replace_write_lock(dev_replace);
switch (dev_replace->replace_state) { switch (dev_replace->replace_state) {
case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED: case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED: case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED: case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED:
result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED; result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED;
btrfs_dev_replace_unlock(dev_replace, 1); btrfs_dev_replace_write_unlock(dev_replace);
goto leave; goto leave;
case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED: case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED: case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED:
...@@ -733,7 +733,7 @@ int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info) ...@@ -733,7 +733,7 @@ int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info)
dev_replace->replace_state = BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED; dev_replace->replace_state = BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED;
dev_replace->time_stopped = get_seconds(); dev_replace->time_stopped = get_seconds();
dev_replace->item_needs_writeback = 1; dev_replace->item_needs_writeback = 1;
btrfs_dev_replace_unlock(dev_replace, 1); btrfs_dev_replace_write_unlock(dev_replace);
btrfs_scrub_cancel(fs_info); btrfs_scrub_cancel(fs_info);
trans = btrfs_start_transaction(root, 0); trans = btrfs_start_transaction(root, 0);
...@@ -762,7 +762,7 @@ void btrfs_dev_replace_suspend_for_unmount(struct btrfs_fs_info *fs_info) ...@@ -762,7 +762,7 @@ void btrfs_dev_replace_suspend_for_unmount(struct btrfs_fs_info *fs_info)
struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
mutex_lock(&dev_replace->lock_finishing_cancel_unmount); mutex_lock(&dev_replace->lock_finishing_cancel_unmount);
btrfs_dev_replace_lock(dev_replace, 1); btrfs_dev_replace_write_lock(dev_replace);
switch (dev_replace->replace_state) { switch (dev_replace->replace_state) {
case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED: case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED: case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
...@@ -778,7 +778,7 @@ void btrfs_dev_replace_suspend_for_unmount(struct btrfs_fs_info *fs_info) ...@@ -778,7 +778,7 @@ void btrfs_dev_replace_suspend_for_unmount(struct btrfs_fs_info *fs_info)
break; break;
} }
btrfs_dev_replace_unlock(dev_replace, 1); btrfs_dev_replace_write_unlock(dev_replace);
mutex_unlock(&dev_replace->lock_finishing_cancel_unmount); mutex_unlock(&dev_replace->lock_finishing_cancel_unmount);
} }
...@@ -788,12 +788,12 @@ int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info) ...@@ -788,12 +788,12 @@ int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info)
struct task_struct *task; struct task_struct *task;
struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
btrfs_dev_replace_lock(dev_replace, 1); btrfs_dev_replace_write_lock(dev_replace);
switch (dev_replace->replace_state) { switch (dev_replace->replace_state) {
case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED: case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED: case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED: case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED:
btrfs_dev_replace_unlock(dev_replace, 1); btrfs_dev_replace_write_unlock(dev_replace);
return 0; return 0;
case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED: case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
break; break;
...@@ -807,10 +807,10 @@ int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info) ...@@ -807,10 +807,10 @@ int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info)
"cannot continue dev_replace, tgtdev is missing"); "cannot continue dev_replace, tgtdev is missing");
btrfs_info(fs_info, btrfs_info(fs_info,
"you may cancel the operation after 'mount -o degraded'"); "you may cancel the operation after 'mount -o degraded'");
btrfs_dev_replace_unlock(dev_replace, 1); btrfs_dev_replace_write_unlock(dev_replace);
return 0; return 0;
} }
btrfs_dev_replace_unlock(dev_replace, 1); btrfs_dev_replace_write_unlock(dev_replace);
WARN_ON(test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)); WARN_ON(test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags));
task = kthread_run(btrfs_dev_replace_kthread, fs_info, "btrfs-devrepl"); task = kthread_run(btrfs_dev_replace_kthread, fs_info, "btrfs-devrepl");
...@@ -879,10 +879,21 @@ int btrfs_dev_replace_is_ongoing(struct btrfs_dev_replace *dev_replace) ...@@ -879,10 +879,21 @@ int btrfs_dev_replace_is_ongoing(struct btrfs_dev_replace *dev_replace)
return 1; return 1;
} }
void btrfs_dev_replace_lock(struct btrfs_dev_replace *dev_replace, int rw) void btrfs_dev_replace_read_lock(struct btrfs_dev_replace *dev_replace)
{
read_lock(&dev_replace->lock);
atomic_inc(&dev_replace->read_locks);
}
void btrfs_dev_replace_read_unlock(struct btrfs_dev_replace *dev_replace)
{
ASSERT(atomic_read(&dev_replace->read_locks) > 0);
atomic_dec(&dev_replace->read_locks);
read_unlock(&dev_replace->lock);
}
void btrfs_dev_replace_write_lock(struct btrfs_dev_replace *dev_replace)
{ {
if (rw == 1) {
/* write */
again: again:
wait_event(dev_replace->read_lock_wq, wait_event(dev_replace->read_lock_wq,
atomic_read(&dev_replace->blocking_readers) == 0); atomic_read(&dev_replace->blocking_readers) == 0);
...@@ -891,23 +902,12 @@ void btrfs_dev_replace_lock(struct btrfs_dev_replace *dev_replace, int rw) ...@@ -891,23 +902,12 @@ void btrfs_dev_replace_lock(struct btrfs_dev_replace *dev_replace, int rw)
write_unlock(&dev_replace->lock); write_unlock(&dev_replace->lock);
goto again; goto again;
} }
} else {
read_lock(&dev_replace->lock);
atomic_inc(&dev_replace->read_locks);
}
} }
void btrfs_dev_replace_unlock(struct btrfs_dev_replace *dev_replace, int rw) void btrfs_dev_replace_write_unlock(struct btrfs_dev_replace *dev_replace)
{ {
if (rw == 1) {
/* write */
ASSERT(atomic_read(&dev_replace->blocking_readers) == 0); ASSERT(atomic_read(&dev_replace->blocking_readers) == 0);
write_unlock(&dev_replace->lock); write_unlock(&dev_replace->lock);
} else {
ASSERT(atomic_read(&dev_replace->read_locks) > 0);
atomic_dec(&dev_replace->read_locks);
read_unlock(&dev_replace->lock);
}
} }
/* inc blocking cnt and release read lock */ /* inc blocking cnt and release read lock */
......
...@@ -36,8 +36,10 @@ int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info); ...@@ -36,8 +36,10 @@ int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info);
void btrfs_dev_replace_suspend_for_unmount(struct btrfs_fs_info *fs_info); void btrfs_dev_replace_suspend_for_unmount(struct btrfs_fs_info *fs_info);
int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info); int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info);
int btrfs_dev_replace_is_ongoing(struct btrfs_dev_replace *dev_replace); int btrfs_dev_replace_is_ongoing(struct btrfs_dev_replace *dev_replace);
void btrfs_dev_replace_lock(struct btrfs_dev_replace *dev_replace, int rw); void btrfs_dev_replace_read_lock(struct btrfs_dev_replace *dev_replace);
void btrfs_dev_replace_unlock(struct btrfs_dev_replace *dev_replace, int rw); void btrfs_dev_replace_read_unlock(struct btrfs_dev_replace *dev_replace);
void btrfs_dev_replace_write_lock(struct btrfs_dev_replace *dev_replace);
void btrfs_dev_replace_write_unlock(struct btrfs_dev_replace *dev_replace);
void btrfs_dev_replace_set_lock_blocking(struct btrfs_dev_replace *dev_replace); void btrfs_dev_replace_set_lock_blocking(struct btrfs_dev_replace *dev_replace);
void btrfs_dev_replace_clear_lock_blocking( void btrfs_dev_replace_clear_lock_blocking(
struct btrfs_dev_replace *dev_replace); struct btrfs_dev_replace *dev_replace);
......
...@@ -395,20 +395,20 @@ static struct reada_extent *reada_find_extent(struct btrfs_fs_info *fs_info, ...@@ -395,20 +395,20 @@ static struct reada_extent *reada_find_extent(struct btrfs_fs_info *fs_info,
goto error; goto error;
/* insert extent in reada_tree + all per-device trees, all or nothing */ /* insert extent in reada_tree + all per-device trees, all or nothing */
btrfs_dev_replace_lock(&fs_info->dev_replace, 0); btrfs_dev_replace_read_lock(&fs_info->dev_replace);
spin_lock(&fs_info->reada_lock); spin_lock(&fs_info->reada_lock);
ret = radix_tree_insert(&fs_info->reada_tree, index, re); ret = radix_tree_insert(&fs_info->reada_tree, index, re);
if (ret == -EEXIST) { if (ret == -EEXIST) {
re_exist = radix_tree_lookup(&fs_info->reada_tree, index); re_exist = radix_tree_lookup(&fs_info->reada_tree, index);
re_exist->refcnt++; re_exist->refcnt++;
spin_unlock(&fs_info->reada_lock); spin_unlock(&fs_info->reada_lock);
btrfs_dev_replace_unlock(&fs_info->dev_replace, 0); btrfs_dev_replace_read_unlock(&fs_info->dev_replace);
radix_tree_preload_end(); radix_tree_preload_end();
goto error; goto error;
} }
if (ret) { if (ret) {
spin_unlock(&fs_info->reada_lock); spin_unlock(&fs_info->reada_lock);
btrfs_dev_replace_unlock(&fs_info->dev_replace, 0); btrfs_dev_replace_read_unlock(&fs_info->dev_replace);
radix_tree_preload_end(); radix_tree_preload_end();
goto error; goto error;
} }
...@@ -451,13 +451,13 @@ static struct reada_extent *reada_find_extent(struct btrfs_fs_info *fs_info, ...@@ -451,13 +451,13 @@ static struct reada_extent *reada_find_extent(struct btrfs_fs_info *fs_info,
} }
radix_tree_delete(&fs_info->reada_tree, index); radix_tree_delete(&fs_info->reada_tree, index);
spin_unlock(&fs_info->reada_lock); spin_unlock(&fs_info->reada_lock);
btrfs_dev_replace_unlock(&fs_info->dev_replace, 0); btrfs_dev_replace_read_unlock(&fs_info->dev_replace);
goto error; goto error;
} }
have_zone = 1; have_zone = 1;
} }
spin_unlock(&fs_info->reada_lock); spin_unlock(&fs_info->reada_lock);
btrfs_dev_replace_unlock(&fs_info->dev_replace, 0); btrfs_dev_replace_read_unlock(&fs_info->dev_replace);
if (!have_zone) if (!have_zone)
goto error; goto error;
......
...@@ -3935,11 +3935,11 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, ...@@ -3935,11 +3935,11 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
break; break;
} }
btrfs_dev_replace_lock(&fs_info->dev_replace, 1); btrfs_dev_replace_write_lock(&fs_info->dev_replace);
dev_replace->cursor_right = found_key.offset + length; dev_replace->cursor_right = found_key.offset + length;
dev_replace->cursor_left = found_key.offset; dev_replace->cursor_left = found_key.offset;
dev_replace->item_needs_writeback = 1; dev_replace->item_needs_writeback = 1;
btrfs_dev_replace_unlock(&fs_info->dev_replace, 1); btrfs_dev_replace_write_unlock(&fs_info->dev_replace);
ret = scrub_chunk(sctx, scrub_dev, chunk_offset, length, ret = scrub_chunk(sctx, scrub_dev, chunk_offset, length,
found_key.offset, cache, is_dev_replace); found_key.offset, cache, is_dev_replace);
...@@ -3975,10 +3975,10 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, ...@@ -3975,10 +3975,10 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
scrub_pause_off(fs_info); scrub_pause_off(fs_info);
btrfs_dev_replace_lock(&fs_info->dev_replace, 1); btrfs_dev_replace_write_lock(&fs_info->dev_replace);
dev_replace->cursor_left = dev_replace->cursor_right; dev_replace->cursor_left = dev_replace->cursor_right;
dev_replace->item_needs_writeback = 1; dev_replace->item_needs_writeback = 1;
btrfs_dev_replace_unlock(&fs_info->dev_replace, 1); btrfs_dev_replace_write_unlock(&fs_info->dev_replace);
if (ro_set) if (ro_set)
btrfs_dec_block_group_ro(cache); btrfs_dec_block_group_ro(cache);
...@@ -4194,16 +4194,16 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start, ...@@ -4194,16 +4194,16 @@ int btrfs_scrub_dev(struct btrfs_fs_info *fs_info, u64 devid, u64 start,
return -EIO; return -EIO;
} }
btrfs_dev_replace_lock(&fs_info->dev_replace, 0); btrfs_dev_replace_read_lock(&fs_info->dev_replace);
if (dev->scrub_ctx || if (dev->scrub_ctx ||
(!is_dev_replace && (!is_dev_replace &&
btrfs_dev_replace_is_ongoing(&fs_info->dev_replace))) { btrfs_dev_replace_is_ongoing(&fs_info->dev_replace))) {
btrfs_dev_replace_unlock(&fs_info->dev_replace, 0); btrfs_dev_replace_read_unlock(&fs_info->dev_replace);
mutex_unlock(&fs_info->scrub_lock); mutex_unlock(&fs_info->scrub_lock);
mutex_unlock(&fs_info->fs_devices->device_list_mutex); mutex_unlock(&fs_info->fs_devices->device_list_mutex);
return -EINPROGRESS; return -EINPROGRESS;
} }
btrfs_dev_replace_unlock(&fs_info->dev_replace, 0); btrfs_dev_replace_read_unlock(&fs_info->dev_replace);
ret = scrub_workers_get(fs_info, is_dev_replace); ret = scrub_workers_get(fs_info, is_dev_replace);
if (ret) { if (ret) {
......
...@@ -1936,12 +1936,12 @@ int btrfs_rm_device(struct btrfs_fs_info *fs_info, const char *device_path, ...@@ -1936,12 +1936,12 @@ int btrfs_rm_device(struct btrfs_fs_info *fs_info, const char *device_path,
mutex_lock(&uuid_mutex); mutex_lock(&uuid_mutex);
num_devices = fs_info->fs_devices->num_devices; num_devices = fs_info->fs_devices->num_devices;
btrfs_dev_replace_lock(&fs_info->dev_replace, 0); btrfs_dev_replace_read_lock(&fs_info->dev_replace);
if (btrfs_dev_replace_is_ongoing(&fs_info->dev_replace)) { if (btrfs_dev_replace_is_ongoing(&fs_info->dev_replace)) {
WARN_ON(num_devices < 1); WARN_ON(num_devices < 1);
num_devices--; num_devices--;
} }
btrfs_dev_replace_unlock(&fs_info->dev_replace, 0); btrfs_dev_replace_read_unlock(&fs_info->dev_replace);
ret = btrfs_check_raid_min_devices(fs_info, num_devices - 1); ret = btrfs_check_raid_min_devices(fs_info, num_devices - 1);
if (ret) if (ret)
...@@ -3910,12 +3910,12 @@ int btrfs_balance(struct btrfs_balance_control *bctl, ...@@ -3910,12 +3910,12 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
} }
num_devices = fs_info->fs_devices->num_devices; num_devices = fs_info->fs_devices->num_devices;
btrfs_dev_replace_lock(&fs_info->dev_replace, 0); btrfs_dev_replace_read_lock(&fs_info->dev_replace);
if (btrfs_dev_replace_is_ongoing(&fs_info->dev_replace)) { if (btrfs_dev_replace_is_ongoing(&fs_info->dev_replace)) {
BUG_ON(num_devices < 1); BUG_ON(num_devices < 1);
num_devices--; num_devices--;
} }
btrfs_dev_replace_unlock(&fs_info->dev_replace, 0); btrfs_dev_replace_read_unlock(&fs_info->dev_replace);
allowed = BTRFS_AVAIL_ALLOC_BIT_SINGLE | BTRFS_BLOCK_GROUP_DUP; allowed = BTRFS_AVAIL_ALLOC_BIT_SINGLE | BTRFS_BLOCK_GROUP_DUP;
if (num_devices > 1) if (num_devices > 1)
allowed |= (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1); allowed |= (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1);
...@@ -5241,11 +5241,11 @@ int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len) ...@@ -5241,11 +5241,11 @@ int btrfs_num_copies(struct btrfs_fs_info *fs_info, u64 logical, u64 len)
ret = 1; ret = 1;
free_extent_map(em); free_extent_map(em);
btrfs_dev_replace_lock(&fs_info->dev_replace, 0); btrfs_dev_replace_read_lock(&fs_info->dev_replace);
if (btrfs_dev_replace_is_ongoing(&fs_info->dev_replace) && if (btrfs_dev_replace_is_ongoing(&fs_info->dev_replace) &&
fs_info->dev_replace.tgtdev) fs_info->dev_replace.tgtdev)
ret++; ret++;
btrfs_dev_replace_unlock(&fs_info->dev_replace, 0); btrfs_dev_replace_read_unlock(&fs_info->dev_replace);
return ret; return ret;
} }
...@@ -5823,10 +5823,10 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, ...@@ -5823,10 +5823,10 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info,
if (!bbio_ret) if (!bbio_ret)
goto out; goto out;
btrfs_dev_replace_lock(dev_replace, 0); btrfs_dev_replace_read_lock(dev_replace);
dev_replace_is_ongoing = btrfs_dev_replace_is_ongoing(dev_replace); dev_replace_is_ongoing = btrfs_dev_replace_is_ongoing(dev_replace);
if (!dev_replace_is_ongoing) if (!dev_replace_is_ongoing)
btrfs_dev_replace_unlock(dev_replace, 0); btrfs_dev_replace_read_unlock(dev_replace);
else else
btrfs_dev_replace_set_lock_blocking(dev_replace); btrfs_dev_replace_set_lock_blocking(dev_replace);
...@@ -6024,7 +6024,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info, ...@@ -6024,7 +6024,7 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info,
out: out:
if (dev_replace_is_ongoing) { if (dev_replace_is_ongoing) {
btrfs_dev_replace_clear_lock_blocking(dev_replace); btrfs_dev_replace_clear_lock_blocking(dev_replace);
btrfs_dev_replace_unlock(dev_replace, 0); btrfs_dev_replace_read_unlock(dev_replace);
} }
free_extent_map(em); free_extent_map(em);
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment