aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-30 23:08:20 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-30 23:08:20 -0500
commite7651b819e90da924991d727d3c007200a18670d (patch)
treee7a943b5bb56c384972944fd86767a3f079b8a98 /fs/btrfs/ioctl.c
parent060e8e3b6f8fc0ba97de2276249fbd80fa25b0a2 (diff)
parentcf93da7bcf450cb4595055d491a0519cb39e68ed (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs updates from Chris Mason: "This is a pretty big pull, and most of these changes have been floating in btrfs-next for a long time. Filipe's properties work is a cool building block for inheriting attributes like compression down on a per inode basis. Jeff Mahoney kicked in code to export filesystem info into sysfs. Otherwise, lots of performance improvements, cleanups and bug fixes. Looks like there are still a few other small pending incrementals, but I wanted to get the bulk of this in first" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (149 commits) Btrfs: fix spin_unlock in check_ref_cleanup Btrfs: setup inode location during btrfs_init_inode_locked Btrfs: don't use ram_bytes for uncompressed inline items Btrfs: fix btrfs_search_slot_for_read backwards iteration Btrfs: do not export ulist functions Btrfs: rework ulist with list+rb_tree Btrfs: fix memory leaks on walking backrefs failure Btrfs: fix send file hole detection leading to data corruption Btrfs: add a reschedule point in btrfs_find_all_roots() Btrfs: make send's file extent item search more efficient Btrfs: fix to catch all errors when resolving indirect ref Btrfs: fix protection between walking backrefs and root deletion btrfs: fix warning while merging two adjacent extents Btrfs: fix infinite path build loops in incremental send btrfs: undo sysfs when open_ctree() fails Btrfs: fix snprintf usage by send's gen_unique_name btrfs: fix defrag 32-bit integer overflow btrfs: sysfs: list the NO_HOLES feature btrfs: sysfs: don't show reserved incompat feature btrfs: call permission checks earlier in ioctls and return EPERM ...
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c348
1 files changed, 295 insertions, 53 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index ad27dcea319c..b0134892dc70 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -56,6 +56,8 @@
56#include "rcu-string.h" 56#include "rcu-string.h"
57#include "send.h" 57#include "send.h"
58#include "dev-replace.h" 58#include "dev-replace.h"
59#include "props.h"
60#include "sysfs.h"
59 61
60static int btrfs_clone(struct inode *src, struct inode *inode, 62static int btrfs_clone(struct inode *src, struct inode *inode,
61 u64 off, u64 olen, u64 olen_aligned, u64 destoff); 63 u64 off, u64 olen, u64 olen_aligned, u64 destoff);
@@ -190,6 +192,9 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
190 unsigned int i_oldflags; 192 unsigned int i_oldflags;
191 umode_t mode; 193 umode_t mode;
192 194
195 if (!inode_owner_or_capable(inode))
196 return -EPERM;
197
193 if (btrfs_root_readonly(root)) 198 if (btrfs_root_readonly(root))
194 return -EROFS; 199 return -EROFS;
195 200
@@ -200,9 +205,6 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
200 if (ret) 205 if (ret)
201 return ret; 206 return ret;
202 207
203 if (!inode_owner_or_capable(inode))
204 return -EACCES;
205
206 ret = mnt_want_write_file(file); 208 ret = mnt_want_write_file(file);
207 if (ret) 209 if (ret)
208 return ret; 210 return ret;
@@ -280,9 +282,25 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
280 if (flags & FS_NOCOMP_FL) { 282 if (flags & FS_NOCOMP_FL) {
281 ip->flags &= ~BTRFS_INODE_COMPRESS; 283 ip->flags &= ~BTRFS_INODE_COMPRESS;
282 ip->flags |= BTRFS_INODE_NOCOMPRESS; 284 ip->flags |= BTRFS_INODE_NOCOMPRESS;
285
286 ret = btrfs_set_prop(inode, "btrfs.compression", NULL, 0, 0);
287 if (ret && ret != -ENODATA)
288 goto out_drop;
283 } else if (flags & FS_COMPR_FL) { 289 } else if (flags & FS_COMPR_FL) {
290 const char *comp;
291
284 ip->flags |= BTRFS_INODE_COMPRESS; 292 ip->flags |= BTRFS_INODE_COMPRESS;
285 ip->flags &= ~BTRFS_INODE_NOCOMPRESS; 293 ip->flags &= ~BTRFS_INODE_NOCOMPRESS;
294
295 if (root->fs_info->compress_type == BTRFS_COMPRESS_LZO)
296 comp = "lzo";
297 else
298 comp = "zlib";
299 ret = btrfs_set_prop(inode, "btrfs.compression",
300 comp, strlen(comp), 0);
301 if (ret)
302 goto out_drop;
303
286 } else { 304 } else {
287 ip->flags &= ~(BTRFS_INODE_COMPRESS | BTRFS_INODE_NOCOMPRESS); 305 ip->flags &= ~(BTRFS_INODE_COMPRESS | BTRFS_INODE_NOCOMPRESS);
288 } 306 }
@@ -392,6 +410,7 @@ static noinline int create_subvol(struct inode *dir,
392 struct btrfs_root *new_root; 410 struct btrfs_root *new_root;
393 struct btrfs_block_rsv block_rsv; 411 struct btrfs_block_rsv block_rsv;
394 struct timespec cur_time = CURRENT_TIME; 412 struct timespec cur_time = CURRENT_TIME;
413 struct inode *inode;
395 int ret; 414 int ret;
396 int err; 415 int err;
397 u64 objectid; 416 u64 objectid;
@@ -417,7 +436,9 @@ static noinline int create_subvol(struct inode *dir,
417 trans = btrfs_start_transaction(root, 0); 436 trans = btrfs_start_transaction(root, 0);
418 if (IS_ERR(trans)) { 437 if (IS_ERR(trans)) {
419 ret = PTR_ERR(trans); 438 ret = PTR_ERR(trans);
420 goto out; 439 btrfs_subvolume_release_metadata(root, &block_rsv,
440 qgroup_reserved);
441 return ret;
421 } 442 }
422 trans->block_rsv = &block_rsv; 443 trans->block_rsv = &block_rsv;
423 trans->bytes_reserved = block_rsv.size; 444 trans->bytes_reserved = block_rsv.size;
@@ -500,7 +521,7 @@ static noinline int create_subvol(struct inode *dir,
500 521
501 btrfs_record_root_in_trans(trans, new_root); 522 btrfs_record_root_in_trans(trans, new_root);
502 523
503 ret = btrfs_create_subvol_root(trans, new_root, new_dirid); 524 ret = btrfs_create_subvol_root(trans, new_root, root, new_dirid);
504 if (ret) { 525 if (ret) {
505 /* We potentially lose an unused inode item here */ 526 /* We potentially lose an unused inode item here */
506 btrfs_abort_transaction(trans, root, ret); 527 btrfs_abort_transaction(trans, root, ret);
@@ -542,6 +563,8 @@ static noinline int create_subvol(struct inode *dir,
542fail: 563fail:
543 trans->block_rsv = NULL; 564 trans->block_rsv = NULL;
544 trans->bytes_reserved = 0; 565 trans->bytes_reserved = 0;
566 btrfs_subvolume_release_metadata(root, &block_rsv, qgroup_reserved);
567
545 if (async_transid) { 568 if (async_transid) {
546 *async_transid = trans->transid; 569 *async_transid = trans->transid;
547 err = btrfs_commit_transaction_async(trans, root, 1); 570 err = btrfs_commit_transaction_async(trans, root, 1);
@@ -553,10 +576,12 @@ fail:
553 if (err && !ret) 576 if (err && !ret)
554 ret = err; 577 ret = err;
555 578
556 if (!ret) 579 if (!ret) {
557 d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry)); 580 inode = btrfs_lookup_dentry(dir, dentry);
558out: 581 if (IS_ERR(inode))
559 btrfs_subvolume_release_metadata(root, &block_rsv, qgroup_reserved); 582 return PTR_ERR(inode);
583 d_instantiate(dentry, inode);
584 }
560 return ret; 585 return ret;
561} 586}
562 587
@@ -642,7 +667,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
642 ret = PTR_ERR(inode); 667 ret = PTR_ERR(inode);
643 goto fail; 668 goto fail;
644 } 669 }
645 BUG_ON(!inode); 670
646 d_instantiate(dentry, inode); 671 d_instantiate(dentry, inode);
647 ret = 0; 672 ret = 0;
648fail: 673fail:
@@ -1011,7 +1036,7 @@ out:
1011static int cluster_pages_for_defrag(struct inode *inode, 1036static int cluster_pages_for_defrag(struct inode *inode,
1012 struct page **pages, 1037 struct page **pages,
1013 unsigned long start_index, 1038 unsigned long start_index,
1014 int num_pages) 1039 unsigned long num_pages)
1015{ 1040{
1016 unsigned long file_end; 1041 unsigned long file_end;
1017 u64 isize = i_size_read(inode); 1042 u64 isize = i_size_read(inode);
@@ -1169,8 +1194,8 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
1169 int defrag_count = 0; 1194 int defrag_count = 0;
1170 int compress_type = BTRFS_COMPRESS_ZLIB; 1195 int compress_type = BTRFS_COMPRESS_ZLIB;
1171 int extent_thresh = range->extent_thresh; 1196 int extent_thresh = range->extent_thresh;
1172 int max_cluster = (256 * 1024) >> PAGE_CACHE_SHIFT; 1197 unsigned long max_cluster = (256 * 1024) >> PAGE_CACHE_SHIFT;
1173 int cluster = max_cluster; 1198 unsigned long cluster = max_cluster;
1174 u64 new_align = ~((u64)128 * 1024 - 1); 1199 u64 new_align = ~((u64)128 * 1024 - 1);
1175 struct page **pages = NULL; 1200 struct page **pages = NULL;
1176 1201
@@ -1254,7 +1279,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
1254 break; 1279 break;
1255 1280
1256 if (btrfs_defrag_cancelled(root->fs_info)) { 1281 if (btrfs_defrag_cancelled(root->fs_info)) {
1257 printk(KERN_DEBUG "btrfs: defrag_file cancelled\n"); 1282 printk(KERN_DEBUG "BTRFS: defrag_file cancelled\n");
1258 ret = -EAGAIN; 1283 ret = -EAGAIN;
1259 break; 1284 break;
1260 } 1285 }
@@ -1416,20 +1441,20 @@ static noinline int btrfs_ioctl_resize(struct file *file,
1416 ret = -EINVAL; 1441 ret = -EINVAL;
1417 goto out_free; 1442 goto out_free;
1418 } 1443 }
1419 printk(KERN_INFO "btrfs: resizing devid %llu\n", devid); 1444 btrfs_info(root->fs_info, "resizing devid %llu", devid);
1420 } 1445 }
1421 1446
1422 device = btrfs_find_device(root->fs_info, devid, NULL, NULL); 1447 device = btrfs_find_device(root->fs_info, devid, NULL, NULL);
1423 if (!device) { 1448 if (!device) {
1424 printk(KERN_INFO "btrfs: resizer unable to find device %llu\n", 1449 btrfs_info(root->fs_info, "resizer unable to find device %llu",
1425 devid); 1450 devid);
1426 ret = -ENODEV; 1451 ret = -ENODEV;
1427 goto out_free; 1452 goto out_free;
1428 } 1453 }
1429 1454
1430 if (!device->writeable) { 1455 if (!device->writeable) {
1431 printk(KERN_INFO "btrfs: resizer unable to apply on " 1456 btrfs_info(root->fs_info,
1432 "readonly device %llu\n", 1457 "resizer unable to apply on readonly device %llu",
1433 devid); 1458 devid);
1434 ret = -EPERM; 1459 ret = -EPERM;
1435 goto out_free; 1460 goto out_free;
@@ -1466,6 +1491,10 @@ static noinline int btrfs_ioctl_resize(struct file *file,
1466 } 1491 }
1467 new_size = old_size - new_size; 1492 new_size = old_size - new_size;
1468 } else if (mod > 0) { 1493 } else if (mod > 0) {
1494 if (new_size > ULLONG_MAX - old_size) {
1495 ret = -EINVAL;
1496 goto out_free;
1497 }
1469 new_size = old_size + new_size; 1498 new_size = old_size + new_size;
1470 } 1499 }
1471 1500
@@ -1481,7 +1510,7 @@ static noinline int btrfs_ioctl_resize(struct file *file,
1481 do_div(new_size, root->sectorsize); 1510 do_div(new_size, root->sectorsize);
1482 new_size *= root->sectorsize; 1511 new_size *= root->sectorsize;
1483 1512
1484 printk_in_rcu(KERN_INFO "btrfs: new size for %s is %llu\n", 1513 printk_in_rcu(KERN_INFO "BTRFS: new size for %s is %llu\n",
1485 rcu_str_deref(device->name), new_size); 1514 rcu_str_deref(device->name), new_size);
1486 1515
1487 if (new_size > old_size) { 1516 if (new_size > old_size) {
@@ -1542,9 +1571,15 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
1542 1571
1543 src_inode = file_inode(src.file); 1572 src_inode = file_inode(src.file);
1544 if (src_inode->i_sb != file_inode(file)->i_sb) { 1573 if (src_inode->i_sb != file_inode(file)->i_sb) {
1545 printk(KERN_INFO "btrfs: Snapshot src from " 1574 btrfs_info(BTRFS_I(src_inode)->root->fs_info,
1546 "another FS\n"); 1575 "Snapshot src from another FS");
1547 ret = -EINVAL; 1576 ret = -EINVAL;
1577 } else if (!inode_owner_or_capable(src_inode)) {
1578 /*
1579 * Subvolume creation is not restricted, but snapshots
1580 * are limited to own subvolumes only
1581 */
1582 ret = -EPERM;
1548 } else { 1583 } else {
1549 ret = btrfs_mksubvol(&file->f_path, name, namelen, 1584 ret = btrfs_mksubvol(&file->f_path, name, namelen,
1550 BTRFS_I(src_inode)->root, 1585 BTRFS_I(src_inode)->root,
@@ -1662,6 +1697,9 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file,
1662 u64 flags; 1697 u64 flags;
1663 int ret = 0; 1698 int ret = 0;
1664 1699
1700 if (!inode_owner_or_capable(inode))
1701 return -EPERM;
1702
1665 ret = mnt_want_write_file(file); 1703 ret = mnt_want_write_file(file);
1666 if (ret) 1704 if (ret)
1667 goto out; 1705 goto out;
@@ -1686,11 +1724,6 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file,
1686 goto out_drop_write; 1724 goto out_drop_write;
1687 } 1725 }
1688 1726
1689 if (!inode_owner_or_capable(inode)) {
1690 ret = -EACCES;
1691 goto out_drop_write;
1692 }
1693
1694 down_write(&root->fs_info->subvol_sem); 1727 down_write(&root->fs_info->subvol_sem);
1695 1728
1696 /* nothing to do */ 1729 /* nothing to do */
@@ -1698,12 +1731,28 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file,
1698 goto out_drop_sem; 1731 goto out_drop_sem;
1699 1732
1700 root_flags = btrfs_root_flags(&root->root_item); 1733 root_flags = btrfs_root_flags(&root->root_item);
1701 if (flags & BTRFS_SUBVOL_RDONLY) 1734 if (flags & BTRFS_SUBVOL_RDONLY) {
1702 btrfs_set_root_flags(&root->root_item, 1735 btrfs_set_root_flags(&root->root_item,
1703 root_flags | BTRFS_ROOT_SUBVOL_RDONLY); 1736 root_flags | BTRFS_ROOT_SUBVOL_RDONLY);
1704 else 1737 } else {
1705 btrfs_set_root_flags(&root->root_item, 1738 /*
1739 * Block RO -> RW transition if this subvolume is involved in
1740 * send
1741 */
1742 spin_lock(&root->root_item_lock);
1743 if (root->send_in_progress == 0) {
1744 btrfs_set_root_flags(&root->root_item,
1706 root_flags & ~BTRFS_ROOT_SUBVOL_RDONLY); 1745 root_flags & ~BTRFS_ROOT_SUBVOL_RDONLY);
1746 spin_unlock(&root->root_item_lock);
1747 } else {
1748 spin_unlock(&root->root_item_lock);
1749 btrfs_warn(root->fs_info,
1750 "Attempt to set subvolume %llu read-write during send",
1751 root->root_key.objectid);
1752 ret = -EPERM;
1753 goto out_drop_sem;
1754 }
1755 }
1707 1756
1708 trans = btrfs_start_transaction(root, 1); 1757 trans = btrfs_start_transaction(root, 1);
1709 if (IS_ERR(trans)) { 1758 if (IS_ERR(trans)) {
@@ -1910,7 +1959,7 @@ static noinline int search_ioctl(struct inode *inode,
1910 key.offset = (u64)-1; 1959 key.offset = (u64)-1;
1911 root = btrfs_read_fs_root_no_name(info, &key); 1960 root = btrfs_read_fs_root_no_name(info, &key);
1912 if (IS_ERR(root)) { 1961 if (IS_ERR(root)) {
1913 printk(KERN_ERR "could not find root %llu\n", 1962 printk(KERN_ERR "BTRFS: could not find root %llu\n",
1914 sk->tree_id); 1963 sk->tree_id);
1915 btrfs_free_path(path); 1964 btrfs_free_path(path);
1916 return -ENOENT; 1965 return -ENOENT;
@@ -2000,7 +2049,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info,
2000 key.offset = (u64)-1; 2049 key.offset = (u64)-1;
2001 root = btrfs_read_fs_root_no_name(info, &key); 2050 root = btrfs_read_fs_root_no_name(info, &key);
2002 if (IS_ERR(root)) { 2051 if (IS_ERR(root)) {
2003 printk(KERN_ERR "could not find root %llu\n", tree_id); 2052 printk(KERN_ERR "BTRFS: could not find root %llu\n", tree_id);
2004 ret = -ENOENT; 2053 ret = -ENOENT;
2005 goto out; 2054 goto out;
2006 } 2055 }
@@ -2838,12 +2887,14 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
2838 * note the key will change type as we walk through the 2887 * note the key will change type as we walk through the
2839 * tree. 2888 * tree.
2840 */ 2889 */
2890 path->leave_spinning = 1;
2841 ret = btrfs_search_slot(NULL, BTRFS_I(src)->root, &key, path, 2891 ret = btrfs_search_slot(NULL, BTRFS_I(src)->root, &key, path,
2842 0, 0); 2892 0, 0);
2843 if (ret < 0) 2893 if (ret < 0)
2844 goto out; 2894 goto out;
2845 2895
2846 nritems = btrfs_header_nritems(path->nodes[0]); 2896 nritems = btrfs_header_nritems(path->nodes[0]);
2897process_slot:
2847 if (path->slots[0] >= nritems) { 2898 if (path->slots[0] >= nritems) {
2848 ret = btrfs_next_leaf(BTRFS_I(src)->root, path); 2899 ret = btrfs_next_leaf(BTRFS_I(src)->root, path);
2849 if (ret < 0) 2900 if (ret < 0)
@@ -2870,11 +2921,6 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
2870 u8 comp; 2921 u8 comp;
2871 u64 endoff; 2922 u64 endoff;
2872 2923
2873 size = btrfs_item_size_nr(leaf, slot);
2874 read_extent_buffer(leaf, buf,
2875 btrfs_item_ptr_offset(leaf, slot),
2876 size);
2877
2878 extent = btrfs_item_ptr(leaf, slot, 2924 extent = btrfs_item_ptr(leaf, slot,
2879 struct btrfs_file_extent_item); 2925 struct btrfs_file_extent_item);
2880 comp = btrfs_file_extent_compression(leaf, extent); 2926 comp = btrfs_file_extent_compression(leaf, extent);
@@ -2893,11 +2939,20 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
2893 datal = btrfs_file_extent_ram_bytes(leaf, 2939 datal = btrfs_file_extent_ram_bytes(leaf,
2894 extent); 2940 extent);
2895 } 2941 }
2896 btrfs_release_path(path);
2897 2942
2898 if (key.offset + datal <= off || 2943 if (key.offset + datal <= off ||
2899 key.offset >= off + len - 1) 2944 key.offset >= off + len - 1) {
2900 goto next; 2945 path->slots[0]++;
2946 goto process_slot;
2947 }
2948
2949 size = btrfs_item_size_nr(leaf, slot);
2950 read_extent_buffer(leaf, buf,
2951 btrfs_item_ptr_offset(leaf, slot),
2952 size);
2953
2954 btrfs_release_path(path);
2955 path->leave_spinning = 0;
2901 2956
2902 memcpy(&new_key, &key, sizeof(new_key)); 2957 memcpy(&new_key, &key, sizeof(new_key));
2903 new_key.objectid = btrfs_ino(inode); 2958 new_key.objectid = btrfs_ino(inode);
@@ -3068,7 +3123,6 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
3068 } 3123 }
3069 ret = btrfs_end_transaction(trans, root); 3124 ret = btrfs_end_transaction(trans, root);
3070 } 3125 }
3071next:
3072 btrfs_release_path(path); 3126 btrfs_release_path(path);
3073 key.offset++; 3127 key.offset++;
3074 } 3128 }
@@ -3196,9 +3250,17 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
3196 3250
3197 unlock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1); 3251 unlock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
3198out_unlock: 3252out_unlock:
3199 mutex_unlock(&src->i_mutex); 3253 if (!same_inode) {
3200 if (!same_inode) 3254 if (inode < src) {
3201 mutex_unlock(&inode->i_mutex); 3255 mutex_unlock(&src->i_mutex);
3256 mutex_unlock(&inode->i_mutex);
3257 } else {
3258 mutex_unlock(&inode->i_mutex);
3259 mutex_unlock(&src->i_mutex);
3260 }
3261 } else {
3262 mutex_unlock(&src->i_mutex);
3263 }
3202out_fput: 3264out_fput:
3203 fdput(src_file); 3265 fdput(src_file);
3204out_drop_write: 3266out_drop_write:
@@ -3321,8 +3383,8 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
3321 if (IS_ERR_OR_NULL(di)) { 3383 if (IS_ERR_OR_NULL(di)) {
3322 btrfs_free_path(path); 3384 btrfs_free_path(path);
3323 btrfs_end_transaction(trans, root); 3385 btrfs_end_transaction(trans, root);
3324 printk(KERN_ERR "Umm, you don't have the default dir item, " 3386 btrfs_err(new_root->fs_info, "Umm, you don't have the default dir"
3325 "this isn't going to work\n"); 3387 "item, this isn't going to work");
3326 ret = -ENOENT; 3388 ret = -ENOENT;
3327 goto out; 3389 goto out;
3328 } 3390 }
@@ -3475,6 +3537,20 @@ out:
3475 return ret; 3537 return ret;
3476} 3538}
3477 3539
3540static long btrfs_ioctl_global_rsv(struct btrfs_root *root, void __user *arg)
3541{
3542 struct btrfs_block_rsv *block_rsv = &root->fs_info->global_block_rsv;
3543 u64 reserved;
3544
3545 spin_lock(&block_rsv->lock);
3546 reserved = block_rsv->reserved;
3547 spin_unlock(&block_rsv->lock);
3548
3549 if (arg && copy_to_user(arg, &reserved, sizeof(reserved)))
3550 return -EFAULT;
3551 return 0;
3552}
3553
3478/* 3554/*
3479 * there are many ways the trans_start and trans_end ioctls can lead 3555 * there are many ways the trans_start and trans_end ioctls can lead
3480 * to deadlocks. They should only be used by applications that 3556 * to deadlocks. They should only be used by applications that
@@ -4303,6 +4379,9 @@ static long btrfs_ioctl_set_received_subvol(struct file *file,
4303 int ret = 0; 4379 int ret = 0;
4304 int received_uuid_changed; 4380 int received_uuid_changed;
4305 4381
4382 if (!inode_owner_or_capable(inode))
4383 return -EPERM;
4384
4306 ret = mnt_want_write_file(file); 4385 ret = mnt_want_write_file(file);
4307 if (ret < 0) 4386 if (ret < 0)
4308 return ret; 4387 return ret;
@@ -4319,11 +4398,6 @@ static long btrfs_ioctl_set_received_subvol(struct file *file,
4319 goto out; 4398 goto out;
4320 } 4399 }
4321 4400
4322 if (!inode_owner_or_capable(inode)) {
4323 ret = -EACCES;
4324 goto out;
4325 }
4326
4327 sa = memdup_user(arg, sizeof(*sa)); 4401 sa = memdup_user(arg, sizeof(*sa));
4328 if (IS_ERR(sa)) { 4402 if (IS_ERR(sa)) {
4329 ret = PTR_ERR(sa); 4403 ret = PTR_ERR(sa);
@@ -4409,8 +4483,8 @@ static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg)
4409 len = strnlen(label, BTRFS_LABEL_SIZE); 4483 len = strnlen(label, BTRFS_LABEL_SIZE);
4410 4484
4411 if (len == BTRFS_LABEL_SIZE) { 4485 if (len == BTRFS_LABEL_SIZE) {
4412 pr_warn("btrfs: label is too long, return the first %zu bytes\n", 4486 btrfs_warn(root->fs_info,
4413 --len); 4487 "label is too long, return the first %zu bytes", --len);
4414 } 4488 }
4415 4489
4416 ret = copy_to_user(arg, label, len); 4490 ret = copy_to_user(arg, label, len);
@@ -4433,7 +4507,7 @@ static int btrfs_ioctl_set_fslabel(struct file *file, void __user *arg)
4433 return -EFAULT; 4507 return -EFAULT;
4434 4508
4435 if (strnlen(label, BTRFS_LABEL_SIZE) == BTRFS_LABEL_SIZE) { 4509 if (strnlen(label, BTRFS_LABEL_SIZE) == BTRFS_LABEL_SIZE) {
4436 pr_err("btrfs: unable to set label with more than %d bytes\n", 4510 btrfs_err(root->fs_info, "unable to set label with more than %d bytes",
4437 BTRFS_LABEL_SIZE - 1); 4511 BTRFS_LABEL_SIZE - 1);
4438 return -EINVAL; 4512 return -EINVAL;
4439 } 4513 }
@@ -4458,6 +4532,166 @@ out_unlock:
4458 return ret; 4532 return ret;
4459} 4533}
4460 4534
4535#define INIT_FEATURE_FLAGS(suffix) \
4536 { .compat_flags = BTRFS_FEATURE_COMPAT_##suffix, \
4537 .compat_ro_flags = BTRFS_FEATURE_COMPAT_RO_##suffix, \
4538 .incompat_flags = BTRFS_FEATURE_INCOMPAT_##suffix }
4539
4540static int btrfs_ioctl_get_supported_features(struct file *file,
4541 void __user *arg)
4542{
4543 static struct btrfs_ioctl_feature_flags features[3] = {
4544 INIT_FEATURE_FLAGS(SUPP),
4545 INIT_FEATURE_FLAGS(SAFE_SET),
4546 INIT_FEATURE_FLAGS(SAFE_CLEAR)
4547 };
4548
4549 if (copy_to_user(arg, &features, sizeof(features)))
4550 return -EFAULT;
4551
4552 return 0;
4553}
4554
4555static int btrfs_ioctl_get_features(struct file *file, void __user *arg)
4556{
4557 struct btrfs_root *root = BTRFS_I(file_inode(file))->root;
4558 struct btrfs_super_block *super_block = root->fs_info->super_copy;
4559 struct btrfs_ioctl_feature_flags features;
4560
4561 features.compat_flags = btrfs_super_compat_flags(super_block);
4562 features.compat_ro_flags = btrfs_super_compat_ro_flags(super_block);
4563 features.incompat_flags = btrfs_super_incompat_flags(super_block);
4564
4565 if (copy_to_user(arg, &features, sizeof(features)))
4566 return -EFAULT;
4567
4568 return 0;
4569}
4570
4571static int check_feature_bits(struct btrfs_root *root,
4572 enum btrfs_feature_set set,
4573 u64 change_mask, u64 flags, u64 supported_flags,
4574 u64 safe_set, u64 safe_clear)
4575{
4576 const char *type = btrfs_feature_set_names[set];
4577 char *names;
4578 u64 disallowed, unsupported;
4579 u64 set_mask = flags & change_mask;
4580 u64 clear_mask = ~flags & change_mask;
4581
4582 unsupported = set_mask & ~supported_flags;
4583 if (unsupported) {
4584 names = btrfs_printable_features(set, unsupported);
4585 if (names) {
4586 btrfs_warn(root->fs_info,
4587 "this kernel does not support the %s feature bit%s",
4588 names, strchr(names, ',') ? "s" : "");
4589 kfree(names);
4590 } else
4591 btrfs_warn(root->fs_info,
4592 "this kernel does not support %s bits 0x%llx",
4593 type, unsupported);
4594 return -EOPNOTSUPP;
4595 }
4596
4597 disallowed = set_mask & ~safe_set;
4598 if (disallowed) {
4599 names = btrfs_printable_features(set, disallowed);
4600 if (names) {
4601 btrfs_warn(root->fs_info,
4602 "can't set the %s feature bit%s while mounted",
4603 names, strchr(names, ',') ? "s" : "");
4604 kfree(names);
4605 } else
4606 btrfs_warn(root->fs_info,
4607 "can't set %s bits 0x%llx while mounted",
4608 type, disallowed);
4609 return -EPERM;
4610 }
4611
4612 disallowed = clear_mask & ~safe_clear;
4613 if (disallowed) {
4614 names = btrfs_printable_features(set, disallowed);
4615 if (names) {
4616 btrfs_warn(root->fs_info,
4617 "can't clear the %s feature bit%s while mounted",
4618 names, strchr(names, ',') ? "s" : "");
4619 kfree(names);
4620 } else
4621 btrfs_warn(root->fs_info,
4622 "can't clear %s bits 0x%llx while mounted",
4623 type, disallowed);
4624 return -EPERM;
4625 }
4626
4627 return 0;
4628}
4629
4630#define check_feature(root, change_mask, flags, mask_base) \
4631check_feature_bits(root, FEAT_##mask_base, change_mask, flags, \
4632 BTRFS_FEATURE_ ## mask_base ## _SUPP, \
4633 BTRFS_FEATURE_ ## mask_base ## _SAFE_SET, \
4634 BTRFS_FEATURE_ ## mask_base ## _SAFE_CLEAR)
4635
4636static int btrfs_ioctl_set_features(struct file *file, void __user *arg)
4637{
4638 struct btrfs_root *root = BTRFS_I(file_inode(file))->root;
4639 struct btrfs_super_block *super_block = root->fs_info->super_copy;
4640 struct btrfs_ioctl_feature_flags flags[2];
4641 struct btrfs_trans_handle *trans;
4642 u64 newflags;
4643 int ret;
4644
4645 if (!capable(CAP_SYS_ADMIN))
4646 return -EPERM;
4647
4648 if (copy_from_user(flags, arg, sizeof(flags)))
4649 return -EFAULT;
4650
4651 /* Nothing to do */
4652 if (!flags[0].compat_flags && !flags[0].compat_ro_flags &&
4653 !flags[0].incompat_flags)
4654 return 0;
4655
4656 ret = check_feature(root, flags[0].compat_flags,
4657 flags[1].compat_flags, COMPAT);
4658 if (ret)
4659 return ret;
4660
4661 ret = check_feature(root, flags[0].compat_ro_flags,
4662 flags[1].compat_ro_flags, COMPAT_RO);
4663 if (ret)
4664 return ret;
4665
4666 ret = check_feature(root, flags[0].incompat_flags,
4667 flags[1].incompat_flags, INCOMPAT);
4668 if (ret)
4669 return ret;
4670
4671 trans = btrfs_start_transaction(root, 1);
4672 if (IS_ERR(trans))
4673 return PTR_ERR(trans);
4674
4675 spin_lock(&root->fs_info->super_lock);
4676 newflags = btrfs_super_compat_flags(super_block);
4677 newflags |= flags[0].compat_flags & flags[1].compat_flags;
4678 newflags &= ~(flags[0].compat_flags & ~flags[1].compat_flags);
4679 btrfs_set_super_compat_flags(super_block, newflags);
4680
4681 newflags = btrfs_super_compat_ro_flags(super_block);
4682 newflags |= flags[0].compat_ro_flags & flags[1].compat_ro_flags;
4683 newflags &= ~(flags[0].compat_ro_flags & ~flags[1].compat_ro_flags);
4684 btrfs_set_super_compat_ro_flags(super_block, newflags);
4685
4686 newflags = btrfs_super_incompat_flags(super_block);
4687 newflags |= flags[0].incompat_flags & flags[1].incompat_flags;
4688 newflags &= ~(flags[0].incompat_flags & ~flags[1].incompat_flags);
4689 btrfs_set_super_incompat_flags(super_block, newflags);
4690 spin_unlock(&root->fs_info->super_lock);
4691
4692 return btrfs_end_transaction(trans, root);
4693}
4694
4461long btrfs_ioctl(struct file *file, unsigned int 4695long btrfs_ioctl(struct file *file, unsigned int
4462 cmd, unsigned long arg) 4696 cmd, unsigned long arg)
4463{ 4697{
@@ -4523,6 +4757,8 @@ long btrfs_ioctl(struct file *file, unsigned int
4523 return btrfs_ioctl_logical_to_ino(root, argp); 4757 return btrfs_ioctl_logical_to_ino(root, argp);
4524 case BTRFS_IOC_SPACE_INFO: 4758 case BTRFS_IOC_SPACE_INFO:
4525 return btrfs_ioctl_space_info(root, argp); 4759 return btrfs_ioctl_space_info(root, argp);
4760 case BTRFS_IOC_GLOBAL_RSV:
4761 return btrfs_ioctl_global_rsv(root, argp);
4526 case BTRFS_IOC_SYNC: { 4762 case BTRFS_IOC_SYNC: {
4527 int ret; 4763 int ret;
4528 4764
@@ -4576,6 +4812,12 @@ long btrfs_ioctl(struct file *file, unsigned int
4576 return btrfs_ioctl_set_fslabel(file, argp); 4812 return btrfs_ioctl_set_fslabel(file, argp);
4577 case BTRFS_IOC_FILE_EXTENT_SAME: 4813 case BTRFS_IOC_FILE_EXTENT_SAME:
4578 return btrfs_ioctl_file_extent_same(file, argp); 4814 return btrfs_ioctl_file_extent_same(file, argp);
4815 case BTRFS_IOC_GET_SUPPORTED_FEATURES:
4816 return btrfs_ioctl_get_supported_features(file, argp);
4817 case BTRFS_IOC_GET_FEATURES:
4818 return btrfs_ioctl_get_features(file, argp);
4819 case BTRFS_IOC_SET_FEATURES:
4820 return btrfs_ioctl_set_features(file, argp);
4579 } 4821 }
4580 4822
4581 return -ENOTTY; 4823 return -ENOTTY;