diff options
Diffstat (limited to 'fs/btrfs/ioctl.c')
| -rw-r--r-- | fs/btrfs/ioctl.c | 75 | 
1 files changed, 34 insertions, 41 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 23272d9154f3..18e328ce4b54 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -479,10 +479,9 @@ static int btrfs_ioctl_getversion(struct file *file, int __user *arg)  	return put_user(inode->i_generation, arg);  } -static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) +static noinline int btrfs_ioctl_fitrim(struct btrfs_fs_info *fs_info, +					void __user *arg)  { -	struct inode *inode = file_inode(file); -	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);  	struct btrfs_device *device;  	struct request_queue *q;  	struct fstrim_range range; @@ -541,7 +540,7 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)  	return 0;  } -int btrfs_is_empty_uuid(u8 *uuid) +int __pure btrfs_is_empty_uuid(u8 *uuid)  {  	int i; @@ -705,11 +704,17 @@ static noinline int create_subvol(struct inode *dir,  	btrfs_i_size_write(BTRFS_I(dir), dir->i_size + namelen * 2);  	ret = btrfs_update_inode(trans, root, dir); -	BUG_ON(ret); +	if (ret) { +		btrfs_abort_transaction(trans, ret); +		goto fail; +	}  	ret = btrfs_add_root_ref(trans, objectid, root->root_key.objectid,  				 btrfs_ino(BTRFS_I(dir)), index, name, namelen); -	BUG_ON(ret); +	if (ret) { +		btrfs_abort_transaction(trans, ret); +		goto fail; +	}  	ret = btrfs_uuid_tree_add(trans, root_item->uuid,  				  BTRFS_UUID_KEY_SUBVOL, objectid); @@ -1409,7 +1414,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,  		return -EINVAL;  	if (do_compress) { -		if (range->compress_type > BTRFS_COMPRESS_TYPES) +		if (range->compress_type >= BTRFS_NR_COMPRESS_TYPES)  			return -EINVAL;  		if (range->compress_type)  			compress_type = range->compress_type; @@ -2462,7 +2467,7 @@ static int btrfs_search_path_in_tree_user(struct inode *inode,  				goto out;  			} -			temp_inode = btrfs_iget(sb, &key2, root, NULL); +			temp_inode = btrfs_iget(sb, &key2, root);  			if (IS_ERR(temp_inode)) {  				ret = PTR_ERR(temp_inode);  				goto out; @@ -3721,24 +3726,18 @@ process_slot:  	ret = 0;  	if (last_dest_end < destoff + len) { -		struct btrfs_clone_extent_info clone_info = { 0 };  		/* -		 * We have an implicit hole (NO_HOLES feature is enabled) that -		 * fully or partially overlaps our cloning range at its end. +		 * We have an implicit hole that fully or partially overlaps our +		 * cloning range at its end. This means that we either have the +		 * NO_HOLES feature enabled or the implicit hole happened due to +		 * mixing buffered and direct IO writes against this file.  		 */  		btrfs_release_path(path);  		path->leave_spinning = 0; -		/* -		 * We are dealing with a hole and our clone_info already has a -		 * disk_offset of 0, we only need to fill the data length and -		 * file offset. -		 */ -		clone_info.data_len = destoff + len - last_dest_end; -		clone_info.file_offset = last_dest_end;  		ret = btrfs_punch_hole_range(inode, path,  					     last_dest_end, destoff + len - 1, -					     &clone_info, &trans); +					     NULL, &trans);  		if (ret)  			goto out; @@ -4032,16 +4031,15 @@ out:  static void get_block_group_info(struct list_head *groups_list,  				 struct btrfs_ioctl_space_info *space)  { -	struct btrfs_block_group_cache *block_group; +	struct btrfs_block_group *block_group;  	space->total_bytes = 0;  	space->used_bytes = 0;  	space->flags = 0;  	list_for_each_entry(block_group, groups_list, list) {  		space->flags = block_group->flags; -		space->total_bytes += block_group->key.offset; -		space->used_bytes += -			btrfs_block_group_used(&block_group->item); +		space->total_bytes += block_group->length; +		space->used_bytes += block_group->used;  	}  } @@ -4952,10 +4950,9 @@ drop_write:  	return ret;  } -static long btrfs_ioctl_quota_rescan_status(struct file *file, void __user *arg) +static long btrfs_ioctl_quota_rescan_status(struct btrfs_fs_info *fs_info, +						void __user *arg)  { -	struct inode *inode = file_inode(file); -	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);  	struct btrfs_ioctl_quota_rescan_args *qsa;  	int ret = 0; @@ -4978,11 +4975,9 @@ static long btrfs_ioctl_quota_rescan_status(struct file *file, void __user *arg)  	return ret;  } -static long btrfs_ioctl_quota_rescan_wait(struct file *file, void __user *arg) +static long btrfs_ioctl_quota_rescan_wait(struct btrfs_fs_info *fs_info, +						void __user *arg)  { -	struct inode *inode = file_inode(file); -	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); -  	if (!capable(CAP_SYS_ADMIN))  		return -EPERM; @@ -5154,10 +5149,9 @@ out:  	return ret;  } -static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) +static int btrfs_ioctl_get_fslabel(struct btrfs_fs_info *fs_info, +					void __user *arg)  { -	struct inode *inode = file_inode(file); -	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);  	size_t len;  	int ret;  	char label[BTRFS_LABEL_SIZE]; @@ -5241,10 +5235,9 @@ int btrfs_ioctl_get_supported_features(void __user *arg)  	return 0;  } -static int btrfs_ioctl_get_features(struct file *file, void __user *arg) +static int btrfs_ioctl_get_features(struct btrfs_fs_info *fs_info, +					void __user *arg)  { -	struct inode *inode = file_inode(file); -	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);  	struct btrfs_super_block *super_block = fs_info->super_copy;  	struct btrfs_ioctl_feature_flags features; @@ -5445,11 +5438,11 @@ long btrfs_ioctl(struct file *file, unsigned int  	case FS_IOC_GETVERSION:  		return btrfs_ioctl_getversion(file, argp);  	case FS_IOC_GETFSLABEL: -		return btrfs_ioctl_get_fslabel(file, argp); +		return btrfs_ioctl_get_fslabel(fs_info, argp);  	case FS_IOC_SETFSLABEL:  		return btrfs_ioctl_set_fslabel(file, argp);  	case FITRIM: -		return btrfs_ioctl_fitrim(file, argp); +		return btrfs_ioctl_fitrim(fs_info, argp);  	case BTRFS_IOC_SNAP_CREATE:  		return btrfs_ioctl_snap_create(file, argp, 0);  	case BTRFS_IOC_SNAP_CREATE_V2: @@ -5554,15 +5547,15 @@ long btrfs_ioctl(struct file *file, unsigned int  	case BTRFS_IOC_QUOTA_RESCAN:  		return btrfs_ioctl_quota_rescan(file, argp);  	case BTRFS_IOC_QUOTA_RESCAN_STATUS: -		return btrfs_ioctl_quota_rescan_status(file, argp); +		return btrfs_ioctl_quota_rescan_status(fs_info, argp);  	case BTRFS_IOC_QUOTA_RESCAN_WAIT: -		return btrfs_ioctl_quota_rescan_wait(file, argp); +		return btrfs_ioctl_quota_rescan_wait(fs_info, argp);  	case BTRFS_IOC_DEV_REPLACE:  		return btrfs_ioctl_dev_replace(fs_info, argp);  	case BTRFS_IOC_GET_SUPPORTED_FEATURES:  		return btrfs_ioctl_get_supported_features(argp);  	case BTRFS_IOC_GET_FEATURES: -		return btrfs_ioctl_get_features(file, argp); +		return btrfs_ioctl_get_features(fs_info, argp);  	case BTRFS_IOC_SET_FEATURES:  		return btrfs_ioctl_set_features(file, argp);  	case FS_IOC_FSGETXATTR:  |