Merge tag 'csky-for-linus-4.21' of git://github.com/c-sky/csky-linux
[linux-2.6-block.git] / fs / btrfs / dev-replace.c
index ead4f380352744f275c799637790b8b7bf242057..8750c835f53548963ad5cad5411cdbfbc3a6817b 100644 (file)
@@ -284,13 +284,13 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans,
        struct btrfs_dev_replace_item *ptr;
        struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
 
-       btrfs_dev_replace_read_lock(dev_replace);
+       down_read(&dev_replace->rwsem);
        if (!dev_replace->is_valid ||
            !dev_replace->item_needs_writeback) {
-               btrfs_dev_replace_read_unlock(dev_replace);
+               up_read(&dev_replace->rwsem);
                return 0;
        }
-       btrfs_dev_replace_read_unlock(dev_replace);
+       up_read(&dev_replace->rwsem);
 
        key.objectid = 0;
        key.type = BTRFS_DEV_REPLACE_KEY;
@@ -348,7 +348,7 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans,
        ptr = btrfs_item_ptr(eb, path->slots[0],
                             struct btrfs_dev_replace_item);
 
-       btrfs_dev_replace_write_lock(dev_replace);
+       down_write(&dev_replace->rwsem);
        if (dev_replace->srcdev)
                btrfs_set_dev_replace_src_devid(eb, ptr,
                        dev_replace->srcdev->devid);
@@ -371,7 +371,7 @@ int btrfs_run_dev_replace(struct btrfs_trans_handle *trans,
        btrfs_set_dev_replace_cursor_right(eb, ptr,
                dev_replace->cursor_right);
        dev_replace->item_needs_writeback = 0;
-       btrfs_dev_replace_write_unlock(dev_replace);
+       up_write(&dev_replace->rwsem);
 
        btrfs_mark_buffer_dirty(eb);
 
@@ -432,7 +432,7 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
        }
 
        need_unlock = true;
