diff options
Diffstat (limited to 'fs/btrfs/dev-replace.c')
| -rw-r--r-- | fs/btrfs/dev-replace.c | 38 | 
1 files changed, 27 insertions, 11 deletions
| diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index 1502d664c892..fb33027e5a4c 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c @@ -246,7 +246,7 @@ static int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,  {  	struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;  	struct btrfs_device *device; -	struct bdev_handle *bdev_handle; +	struct file *bdev_file;  	struct block_device *bdev;  	u64 devid = BTRFS_DEV_REPLACE_DEVID;  	int ret = 0; @@ -257,13 +257,13 @@ static int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,  		return -EINVAL;  	} -	bdev_handle = bdev_open_by_path(device_path, BLK_OPEN_WRITE, +	bdev_file = bdev_file_open_by_path(device_path, BLK_OPEN_WRITE,  					fs_info->bdev_holder, NULL); -	if (IS_ERR(bdev_handle)) { +	if (IS_ERR(bdev_file)) {  		btrfs_err(fs_info, "target device %s is invalid!", device_path); -		return PTR_ERR(bdev_handle); +		return PTR_ERR(bdev_file);  	} -	bdev = bdev_handle->bdev; +	bdev = file_bdev(bdev_file);  	if (!btrfs_check_device_zone_type(fs_info, bdev)) {  		btrfs_err(fs_info, @@ -314,7 +314,7 @@ static int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,  	device->commit_bytes_used = device->bytes_used;  	device->fs_info = fs_info;  	device->bdev = bdev; -	device->bdev_handle = bdev_handle; +	device->bdev_file = bdev_file;  	set_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &device->dev_state);  	set_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state);  	device->dev_stats_valid = 1; @@ -335,7 +335,7 @@ static int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,  	return 0;  error: -	bdev_release(bdev_handle); +	fput(bdev_file);  	return ret;  } @@ -725,6 +725,23 @@ leave:  	return ret;  } +static int btrfs_check_replace_dev_names(struct btrfs_ioctl_dev_replace_args *args) +{ +	if (args->start.srcdevid == 0) { +		if (memchr(args->start.srcdev_name, 0, +			   sizeof(args->start.srcdev_name)) == NULL) +			return -ENAMETOOLONG; +	} else { +		args->start.srcdev_name[0] = 0; +	} + +	if (memchr(args->start.tgtdev_name, 0, +		   sizeof(args->start.tgtdev_name)) == NULL) +	    return -ENAMETOOLONG; + +	return 0; +} +  int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,  			    struct btrfs_ioctl_dev_replace_args *args)  { @@ -737,10 +754,9 @@ int btrfs_dev_replace_by_ioctl(struct btrfs_fs_info *fs_info,  	default:  		return -EINVAL;  	} - -	if ((args->start.srcdevid == 0 && args->start.srcdev_name[0] == '\0') || -	    args->start.tgtdev_name[0] == '\0') -		return -EINVAL; +	ret = btrfs_check_replace_dev_names(args); +	if (ret < 0) +		return ret;  	ret = btrfs_dev_replace_start(fs_info, args->start.tgtdev_name,  					args->start.srcdevid, |