diff options
Diffstat (limited to 'fs/btrfs/dev-replace.c')
| -rw-r--r-- | fs/btrfs/dev-replace.c | 26 | 
1 files changed, 24 insertions, 2 deletions
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index 5b9e3f3ace22..10638537b9ef 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c @@ -91,6 +91,17 @@ int btrfs_init_dev_replace(struct btrfs_fs_info *fs_info)  	ret = btrfs_search_slot(NULL, dev_root, &key, path, 0, 0);  	if (ret) {  no_valid_dev_replace_entry_found: +		/* +		 * We don't have a replace item or it's corrupted.  If there is +		 * a replace target, fail the mount. +		 */ +		if (btrfs_find_device(fs_info->fs_devices, +				      BTRFS_DEV_REPLACE_DEVID, NULL, NULL, false)) { +			btrfs_err(fs_info, +			"found replace target device without a valid replace item"); +			ret = -EUCLEAN; +			goto out; +		}  		ret = 0;  		dev_replace->replace_state =  			BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED; @@ -143,8 +154,19 @@ no_valid_dev_replace_entry_found:  	case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED:  	case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED:  	case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED: -		dev_replace->srcdev = NULL; -		dev_replace->tgtdev = NULL; +		/* +		 * We don't have an active replace item but if there is a +		 * replace target, fail the mount. +		 */ +		if (btrfs_find_device(fs_info->fs_devices, +				      BTRFS_DEV_REPLACE_DEVID, NULL, NULL, false)) { +			btrfs_err(fs_info, +			"replace devid present without an active replace item"); +			ret = -EUCLEAN; +		} else { +			dev_replace->srcdev = NULL; +			dev_replace->tgtdev = NULL; +		}  		break;  	case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED:  	case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED:  | 