-       btrfs_dev_replace_write_lock(dev_replace);
+       down_write(&dev_replace->rwsem);
        switch (dev_replace->replace_state) {
        case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
        case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
@@ -470,7 +470,7 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
        dev_replace->item_needs_writeback = 1;
        atomic64_set(&dev_replace->num_write_errors, 0);
        atomic64_set(&dev_replace->num_uncorrectable_read_errors, 0);
-       btrfs_dev_replace_write_unlock(dev_replace);
+       up_write(&dev_replace->rwsem);
        need_unlock = false;
 
        ret = btrfs_sysfs_add_device_link(tgt_device->fs_devices, tgt_device);
@@ -484,7 +484,7 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
        if (IS_ERR(trans)) {
                ret = PTR_ERR(trans);
                need_unlock = true;
-               btrfs_dev_replace_write_lock(dev_replace);
+               down_write(&dev_replace->rwsem);
                dev_replace->replace_state =
                        BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED;
                dev_replace->srcdev = NULL;
@@ -511,7 +511,7 @@ static int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
 
 leave:
        if (need_unlock)
-               btrfs_dev_replace_write_unlock(dev_replace);
+               up_write(&dev_replace->rwsem);
        btrfs_destroy_dev_replace_tgtdev(tgt_device);
        return ret;
 }
@@ -579,18 +579,18 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
        /* don't allow cancel or unmount to disturb the finishing procedure */
        mutex_lock(&dev_replace->lock_finishing_cancel_unmount);
 
-       btrfs_dev_replace_read_lock(dev_replace);
+       down_read(&dev_replace->rwsem);
        /* was the operation canceled, or is it finished? */
        if (dev_replace->replace_state !=
            BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED) {
-               btrfs_dev_replace_read_unlock(dev_replace);
+               up_read(&dev_replace->rwsem);
                mutex_unlock(&dev_replace->lock_finishing_cancel_unmount);
                return 0;
        }
 
        tgt_device = dev_replace->tgtdev;
        src_device = dev_replace->srcdev;
-       btrfs_dev_replace_read_unlock(dev_replace);
+       up_read(&dev_replace->rwsem);
 
        /*
         * flush all outstanding I/O and inode extent mappings before the
@@ -614,7 +614,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
        /* keep away write_all_supers() during the finishing procedure */
        mutex_lock(&fs_info->fs_devices->device_list_mutex);
        mutex_lock(&fs_info->chunk_mutex);
-       btrfs_dev_replace_write_lock(dev_replace);
+       down_write(&dev_replace->rwsem);
        dev_replace->replace_state =
                scrub_ret ? BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED
                          : BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED;
@@ -629,12 +629,13 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
                                                                src_device,
                                                                tgt_device);
        } else {
-               btrfs_err_in_rcu(fs_info,
+               if (scrub_ret != -ECANCELED)
+                       btrfs_err_in_rcu(fs_info,
                                 "btrfs_scrub_dev(%s, %llu, %s) failed %d",
                                 btrfs_dev_name(src_device),
                                 src_device->devid,
                                 rcu_str_deref(tgt_device->name), scrub_ret);
-               btrfs_dev_replace_write_unlock(dev_replace);
+               up_write(&dev_replace->rwsem);
                mutex_unlock(&fs_info->chunk_mutex);
                mutex_unlock(&fs_info->fs_devices->device_list_mutex);
                btrfs_rm_dev_replace_blocked(fs_info);
@@ -670,8 +671,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);
        fs_info->fs_devices->rw_devices++;
 
-       btrfs_dev_replace_write_unlock(dev_replace);
-
+       up_write(&dev_replace->rwsem);
        btrfs_rm_dev_replace_blocked(fs_info);
 
        btrfs_rm_dev_replace_remove_srcdev(src_device);
@@ -768,7 +768,7 @@ void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info,
 {
        struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
 
-       btrfs_dev_replace_read_lock(dev_replace);
+       down_read(&dev_replace->rwsem);
        /* even if !dev_replace_is_valid, the values are good enough for
         * the replace_status ioctl */
        args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR;
@@ -780,7 +780,7 @@ void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info,
        args->status.num_uncorrectable_read_errors =
                atomic64_read(&dev_replace->num_uncorrectable_read_errors);
        args->status.progress_1000 = btrfs_dev_replace_progress(fs_info);
-       btrfs_dev_replace_read_unlock(dev_replace);
+       up_read(&dev_replace->rwsem);
 }
 
 int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info)
@@ -797,18 +797,18 @@ int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info)
                return -EROFS;
 
        mutex_lock(&dev_replace->lock_finishing_cancel_unmount);
-       btrfs_dev_replace_write_lock(dev_replace);
+       down_write(&dev_replace->rwsem);
        switch (dev_replace->replace_state) {
        case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
        case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
        case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED:
                result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED;
-               btrfs_dev_replace_write_unlock(dev_replace);
+               up_write(&dev_replace->rwsem);
                break;
        case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
                tgt_device = dev_replace->tgtdev;
                src_device = dev_replace->srcdev;
-               btrfs_dev_replace_write_unlock(dev_replace);
+               up_write(&dev_replace->rwsem);
                ret = btrfs_scrub_cancel(fs_info);
                if (ret < 0) {
                        result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NOT_STARTED;
@@ -839,7 +839,7 @@ int btrfs_dev_replace_cancel(struct btrfs_fs_info *fs_info)
                dev_replace->time_stopped = ktime_get_real_seconds();
                dev_replace->item_needs_writeback = 1;
 
-               btrfs_dev_replace_write_unlock(dev_replace);
+               up_write(&dev_replace->rwsem);
 
                /* Scrub for replace must not be running in suspended state */
                ret = btrfs_scrub_cancel(fs_info);
@@ -874,7 +874,8 @@ void btrfs_dev_replace_suspend_for_unmount(struct btrfs_fs_info *fs_info)
        struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
 
        mutex_lock(&dev_replace->lock_finishing_cancel_unmount);
-       btrfs_dev_replace_write_lock(dev_replace);
+       down_write(&dev_replace->rwsem);
+
        switch (dev_replace->replace_state) {
        case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
        case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
@@ -890,7 +891,7 @@ void btrfs_dev_replace_suspend_for_unmount(struct btrfs_fs_info *fs_info)
                break;
        }
 
-       btrfs_dev_replace_write_unlock(dev_replace);
+       up_write(&dev_replace->rwsem);
        mutex_unlock(&dev_replace->lock_finishing_cancel_unmount);
 }
 
@@ -900,12 +901,13 @@ int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info)
        struct task_struct *task;
        struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace;
 
