diff options
-rw-r--r-- | fs/btrfs/extent_io.c | 39 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 3 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 147 | ||||
-rw-r--r-- | fs/btrfs/qgroup.c | 4 | ||||
-rw-r--r-- | fs/btrfs/reada.c | 9 | ||||
-rw-r--r-- | fs/btrfs/tests/btrfs-tests.c | 2 | ||||
-rw-r--r-- | fs/btrfs/tests/qgroup-tests.c | 2 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 12 | ||||
-rw-r--r-- | include/uapi/linux/btrfs.h | 10 |
9 files changed, 192 insertions, 36 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index f25a9092b946..a389820d158b 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -2354,7 +2354,7 @@ int end_extent_writepage(struct page *page, int err, u64 start, u64 end) | |||
2354 | { | 2354 | { |
2355 | int uptodate = (err == 0); | 2355 | int uptodate = (err == 0); |
2356 | struct extent_io_tree *tree; | 2356 | struct extent_io_tree *tree; |
2357 | int ret; | 2357 | int ret = 0; |
2358 | 2358 | ||
2359 | tree = &BTRFS_I(page->mapping->host)->io_tree; | 2359 | tree = &BTRFS_I(page->mapping->host)->io_tree; |
2360 | 2360 | ||
@@ -5068,6 +5068,43 @@ void read_extent_buffer(struct extent_buffer *eb, void *dstv, | |||
5068 | } | 5068 | } |
5069 | } | 5069 | } |
5070 | 5070 | ||
5071 | int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dstv, | ||
5072 | unsigned long start, | ||
5073 | unsigned long len) | ||
5074 | { | ||
5075 | size_t cur; | ||
5076 | size_t offset; | ||
5077 | struct page *page; | ||
5078 | char *kaddr; | ||
5079 | char __user *dst = (char __user *)dstv; | ||
5080 | size_t start_offset = eb->start & ((u64)PAGE_CACHE_SIZE - 1); | ||
5081 | unsigned long i = (start_offset + start) >> PAGE_CACHE_SHIFT; | ||
5082 | int ret = 0; | ||
5083 | |||
5084 | WARN_ON(start > eb->len); | ||
5085 | WARN_ON(start + len > eb->start + eb->len); | ||
5086 | |||
5087 | offset = (start_offset + start) & (PAGE_CACHE_SIZE - 1); | ||
5088 | |||
5089 | while (len > 0) { | ||
5090 | page = extent_buffer_page(eb, i); | ||
5091 | |||
5092 | cur = min(len, (PAGE_CACHE_SIZE - offset)); | ||
5093 | kaddr = page_address(page); | ||
5094 | if (copy_to_user(dst, kaddr + offset, cur)) { | ||
5095 | ret = -EFAULT; | ||
5096 | break; | ||
5097 | } | ||
5098 | |||
5099 | dst += cur; | ||
5100 | len -= cur; | ||
5101 | offset = 0; | ||
5102 | i++; | ||
5103 | } | ||
5104 | |||
5105 | return ret; | ||
5106 | } | ||
5107 | |||
5071 | int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, | 5108 | int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, |
5072 | unsigned long min_len, char **map, | 5109 | unsigned long min_len, char **map, |
5073 | unsigned long *map_start, | 5110 | unsigned long *map_start, |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 8b63f2d46518..15ce5f2a2b62 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
@@ -304,6 +304,9 @@ int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv, | |||
304 | void read_extent_buffer(struct extent_buffer *eb, void *dst, | 304 | void read_extent_buffer(struct extent_buffer *eb, void *dst, |
305 | unsigned long start, | 305 | unsigned long start, |
306 | unsigned long len); | 306 | unsigned long len); |
307 | int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dst, | ||
308 | unsigned long start, | ||
309 | unsigned long len); | ||
307 | void write_extent_buffer(struct extent_buffer *eb, const void *src, | 310 | void write_extent_buffer(struct extent_buffer *eb, const void *src, |
308 | unsigned long start, unsigned long len); | 311 | unsigned long start, unsigned long len); |
309 | void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src, | 312 | void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src, |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 82c18ba12e3f..0d321c23069a 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -1957,7 +1957,8 @@ static noinline int copy_to_sk(struct btrfs_root *root, | |||
1957 | struct btrfs_path *path, | 1957 | struct btrfs_path *path, |
1958 | struct btrfs_key *key, | 1958 | struct btrfs_key *key, |
1959 | struct btrfs_ioctl_search_key *sk, | 1959 | struct btrfs_ioctl_search_key *sk, |
1960 | char *buf, | 1960 | size_t *buf_size, |
1961 | char __user *ubuf, | ||
1961 | unsigned long *sk_offset, | 1962 | unsigned long *sk_offset, |
1962 | int *num_found) | 1963 | int *num_found) |
1963 | { | 1964 | { |
@@ -1989,13 +1990,25 @@ static noinline int copy_to_sk(struct btrfs_root *root, | |||
1989 | if (!key_in_sk(key, sk)) | 1990 | if (!key_in_sk(key, sk)) |
1990 | continue; | 1991 | continue; |
1991 | 1992 | ||
1992 | if (sizeof(sh) + item_len > BTRFS_SEARCH_ARGS_BUFSIZE) | 1993 | if (sizeof(sh) + item_len > *buf_size) { |
1994 | if (*num_found) { | ||
1995 | ret = 1; | ||
1996 | goto out; | ||
1997 | } | ||
1998 | |||
1999 | /* | ||
2000 | * return one empty item back for v1, which does not | ||
2001 | * handle -EOVERFLOW | ||
2002 | */ | ||
2003 | |||
2004 | *buf_size = sizeof(sh) + item_len; | ||
1993 | item_len = 0; | 2005 | item_len = 0; |
2006 | ret = -EOVERFLOW; | ||
2007 | } | ||
1994 | 2008 | ||
1995 | if (sizeof(sh) + item_len + *sk_offset > | 2009 | if (sizeof(sh) + item_len + *sk_offset > *buf_size) { |
1996 | BTRFS_SEARCH_ARGS_BUFSIZE) { | ||
1997 | ret = 1; | 2010 | ret = 1; |
1998 | goto overflow; | 2011 | goto out; |
1999 | } | 2012 | } |
2000 | 2013 | ||
2001 | sh.objectid = key->objectid; | 2014 | sh.objectid = key->objectid; |
@@ -2005,20 +2018,33 @@ static noinline int copy_to_sk(struct btrfs_root *root, | |||
2005 | sh.transid = found_transid; | 2018 | sh.transid = found_transid; |
2006 | 2019 | ||
2007 | /* copy search result header */ | 2020 | /* copy search result header */ |
2008 | memcpy(buf + *sk_offset, &sh, sizeof(sh)); | 2021 | if (copy_to_user(ubuf + *sk_offset, &sh, sizeof(sh))) { |
2022 | ret = -EFAULT; | ||
2023 | goto out; | ||
2024 | } | ||
2025 | |||
2009 | *sk_offset += sizeof(sh); | 2026 | *sk_offset += sizeof(sh); |
2010 | 2027 | ||
2011 | if (item_len) { | 2028 | if (item_len) { |
2012 | char *p = buf + *sk_offset; | 2029 | char __user *up = ubuf + *sk_offset; |
2013 | /* copy the item */ | 2030 | /* copy the item */ |
2014 | read_extent_buffer(leaf, p, | 2031 | if (read_extent_buffer_to_user(leaf, up, |
2015 | item_off, item_len); | 2032 | item_off, item_len)) { |
2033 | ret = -EFAULT; | ||
2034 | goto out; | ||
2035 | } | ||
2036 | |||
2016 | *sk_offset += item_len; | 2037 | *sk_offset += item_len; |
2017 | } | 2038 | } |
2018 | (*num_found)++; | 2039 | (*num_found)++; |
2019 | 2040 | ||
2020 | if (*num_found >= sk->nr_items) | 2041 | if (ret) /* -EOVERFLOW from above */ |
2021 | break; | 2042 | goto out; |
2043 | |||
2044 | if (*num_found >= sk->nr_items) { | ||
2045 | ret = 1; | ||
2046 | goto out; | ||
2047 | } | ||
2022 | } | 2048 | } |
2023 | advance_key: | 2049 | advance_key: |
2024 | ret = 0; | 2050 | ret = 0; |
@@ -2033,22 +2059,37 @@ advance_key: | |||
2033 | key->objectid++; | 2059 | key->objectid++; |
2034 | } else | 2060 | } else |
2035 | ret = 1; | 2061 | ret = 1; |
2036 | overflow: | 2062 | out: |
2063 | /* | ||
2064 | * 0: all items from this leaf copied, continue with next | ||
2065 | * 1: * more items can be copied, but unused buffer is too small | ||
2066 | * * all items were found | ||
2067 | * Either way, it will stops the loop which iterates to the next | ||
2068 | * leaf | ||
2069 | * -EOVERFLOW: item was to large for buffer | ||
2070 | * -EFAULT: could not copy extent buffer back to userspace | ||
2071 | */ | ||
2037 | return ret; | 2072 | return ret; |
2038 | } | 2073 | } |
2039 | 2074 | ||
2040 | static noinline int search_ioctl(struct inode *inode, | 2075 | static noinline int search_ioctl(struct inode *inode, |
2041 | struct btrfs_ioctl_search_args *args) | 2076 | struct btrfs_ioctl_search_key *sk, |
2077 | size_t *buf_size, | ||
2078 | char __user *ubuf) | ||
2042 | { | 2079 | { |
2043 | struct btrfs_root *root; | 2080 | struct btrfs_root *root; |
2044 | struct btrfs_key key; | 2081 | struct btrfs_key key; |
2045 | struct btrfs_path *path; | 2082 | struct btrfs_path *path; |
2046 | struct btrfs_ioctl_search_key *sk = &args->key; | ||
2047 | struct btrfs_fs_info *info = BTRFS_I(inode)->root->fs_info; | 2083 | struct btrfs_fs_info *info = BTRFS_I(inode)->root->fs_info; |
2048 | int ret; | 2084 | int ret; |
2049 | int num_found = 0; | 2085 | int num_found = 0; |
2050 | unsigned long sk_offset = 0; | 2086 | unsigned long sk_offset = 0; |
2051 | 2087 | ||
2088 | if (*buf_size < sizeof(struct btrfs_ioctl_search_header)) { | ||
2089 | *buf_size = sizeof(struct btrfs_ioctl_search_header); | ||
2090 | return -EOVERFLOW; | ||
2091 | } | ||
2092 | |||
2052 | path = btrfs_alloc_path(); | 2093 | path = btrfs_alloc_path(); |
2053 | if (!path) | 2094 | if (!path) |
2054 | return -ENOMEM; | 2095 | return -ENOMEM; |
@@ -2082,14 +2123,15 @@ static noinline int search_ioctl(struct inode *inode, | |||
2082 | ret = 0; | 2123 | ret = 0; |
2083 | goto err; | 2124 | goto err; |
2084 | } | 2125 | } |
2085 | ret = copy_to_sk(root, path, &key, sk, args->buf, | 2126 | ret = copy_to_sk(root, path, &key, sk, buf_size, ubuf, |
2086 | &sk_offset, &num_found); | 2127 | &sk_offset, &num_found); |
2087 | btrfs_release_path(path); | 2128 | btrfs_release_path(path); |
2088 | if (ret || num_found >= sk->nr_items) | 2129 | if (ret) |
2089 | break; | 2130 | break; |
2090 | 2131 | ||
2091 | } | 2132 | } |
2092 | ret = 0; | 2133 | if (ret > 0) |
2134 | ret = 0; | ||
2093 | err: | 2135 | err: |
2094 | sk->nr_items = num_found; | 2136 | sk->nr_items = num_found; |
2095 | btrfs_free_path(path); | 2137 | btrfs_free_path(path); |
@@ -2099,22 +2141,73 @@ err: | |||
2099 | static noinline int btrfs_ioctl_tree_search(struct file *file, | 2141 | static noinline int btrfs_ioctl_tree_search(struct file *file, |
2100 | void __user *argp) | 2142 | void __user *argp) |
2101 | { | 2143 | { |
2102 | struct btrfs_ioctl_search_args *args; | 2144 | struct btrfs_ioctl_search_args __user *uargs; |
2103 | struct inode *inode; | 2145 | struct btrfs_ioctl_search_key sk; |
2104 | int ret; | 2146 | struct inode *inode; |
2147 | int ret; | ||
2148 | size_t buf_size; | ||
2105 | 2149 | ||
2106 | if (!capable(CAP_SYS_ADMIN)) | 2150 | if (!capable(CAP_SYS_ADMIN)) |
2107 | return -EPERM; | 2151 | return -EPERM; |
2108 | 2152 | ||
2109 | args = memdup_user(argp, sizeof(*args)); | 2153 | uargs = (struct btrfs_ioctl_search_args __user *)argp; |
2110 | if (IS_ERR(args)) | 2154 | |
2111 | return PTR_ERR(args); | 2155 | if (copy_from_user(&sk, &uargs->key, sizeof(sk))) |
2156 | return -EFAULT; | ||
2157 | |||
2158 | buf_size = sizeof(uargs->buf); | ||
2112 | 2159 | ||
2113 | inode = file_inode(file); | 2160 | inode = file_inode(file); |
2114 | ret = search_ioctl(inode, args); | 2161 | ret = search_ioctl(inode, &sk, &buf_size, uargs->buf); |
2115 | if (ret == 0 && copy_to_user(argp, args, sizeof(*args))) | 2162 | |
2163 | /* | ||
2164 | * In the origin implementation an overflow is handled by returning a | ||
2165 | * search header with a len of zero, so reset ret. | ||
2166 | */ | ||
2167 | if (ret == -EOVERFLOW) | ||
2168 | ret = 0; | ||
2169 | |||
2170 | if (ret == 0 && copy_to_user(&uargs->key, &sk, sizeof(sk))) | ||
2116 | ret = -EFAULT; | 2171 | ret = -EFAULT; |
2117 | kfree(args); | 2172 | return ret; |
2173 | } | ||
2174 | |||
2175 | static 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 | |||
2118 | return ret; | 2211 | return ret; |
2119 | } | 2212 | } |
2120 | 2213 | ||
@@ -5198,6 +5291,8 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
5198 | return btrfs_ioctl_trans_end(file); | 5291 | return btrfs_ioctl_trans_end(file); |
5199 | case BTRFS_IOC_TREE_SEARCH: | 5292 | case BTRFS_IOC_TREE_SEARCH: |
5200 | 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); | ||
5201 | case BTRFS_IOC_INO_LOOKUP: | 5296 | case BTRFS_IOC_INO_LOOKUP: |
5202 | return btrfs_ioctl_ino_lookup(file, argp); | 5297 | return btrfs_ioctl_ino_lookup(file, argp); |
5203 | case BTRFS_IOC_INO_PATHS: | 5298 | case BTRFS_IOC_INO_PATHS: |
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index cf5aead95a7f..98cb6b2630f9 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c | |||
@@ -1798,8 +1798,10 @@ static int qgroup_shared_accounting(struct btrfs_trans_handle *trans, | |||
1798 | return -ENOMEM; | 1798 | return -ENOMEM; |
1799 | 1799 | ||
1800 | tmp = ulist_alloc(GFP_NOFS); | 1800 | tmp = ulist_alloc(GFP_NOFS); |
1801 | if (!tmp) | 1801 | if (!tmp) { |
1802 | ulist_free(qgroups); | ||
1802 | return -ENOMEM; | 1803 | return -ENOMEM; |
1804 | } | ||
1803 | 1805 | ||
1804 | btrfs_get_tree_mod_seq(fs_info, &elem); | 1806 | btrfs_get_tree_mod_seq(fs_info, &elem); |
1805 | ret = btrfs_find_all_roots(trans, fs_info, oper->bytenr, elem.seq, | 1807 | ret = btrfs_find_all_roots(trans, fs_info, oper->bytenr, elem.seq, |
diff --git a/fs/btrfs/reada.c b/fs/btrfs/reada.c index 30947f923620..09230cf3a244 100644 --- a/fs/btrfs/reada.c +++ b/fs/btrfs/reada.c | |||
@@ -428,8 +428,13 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root, | |||
428 | continue; | 428 | continue; |
429 | } | 429 | } |
430 | if (!dev->bdev) { | 430 | if (!dev->bdev) { |
431 | /* cannot read ahead on missing device */ | 431 | /* |
432 | continue; | 432 | * cannot read ahead on missing device, but for RAID5/6, |
433 | * REQ_GET_READ_MIRRORS return 1. So don't skip missing | ||
434 | * device for such case. | ||
435 | */ | ||
436 | if (nzones > 1) | ||
437 | continue; | ||
433 | } | 438 | } |
434 | if (dev_replace_is_ongoing && | 439 | if (dev_replace_is_ongoing && |
435 | dev == fs_info->dev_replace.tgtdev) { | 440 | dev == fs_info->dev_replace.tgtdev) { |
diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c index a5dcacb5df9c..9626252ee6b4 100644 --- a/fs/btrfs/tests/btrfs-tests.c +++ b/fs/btrfs/tests/btrfs-tests.c | |||
@@ -135,7 +135,7 @@ restart: | |||
135 | radix_tree_for_each_slot(slot, &fs_info->buffer_radix, &iter, 0) { | 135 | radix_tree_for_each_slot(slot, &fs_info->buffer_radix, &iter, 0) { |
136 | struct extent_buffer *eb; | 136 | struct extent_buffer *eb; |
137 | 137 | ||
138 | eb = radix_tree_deref_slot(slot); | 138 | eb = radix_tree_deref_slot_protected(slot, &fs_info->buffer_lock); |
139 | if (!eb) | 139 | if (!eb) |
140 | continue; | 140 | continue; |
141 | /* Shouldn't happen but that kind of thinking creates CVE's */ | 141 | /* Shouldn't happen but that kind of thinking creates CVE's */ |
diff --git a/fs/btrfs/tests/qgroup-tests.c b/fs/btrfs/tests/qgroup-tests.c index fa691b754aaf..ec3dcb202357 100644 --- a/fs/btrfs/tests/qgroup-tests.c +++ b/fs/btrfs/tests/qgroup-tests.c | |||
@@ -415,6 +415,8 @@ int btrfs_test_qgroups(void) | |||
415 | ret = -ENOMEM; | 415 | ret = -ENOMEM; |
416 | goto out; | 416 | goto out; |
417 | } | 417 | } |
418 | btrfs_set_header_level(root->node, 0); | ||
419 | btrfs_set_header_nritems(root->node, 0); | ||
418 | root->alloc_bytenr += 8192; | 420 | root->alloc_bytenr += 8192; |
419 | 421 | ||
420 | tmp_root = btrfs_alloc_dummy_root(); | 422 | tmp_root = btrfs_alloc_dummy_root(); |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 9630f10f8e1e..511839c04f11 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -1284,11 +1284,13 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
1284 | goto fail; | 1284 | goto fail; |
1285 | } | 1285 | } |
1286 | 1286 | ||
1287 | pending->error = btrfs_qgroup_inherit(trans, fs_info, | 1287 | ret = btrfs_qgroup_inherit(trans, fs_info, |
1288 | root->root_key.objectid, | 1288 | root->root_key.objectid, |
1289 | objectid, pending->inherit); | 1289 | objectid, pending->inherit); |
1290 | if (pending->error) | 1290 | if (ret) { |
1291 | goto no_free_objectid; | 1291 | btrfs_abort_transaction(trans, root, ret); |
1292 | goto fail; | ||
1293 | } | ||
1292 | 1294 | ||
1293 | /* see comments in should_cow_block() */ | 1295 | /* see comments in should_cow_block() */ |
1294 | set_bit(BTRFS_ROOT_FORCE_COW, &root->state); | 1296 | set_bit(BTRFS_ROOT_FORCE_COW, &root->state); |
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 | ||
309 | struct 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 | |||
309 | struct btrfs_ioctl_clone_range_args { | 317 | struct 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) |