aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerhard Heift <gerhard@heift.name>2014-01-30 10:24:03 -0500
committerChris Mason <clm@fb.com>2014-06-13 12:52:19 -0400
commitcc68a8a5a4330a4bb72922d0c7a7044ae13ee692 (patch)
tree8b5b09704b99bb0956836c8d45b6228cfcc2bfee
parentba346b357d70becdd8e20ff9493cd56101ee0f46 (diff)
btrfs: new ioctl TREE_SEARCH_V2
This new ioctl call allows the user to supply a buffer of varying size in which a tree search can store its results. This is much more flexible if you want to receive items which are larger than the current fixed buffer of 3992 bytes or if you want to fetch more items at once. Items larger than this buffer are for example some of the type EXTENT_CSUM. Signed-off-by: Gerhard Heift <Gerhard@Heift.Name> Signed-off-by: Chris Mason <clm@fb.com> Acked-by: David Sterba <dsterba@suse.cz>
-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)