diff options
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 85 |
1 files changed, 39 insertions, 46 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 9d46f60cb943..a111622598b0 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <linux/uuid.h> | 44 | #include <linux/uuid.h> |
45 | #include <linux/btrfs.h> | 45 | #include <linux/btrfs.h> |
46 | #include <linux/uaccess.h> | 46 | #include <linux/uaccess.h> |
47 | #include "compat.h" | ||
48 | #include "ctree.h" | 47 | #include "ctree.h" |
49 | #include "disk-io.h" | 48 | #include "disk-io.h" |
50 | #include "transaction.h" | 49 | #include "transaction.h" |
@@ -321,7 +320,7 @@ static int btrfs_ioctl_getversion(struct file *file, int __user *arg) | |||
321 | 320 | ||
322 | static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) | 321 | static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) |
323 | { | 322 | { |
324 | struct btrfs_fs_info *fs_info = btrfs_sb(fdentry(file)->d_sb); | 323 | struct btrfs_fs_info *fs_info = btrfs_sb(file_inode(file)->i_sb); |
325 | struct btrfs_device *device; | 324 | struct btrfs_device *device; |
326 | struct request_queue *q; | 325 | struct request_queue *q; |
327 | struct fstrim_range range; | 326 | struct fstrim_range range; |
@@ -369,9 +368,13 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) | |||
369 | 368 | ||
370 | int btrfs_is_empty_uuid(u8 *uuid) | 369 | int btrfs_is_empty_uuid(u8 *uuid) |
371 | { | 370 | { |
372 | static char empty_uuid[BTRFS_UUID_SIZE] = {0}; | 371 | int i; |
373 | 372 | ||
374 | return !memcmp(uuid, empty_uuid, BTRFS_UUID_SIZE); | 373 | for (i = 0; i < BTRFS_UUID_SIZE; i++) { |
374 | if (uuid[i]) | ||
375 | return 0; | ||
376 | } | ||
377 | return 1; | ||
375 | } | 378 | } |
376 | 379 | ||
377 | static noinline int create_subvol(struct inode *dir, | 380 | static noinline int create_subvol(struct inode *dir, |
@@ -436,7 +439,7 @@ static noinline int create_subvol(struct inode *dir, | |||
436 | btrfs_set_header_backref_rev(leaf, BTRFS_MIXED_BACKREF_REV); | 439 | btrfs_set_header_backref_rev(leaf, BTRFS_MIXED_BACKREF_REV); |
437 | btrfs_set_header_owner(leaf, objectid); | 440 | btrfs_set_header_owner(leaf, objectid); |
438 | 441 | ||
439 | write_extent_buffer(leaf, root->fs_info->fsid, btrfs_header_fsid(leaf), | 442 | write_extent_buffer(leaf, root->fs_info->fsid, btrfs_header_fsid(), |
440 | BTRFS_FSID_SIZE); | 443 | BTRFS_FSID_SIZE); |
441 | write_extent_buffer(leaf, root->fs_info->chunk_tree_uuid, | 444 | write_extent_buffer(leaf, root->fs_info->chunk_tree_uuid, |
442 | btrfs_header_chunk_tree_uuid(leaf), | 445 | btrfs_header_chunk_tree_uuid(leaf), |
@@ -574,7 +577,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, | |||
574 | if (ret) | 577 | if (ret) |
575 | return ret; | 578 | return ret; |
576 | 579 | ||
577 | btrfs_wait_ordered_extents(root); | 580 | btrfs_wait_ordered_extents(root, -1); |
578 | 581 | ||
579 | pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); | 582 | pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); |
580 | if (!pending_snapshot) | 583 | if (!pending_snapshot) |
@@ -688,7 +691,7 @@ static inline int btrfs_check_sticky(struct inode *dir, struct inode *inode) | |||
688 | * nfs_async_unlink(). | 691 | * nfs_async_unlink(). |
689 | */ | 692 | */ |
690 | 693 | ||
691 | static int btrfs_may_delete(struct inode *dir,struct dentry *victim,int isdir) | 694 | static int btrfs_may_delete(struct inode *dir, struct dentry *victim, int isdir) |
692 | { | 695 | { |
693 | int error; | 696 | int error; |
694 | 697 | ||
@@ -842,7 +845,6 @@ static int find_new_extents(struct btrfs_root *root, | |||
842 | { | 845 | { |
843 | struct btrfs_path *path; | 846 | struct btrfs_path *path; |
844 | struct btrfs_key min_key; | 847 | struct btrfs_key min_key; |
845 | struct btrfs_key max_key; | ||
846 | struct extent_buffer *leaf; | 848 | struct extent_buffer *leaf; |
847 | struct btrfs_file_extent_item *extent; | 849 | struct btrfs_file_extent_item *extent; |
848 | int type; | 850 | int type; |
@@ -857,15 +859,10 @@ static int find_new_extents(struct btrfs_root *root, | |||
857 | min_key.type = BTRFS_EXTENT_DATA_KEY; | 859 | min_key.type = BTRFS_EXTENT_DATA_KEY; |
858 | min_key.offset = *off; | 860 | min_key.offset = *off; |
859 | 861 | ||
860 | max_key.objectid = ino; | ||
861 | max_key.type = (u8)-1; | ||
862 | max_key.offset = (u64)-1; | ||
863 | |||
864 | path->keep_locks = 1; | 862 | path->keep_locks = 1; |
865 | 863 | ||
866 | while(1) { | 864 | while (1) { |
867 | ret = btrfs_search_forward(root, &min_key, &max_key, | 865 | ret = btrfs_search_forward(root, &min_key, path, newer_than); |
868 | path, newer_than); | ||
869 | if (ret != 0) | 866 | if (ret != 0) |
870 | goto none; | 867 | goto none; |
871 | if (min_key.objectid != ino) | 868 | if (min_key.objectid != ino) |
@@ -1206,7 +1203,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, | |||
1206 | ra = &file->f_ra; | 1203 | ra = &file->f_ra; |
1207 | } | 1204 | } |
1208 | 1205 | ||
1209 | pages = kmalloc(sizeof(struct page *) * max_cluster, | 1206 | pages = kmalloc_array(max_cluster, sizeof(struct page *), |
1210 | GFP_NOFS); | 1207 | GFP_NOFS); |
1211 | if (!pages) { | 1208 | if (!pages) { |
1212 | ret = -ENOMEM; | 1209 | ret = -ENOMEM; |
@@ -1893,7 +1890,6 @@ static noinline int search_ioctl(struct inode *inode, | |||
1893 | { | 1890 | { |
1894 | struct btrfs_root *root; | 1891 | struct btrfs_root *root; |
1895 | struct btrfs_key key; | 1892 | struct btrfs_key key; |
1896 | struct btrfs_key max_key; | ||
1897 | struct btrfs_path *path; | 1893 | struct btrfs_path *path; |
1898 | struct btrfs_ioctl_search_key *sk = &args->key; | 1894 | struct btrfs_ioctl_search_key *sk = &args->key; |
1899 | struct btrfs_fs_info *info = BTRFS_I(inode)->root->fs_info; | 1895 | struct btrfs_fs_info *info = BTRFS_I(inode)->root->fs_info; |
@@ -1925,15 +1921,10 @@ static noinline int search_ioctl(struct inode *inode, | |||
1925 | key.type = sk->min_type; | 1921 | key.type = sk->min_type; |
1926 | key.offset = sk->min_offset; | 1922 | key.offset = sk->min_offset; |
1927 | 1923 | ||
1928 | max_key.objectid = sk->max_objectid; | ||
1929 | max_key.type = sk->max_type; | ||
1930 | max_key.offset = sk->max_offset; | ||
1931 | |||
1932 | path->keep_locks = 1; | 1924 | path->keep_locks = 1; |
1933 | 1925 | ||
1934 | while(1) { | 1926 | while (1) { |
1935 | ret = btrfs_search_forward(root, &key, &max_key, path, | 1927 | ret = btrfs_search_forward(root, &key, path, sk->min_transid); |
1936 | sk->min_transid); | ||
1937 | if (ret != 0) { | 1928 | if (ret != 0) { |
1938 | if (ret > 0) | 1929 | if (ret > 0) |
1939 | ret = 0; | 1930 | ret = 0; |
@@ -2018,7 +2009,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, | |||
2018 | key.type = BTRFS_INODE_REF_KEY; | 2009 | key.type = BTRFS_INODE_REF_KEY; |
2019 | key.offset = (u64)-1; | 2010 | key.offset = (u64)-1; |
2020 | 2011 | ||
2021 | while(1) { | 2012 | while (1) { |
2022 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 2013 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
2023 | if (ret < 0) | 2014 | if (ret < 0) |
2024 | goto out; | 2015 | goto out; |
@@ -2047,7 +2038,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, | |||
2047 | } | 2038 | } |
2048 | 2039 | ||
2049 | *(ptr + len) = '/'; | 2040 | *(ptr + len) = '/'; |
2050 | read_extent_buffer(l, ptr,(unsigned long)(iref + 1), len); | 2041 | read_extent_buffer(l, ptr, (unsigned long)(iref + 1), len); |
2051 | 2042 | ||
2052 | if (key.offset == BTRFS_FIRST_FREE_OBJECTID) | 2043 | if (key.offset == BTRFS_FIRST_FREE_OBJECTID) |
2053 | break; | 2044 | break; |
@@ -2058,7 +2049,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, | |||
2058 | dirid = key.objectid; | 2049 | dirid = key.objectid; |
2059 | } | 2050 | } |
2060 | memmove(name, ptr, total_len); | 2051 | memmove(name, ptr, total_len); |
2061 | name[total_len]='\0'; | 2052 | name[total_len] = '\0'; |
2062 | ret = 0; | 2053 | ret = 0; |
2063 | out: | 2054 | out: |
2064 | btrfs_free_path(path); | 2055 | btrfs_free_path(path); |
@@ -2098,7 +2089,7 @@ static noinline int btrfs_ioctl_ino_lookup(struct file *file, | |||
2098 | static noinline int btrfs_ioctl_snap_destroy(struct file *file, | 2089 | static noinline int btrfs_ioctl_snap_destroy(struct file *file, |
2099 | void __user *arg) | 2090 | void __user *arg) |
2100 | { | 2091 | { |
2101 | struct dentry *parent = fdentry(file); | 2092 | struct dentry *parent = file->f_path.dentry; |
2102 | struct dentry *dentry; | 2093 | struct dentry *dentry; |
2103 | struct inode *dir = parent->d_inode; | 2094 | struct inode *dir = parent->d_inode; |
2104 | struct inode *inode; | 2095 | struct inode *inode; |
@@ -2144,7 +2135,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
2144 | 2135 | ||
2145 | inode = dentry->d_inode; | 2136 | inode = dentry->d_inode; |
2146 | dest = BTRFS_I(inode)->root; | 2137 | dest = BTRFS_I(inode)->root; |
2147 | if (!capable(CAP_SYS_ADMIN)){ | 2138 | if (!capable(CAP_SYS_ADMIN)) { |
2148 | /* | 2139 | /* |
2149 | * Regular user. Only allow this with a special mount | 2140 | * Regular user. Only allow this with a special mount |
2150 | * option, when the user has write+exec access to the | 2141 | * option, when the user has write+exec access to the |
@@ -2727,15 +2718,10 @@ static long btrfs_ioctl_file_extent_same(struct file *file, | |||
2727 | size = sizeof(tmp) + | 2718 | size = sizeof(tmp) + |
2728 | tmp.dest_count * sizeof(struct btrfs_ioctl_same_extent_info); | 2719 | tmp.dest_count * sizeof(struct btrfs_ioctl_same_extent_info); |
2729 | 2720 | ||
2730 | same = kmalloc(size, GFP_NOFS); | 2721 | same = memdup_user((struct btrfs_ioctl_same_args __user *)argp, size); |
2731 | if (!same) { | ||
2732 | ret = -EFAULT; | ||
2733 | goto out; | ||
2734 | } | ||
2735 | 2722 | ||
2736 | if (copy_from_user(same, | 2723 | if (IS_ERR(same)) { |
2737 | (struct btrfs_ioctl_same_args __user *)argp, size)) { | 2724 | ret = PTR_ERR(same); |
2738 | ret = -EFAULT; | ||
2739 | goto out; | 2725 | goto out; |
2740 | } | 2726 | } |
2741 | 2727 | ||
@@ -3119,7 +3105,7 @@ out: | |||
3119 | static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | 3105 | static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, |
3120 | u64 off, u64 olen, u64 destoff) | 3106 | u64 off, u64 olen, u64 destoff) |
3121 | { | 3107 | { |
3122 | struct inode *inode = fdentry(file)->d_inode; | 3108 | struct inode *inode = file_inode(file); |
3123 | struct btrfs_root *root = BTRFS_I(inode)->root; | 3109 | struct btrfs_root *root = BTRFS_I(inode)->root; |
3124 | struct fd src_file; | 3110 | struct fd src_file; |
3125 | struct inode *src; | 3111 | struct inode *src; |
@@ -3679,9 +3665,10 @@ static long btrfs_ioctl_dev_replace(struct btrfs_root *root, void __user *arg) | |||
3679 | 3665 | ||
3680 | switch (p->cmd) { | 3666 | switch (p->cmd) { |
3681 | case BTRFS_IOCTL_DEV_REPLACE_CMD_START: | 3667 | case BTRFS_IOCTL_DEV_REPLACE_CMD_START: |
3682 | if (root->fs_info->sb->s_flags & MS_RDONLY) | 3668 | if (root->fs_info->sb->s_flags & MS_RDONLY) { |
3683 | return -EROFS; | 3669 | ret = -EROFS; |
3684 | 3670 | goto out; | |
3671 | } | ||
3685 | if (atomic_xchg( | 3672 | if (atomic_xchg( |
3686 | &root->fs_info->mutually_exclusive_operation_running, | 3673 | &root->fs_info->mutually_exclusive_operation_running, |
3687 | 1)) { | 3674 | 1)) { |
@@ -3707,7 +3694,7 @@ static long btrfs_ioctl_dev_replace(struct btrfs_root *root, void __user *arg) | |||
3707 | 3694 | ||
3708 | if (copy_to_user(arg, p, sizeof(*p))) | 3695 | if (copy_to_user(arg, p, sizeof(*p))) |
3709 | ret = -EFAULT; | 3696 | ret = -EFAULT; |
3710 | 3697 | out: | |
3711 | kfree(p); | 3698 | kfree(p); |
3712 | return ret; | 3699 | return ret; |
3713 | } | 3700 | } |
@@ -4317,7 +4304,7 @@ static long btrfs_ioctl_quota_rescan_status(struct file *file, void __user *arg) | |||
4317 | 4304 | ||
4318 | static long btrfs_ioctl_quota_rescan_wait(struct file *file, void __user *arg) | 4305 | static long btrfs_ioctl_quota_rescan_wait(struct file *file, void __user *arg) |
4319 | { | 4306 | { |
4320 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | 4307 | struct btrfs_root *root = BTRFS_I(file_inode(file))->root; |
4321 | 4308 | ||
4322 | if (!capable(CAP_SYS_ADMIN)) | 4309 | if (!capable(CAP_SYS_ADMIN)) |
4323 | return -EPERM; | 4310 | return -EPERM; |
@@ -4557,9 +4544,15 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
4557 | return btrfs_ioctl_logical_to_ino(root, argp); | 4544 | return btrfs_ioctl_logical_to_ino(root, argp); |
4558 | case BTRFS_IOC_SPACE_INFO: | 4545 | case BTRFS_IOC_SPACE_INFO: |
4559 | return btrfs_ioctl_space_info(root, argp); | 4546 | return btrfs_ioctl_space_info(root, argp); |
4560 | case BTRFS_IOC_SYNC: | 4547 | case BTRFS_IOC_SYNC: { |
4561 | btrfs_sync_fs(file->f_dentry->d_sb, 1); | 4548 | int ret; |
4562 | return 0; | 4549 | |
4550 | ret = btrfs_start_delalloc_roots(root->fs_info, 0); | ||
4551 | if (ret) | ||
4552 | return ret; | ||
4553 | ret = btrfs_sync_fs(file->f_dentry->d_sb, 1); | ||
4554 | return ret; | ||
4555 | } | ||
4563 | case BTRFS_IOC_START_SYNC: | 4556 | case BTRFS_IOC_START_SYNC: |
4564 | return btrfs_ioctl_start_sync(root, argp); | 4557 | return btrfs_ioctl_start_sync(root, argp); |
4565 | case BTRFS_IOC_WAIT_SYNC: | 4558 | case BTRFS_IOC_WAIT_SYNC: |