]> git.ipfire.org Git - thirdparty/kernel/stable.git/blobdiff - fs/btrfs/dev-replace.c
nfs: Fix NULL pointer dereference of dev_name
[thirdparty/kernel/stable.git] / fs / btrfs / dev-replace.c
index 7c655f9a7a504e5d758323e6be536cfb39753b2d..f86457713e60d705b4d0d7d7ff1a1cf4b99b5438 100644 (file)
@@ -351,6 +351,7 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
                break;
        case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:
        case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED:
+               ASSERT(0);
                ret = BTRFS_IOCTL_DEV_REPLACE_RESULT_ALREADY_STARTED;
                goto leave;
        }
@@ -395,6 +396,10 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
        if (IS_ERR(trans)) {
                ret = PTR_ERR(trans);
                btrfs_dev_replace_lock(dev_replace, 1);
+               dev_replace->replace_state =
+                       BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED;
+               dev_replace->srcdev = NULL;
+               dev_replace->tgtdev = NULL;
                goto leave;
        }
 
@@ -416,8 +421,6 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,
        return ret;
 
 leave:
-       dev_replace->srcdev = NULL;
-       dev_replace->tgtdev = NULL;
        btrfs_dev_replace_unlock(dev_replace, 1);
        btrfs_destroy_dev_replace_tgtdev(fs_info, tgt_device);
        return ret;
@@ -588,6 +591,12 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
 
        btrfs_rm_dev_replace_unblocked(fs_info);
 
+       /*
+        * Increment dev_stats_ccnt so that btrfs_run_dev_stats() will
+        * update on-disk dev stats value during commit transaction
+        */
+       atomic_inc(&tgt_device->dev_stats_ccnt);
+
        /*
         * this is again a consistent state where no dev_replace procedure
         * is running, the target device is part of the filesystem, the
@@ -795,6 +804,8 @@ int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info)
                           "cannot continue dev_replace, tgtdev is missing");
                btrfs_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_unlock(dev_replace, 1);
                return 0;
        }