-       btrfs_dev_replace_write_lock(dev_replace);
+       down_write(&dev_replace->rwsem);
+
        switch (dev_replace->replace_state) {
        case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:
        case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:
        case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED:
-               btrfs_dev_replace_write_unlock(dev_replace);
+               up_write(&dev_replace->rwsem);
                return 0;
        case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
                break;
@@ -921,10 +923,10 @@ int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info)
                           "you may cancel the operation after 'mount -o degraded'");
                dev_replace->replace_state =
                                        BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED;
-               btrfs_dev_replace_write_unlock(dev_replace);
+               up_write(&dev_replace->rwsem);
                return 0;
        }
-       btrfs_dev_replace_write_unlock(dev_replace);
+       up_write(&dev_replace->rwsem);
 
        /*
         * This could collide with a paused balance, but the exclusive op logic
@@ -932,10 +934,10 @@ int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info)
         * dev-replace to start anyway.
         */
        if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) {
-               btrfs_dev_replace_write_lock(dev_replace);
+               down_write(&dev_replace->rwsem);
                dev_replace->replace_state =
                                        BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED;
-               btrfs_dev_replace_write_unlock(dev_replace);
+               up_write(&dev_replace->rwsem);
                btrfs_info(fs_info,
                "cannot resume dev-replace, other exclusive operation running");
                return 0;
@@ -989,7 +991,7 @@ int btrfs_dev_replace_is_ongoing(struct btrfs_dev_replace *dev_replace)
                 * something that can happen if the dev_replace
                 * procedure is suspended by an umount and then
                 * the tgtdev is missing (or "btrfs dev scan") was
-                * not called and the the filesystem is remounted
+                * not called and the filesystem is remounted
                 * in degraded state. This does not stop the
                 * dev_replace procedure. It needs to be canceled
                 * manually if the cancellation is wanted.
@@ -999,42 +1001,6 @@ int btrfs_dev_replace_is_ongoing(struct btrfs_dev_replace *dev_replace)
        return 1;
 }
 
-void btrfs_dev_replace_read_lock(struct btrfs_dev_replace *dev_replace)
-{
-       read_lock(&dev_replace->lock);
-}
-
-void btrfs_dev_replace_read_unlock(struct btrfs_dev_replace *dev_replace)
-{
-       read_unlock(&dev_replace->lock);
-}
-
-void btrfs_dev_replace_write_lock(struct btrfs_dev_replace *dev_replace)
-{
-again:
-       wait_event(dev_replace->read_lock_wq,
-                  atomic_read(&dev_replace->blocking_readers) == 0);
-       write_lock(&dev_replace->lock);
-       if (atomic_read(&dev_replace->blocking_readers)) {
-               write_unlock(&dev_replace->lock);
-               goto again;
-       }
-}
-
-void btrfs_dev_replace_write_unlock(struct btrfs_dev_replace *dev_replace)
-{
-       write_unlock(&dev_replace->lock);
-}
-
-/* inc blocking cnt and release read lock */
-void btrfs_dev_replace_set_lock_blocking(
-                                       struct btrfs_dev_replace *dev_replace)
-{
-       /* only set blocking for read lock */
-       atomic_inc(&dev_replace->blocking_readers);
-       read_unlock(&dev_replace->lock);
-}
-
 void btrfs_bio_counter_inc_noblocked(struct btrfs_fs_info *fs_info)
 {
        percpu_counter_inc(&fs_info->dev_replace.bio_counter);