FAILED: patch "[PATCH] btrfs: fix error handling in btrfs_dev_replace_start" failed to apply to 4.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
5c06147128fbbdf7a84232c5f0d808f53153defeMon Sep 17 00:00:00 2001
From: Jeff Mahoney <[email protected]>
Date: Thu, 6 Sep 2018 15:52:17 -0400
Subject: [PATCH] btrfs: fix error handling in btrfs_dev_replace_start
When we fail to start a transaction in btrfs_dev_replace_start, we leave dev_replace->replace_start set to STARTED but clear ->srcdev and ->tgtdev. Later, that can result in an Oops in btrfs_dev_replace_progress when having state set to STARTED or SUSPENDED implies that ->srcdev is valid.
Also fix error handling when the state is already STARTED or SUSPENDED while starting. That, too, will clear ->srcdev and ->tgtdev even though it doesn't own them. This should be an impossible case to hit since we should be protected by the BTRFS_FS_EXCL_OP bit being set. Let's add an ASSERT there while we're at it.
fs/btrfs/dev-replace.c +5 -2
@@ -440,6 +440,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; }
@@ -482,6 +483,10 @@ int btrfs_dev_replace_start(struct btrfs_fs_info *fs_info,if (IS_ERR (trans)) { ret =PTR_ERR (trans);btrfs_dev_replace_write_lock (dev_replace); + dev_replace->replace_state = +BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED ; + dev_replace->srcdev =NULL ; + dev_replace->tgtdev =NULL ; goto leave; }
@@ -503,8 +508,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_write_unlock (dev_replace);btrfs_destroy_dev_replace_tgtdev (tgt_device);return ret;