aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/extent_io.c39
-rw-r--r--fs/btrfs/extent_io.h3
-rw-r--r--fs/btrfs/ioctl.c147
-rw-r--r--fs/btrfs/qgroup.c4
-rw-r--r--fs/btrfs/reada.c9
-rw-r--r--fs/btrfs/tests/btrfs-tests.c2
-rw-r--r--fs/btrfs/tests/qgroup-tests.c2
-rw-r--r--fs/btrfs/transaction.c12
-rw-r--r--include/uapi/linux/btrfs.h10
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
5071int 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
5071int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start, 5108int 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,
304void read_extent_buffer(struct extent_buffer *eb, void *dst, 304void 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);
307int read_extent_buffer_to_user(struct extent_buffer *eb, void __user *dst,
308 unsigned long start,
309 unsigned long len);
307void write_extent_buffer(struct extent_buffer *eb, const void *src, 310void write_extent_buffer(struct extent_buffer *eb, const void *src,
308 unsigned long start, unsigned long len); 311 unsigned long start, unsigned long len);
309void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src, 312void 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 }
2023advance_key: 2049advance_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;
2036overflow: 2062out:
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
2040static noinline int search_ioctl(struct inode *inode, 2075static 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;
2093err: 2135err:
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:
2099static noinline int btrfs_ioctl_tree_search(struct file *file, 2141static 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
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
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
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)