aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ioctl.c41
-rw-r--r--include/uapi/linux/btrfs.h10
2 files changed, 51 insertions, 0 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 393a543a519e..6ea15469c63f 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2172,6 +2172,45 @@ static noinline int btrfs_ioctl_tree_search(struct file *file,
2172 return ret; 2172 return ret;
2173} 2173}
2174 2174
2175static noinline int btrfs_ioctl_tree_search_v2(struct file *file,
2176 void __user *argp)
2177{
2178 struct btrfs_ioctl_search_args_v2 __user *uarg;
2179 struct btrfs_ioctl_search_args_v2 args;
2180 struct inode *inode;
2181 int ret;
2182 size_t buf_size;
2183 const size_t buf_limit = 16 * 1024 * 1024;
2184
2185 if (!capable(CAP_SYS_ADMIN))
2186 return -EPERM;
2187
2188 /* copy search header and buffer size */
2189 uarg = (struct btrfs_ioctl_search_args_v2 __user *)argp;
2190 if (copy_from_user(&args, uarg, sizeof(args)))
2191 return -EFAULT;
2192
2193 buf_size = args.buf_size;
2194
2195 if (buf_size < sizeof(struct btrfs_ioctl_search_header))
2196 return -EOVERFLOW;
2197
2198 /* limit result size to 16MB */
2199 if (buf_size > buf_limit)
2200 buf_size = buf_limit;
2201
2202 inode = file_inode(file);
2203 ret = search_ioctl(inode, &args.key, &buf_size,
2204 (char *)(&uarg->buf[0]));
2205 if (ret == 0 && copy_to_user(&uarg->key, &args.key, sizeof(args.key)))
2206 ret = -EFAULT;
2207 else if (ret == -EOVERFLOW &&
2208 copy_to_user(&uarg->buf_size, &buf_size, sizeof(buf_size)))
2209 ret = -EFAULT;
2210
2211 return ret;
2212}
2213
2175/* 2214/*
2176 * Search INODE_REFs to identify path name of 'dirid' directory 2215 * Search INODE_REFs to identify path name of 'dirid' directory
2177 * in a 'tree_id' tree. and sets path name to 'name'. 2216 * in a 'tree_id' tree. and sets path name to 'name'.
@@ -5252,6 +5291,8 @@ long btrfs_ioctl(struct file *file, unsigned int
5252 return btrfs_ioctl_trans_end(file); 5291 return btrfs_ioctl_trans_end(file);
5253 case BTRFS_IOC_TREE_SEARCH: 5292 case BTRFS_IOC_TREE_SEARCH:
5254 return btrfs_ioctl_tree_search(file, argp); 5293 return btrfs_ioctl_tree_search(file, argp);
5294 case BTRFS_IOC_TREE_SEARCH_V2:
5295 return btrfs_ioctl_tree_search_v2(file, argp);
5255 case BTRFS_IOC_INO_LOOKUP: 5296 case BTRFS_IOC_INO_LOOKUP:
5256 return btrfs_ioctl_ino_lookup(file, argp); 5297 return btrfs_ioctl_ino_lookup(file, argp);
5257 case BTRFS_IOC_INO_PATHS: 5298 case BTRFS_IOC_INO_PATHS:
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index 7554fd381a56..6f9c38ce45c7 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -306,6 +306,14 @@ struct btrfs_ioctl_search_args {
306 char buf[BTRFS_SEARCH_ARGS_BUFSIZE]; 306 char buf[BTRFS_SEARCH_ARGS_BUFSIZE];
307}; 307};
308 308
309struct btrfs_ioctl_search_args_v2 {
310 struct btrfs_ioctl_search_key key; /* in/out - search parameters */
311 __u64 buf_size; /* in - size of buffer
312 * out - on EOVERFLOW: needed size
313 * to store item */
314 __u64 buf[0]; /* out - found items */
315};
316
309struct btrfs_ioctl_clone_range_args { 317struct btrfs_ioctl_clone_range_args {
310 __s64 src_fd; 318 __s64 src_fd;
311 __u64 src_offset, src_length; 319 __u64 src_offset, src_length;
@@ -558,6 +566,8 @@ static inline char *btrfs_err_str(enum btrfs_err_code err_code)
558 struct btrfs_ioctl_defrag_range_args) 566 struct btrfs_ioctl_defrag_range_args)
559#define BTRFS_IOC_TREE_SEARCH _IOWR(BTRFS_IOCTL_MAGIC, 17, \ 567#define BTRFS_IOC_TREE_SEARCH _IOWR(BTRFS_IOCTL_MAGIC, 17, \
560 struct btrfs_ioctl_search_args) 568 struct btrfs_ioctl_search_args)
569#define BTRFS_IOC_TREE_SEARCH_V2 _IOWR(BTRFS_IOCTL_MAGIC, 17, \
570 struct btrfs_ioctl_search_args_v2)
561#define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, \ 571#define BTRFS_IOC_INO_LOOKUP _IOWR(BTRFS_IOCTL_MAGIC, 18, \
562 struct btrfs_ioctl_ino_lookup_args) 572 struct btrfs_ioctl_ino_lookup_args)
563#define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, __u64) 573#define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, __u64)