diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ctree.h | 2 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 131 | ||||
-rw-r--r-- | fs/btrfs/ioctl.h | 38 |
3 files changed, 169 insertions, 2 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 31141ba6072d..b7373b14e4cd 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -189,7 +189,6 @@ struct btrfs_mapping_tree { | |||
189 | struct extent_map_tree map_tree; | 189 | struct extent_map_tree map_tree; |
190 | }; | 190 | }; |
191 | 191 | ||
192 | #define BTRFS_UUID_SIZE 16 | ||
193 | struct btrfs_dev_item { | 192 | struct btrfs_dev_item { |
194 | /* the internal btrfs device id */ | 193 | /* the internal btrfs device id */ |
195 | __le64 devid; | 194 | __le64 devid; |
@@ -296,7 +295,6 @@ static inline unsigned long btrfs_chunk_item_size(int num_stripes) | |||
296 | sizeof(struct btrfs_stripe) * (num_stripes - 1); | 295 | sizeof(struct btrfs_stripe) * (num_stripes - 1); |
297 | } | 296 | } |
298 | 297 | ||
299 | #define BTRFS_FSID_SIZE 16 | ||
300 | #define BTRFS_HEADER_FLAG_WRITTEN (1ULL << 0) | 298 | #define BTRFS_HEADER_FLAG_WRITTEN (1ULL << 0) |
301 | #define BTRFS_HEADER_FLAG_RELOC (1ULL << 1) | 299 | #define BTRFS_HEADER_FLAG_RELOC (1ULL << 1) |
302 | 300 | ||
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index f580a3a5d2fc..205cd011d2f3 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -1803,6 +1803,75 @@ static long btrfs_ioctl_rm_dev(struct btrfs_root *root, void __user *arg) | |||
1803 | return ret; | 1803 | return ret; |
1804 | } | 1804 | } |
1805 | 1805 | ||
1806 | static long btrfs_ioctl_fs_info(struct btrfs_root *root, void __user *arg) | ||
1807 | { | ||
1808 | struct btrfs_ioctl_fs_info_args fi_args; | ||
1809 | struct btrfs_device *device; | ||
1810 | struct btrfs_device *next; | ||
1811 | struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; | ||
1812 | |||
1813 | if (!capable(CAP_SYS_ADMIN)) | ||
1814 | return -EPERM; | ||
1815 | |||
1816 | fi_args.num_devices = fs_devices->num_devices; | ||
1817 | fi_args.max_id = 0; | ||
1818 | memcpy(&fi_args.fsid, root->fs_info->fsid, sizeof(fi_args.fsid)); | ||
1819 | |||
1820 | mutex_lock(&fs_devices->device_list_mutex); | ||
1821 | list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) { | ||
1822 | if (device->devid > fi_args.max_id) | ||
1823 | fi_args.max_id = device->devid; | ||
1824 | } | ||
1825 | mutex_unlock(&fs_devices->device_list_mutex); | ||
1826 | |||
1827 | if (copy_to_user(arg, &fi_args, sizeof(fi_args))) | ||
1828 | return -EFAULT; | ||
1829 | |||
1830 | return 0; | ||
1831 | } | ||
1832 | |||
1833 | static long btrfs_ioctl_dev_info(struct btrfs_root *root, void __user *arg) | ||
1834 | { | ||
1835 | struct btrfs_ioctl_dev_info_args *di_args; | ||
1836 | struct btrfs_device *dev; | ||
1837 | struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; | ||
1838 | int ret = 0; | ||
1839 | char *s_uuid = NULL; | ||
1840 | char empty_uuid[BTRFS_UUID_SIZE] = {0}; | ||
1841 | |||
1842 | if (!capable(CAP_SYS_ADMIN)) | ||
1843 | return -EPERM; | ||
1844 | |||
1845 | di_args = memdup_user(arg, sizeof(*di_args)); | ||
1846 | if (IS_ERR(di_args)) | ||
1847 | return PTR_ERR(di_args); | ||
1848 | |||
1849 | if (memcmp(empty_uuid, di_args->uuid, BTRFS_UUID_SIZE) != 0) | ||
1850 | s_uuid = di_args->uuid; | ||
1851 | |||
1852 | mutex_lock(&fs_devices->device_list_mutex); | ||
1853 | dev = btrfs_find_device(root, di_args->devid, s_uuid, NULL); | ||
1854 | mutex_unlock(&fs_devices->device_list_mutex); | ||
1855 | |||
1856 | if (!dev) { | ||
1857 | ret = -ENODEV; | ||
1858 | goto out; | ||
1859 | } | ||
1860 | |||
1861 | di_args->devid = dev->devid; | ||
1862 | di_args->bytes_used = dev->bytes_used; | ||
1863 | di_args->total_bytes = dev->total_bytes; | ||
1864 | memcpy(di_args->uuid, dev->uuid, sizeof(di_args->uuid)); | ||
1865 | strncpy(di_args->path, dev->name, sizeof(di_args->path)); | ||
1866 | |||
1867 | out: | ||
1868 | if (ret == 0 && copy_to_user(arg, di_args, sizeof(*di_args))) | ||
1869 | ret = -EFAULT; | ||
1870 | |||
1871 | kfree(di_args); | ||
1872 | return ret; | ||
1873 | } | ||
1874 | |||
1806 | static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | 1875 | static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, |
1807 | u64 off, u64 olen, u64 destoff) | 1876 | u64 off, u64 olen, u64 destoff) |
1808 | { | 1877 | { |
@@ -2465,6 +2534,58 @@ static noinline long btrfs_ioctl_wait_sync(struct file *file, void __user *argp) | |||
2465 | return btrfs_wait_for_commit(root, transid); | 2534 | return btrfs_wait_for_commit(root, transid); |
2466 | } | 2535 | } |
2467 | 2536 | ||
2537 | static long btrfs_ioctl_scrub(struct btrfs_root *root, void __user *arg) | ||
2538 | { | ||
2539 | int ret; | ||
2540 | struct btrfs_ioctl_scrub_args *sa; | ||
2541 | |||
2542 | if (!capable(CAP_SYS_ADMIN)) | ||
2543 | return -EPERM; | ||
2544 | |||
2545 | sa = memdup_user(arg, sizeof(*sa)); | ||
2546 | if (IS_ERR(sa)) | ||
2547 | return PTR_ERR(sa); | ||
2548 | |||
2549 | ret = btrfs_scrub_dev(root, sa->devid, sa->start, sa->end, | ||
2550 | &sa->progress); | ||
2551 | |||
2552 | if (copy_to_user(arg, sa, sizeof(*sa))) | ||
2553 | ret = -EFAULT; | ||
2554 | |||
2555 | kfree(sa); | ||
2556 | return ret; | ||
2557 | } | ||
2558 | |||
2559 | static long btrfs_ioctl_scrub_cancel(struct btrfs_root *root, void __user *arg) | ||
2560 | { | ||
2561 | if (!capable(CAP_SYS_ADMIN)) | ||
2562 | return -EPERM; | ||
2563 | |||
2564 | return btrfs_scrub_cancel(root); | ||
2565 | } | ||
2566 | |||
2567 | static long btrfs_ioctl_scrub_progress(struct btrfs_root *root, | ||
2568 | void __user *arg) | ||
2569 | { | ||
2570 | struct btrfs_ioctl_scrub_args *sa; | ||
2571 | int ret; | ||
2572 | |||
2573 | if (!capable(CAP_SYS_ADMIN)) | ||
2574 | return -EPERM; | ||
2575 | |||
2576 | sa = memdup_user(arg, sizeof(*sa)); | ||
2577 | if (IS_ERR(sa)) | ||
2578 | return PTR_ERR(sa); | ||
2579 | |||
2580 | ret = btrfs_scrub_progress(root, sa->devid, &sa->progress); | ||
2581 | |||
2582 | if (copy_to_user(arg, sa, sizeof(*sa))) | ||
2583 | ret = -EFAULT; | ||
2584 | |||
2585 | kfree(sa); | ||
2586 | return ret; | ||
2587 | } | ||
2588 | |||
2468 | long btrfs_ioctl(struct file *file, unsigned int | 2589 | long btrfs_ioctl(struct file *file, unsigned int |
2469 | cmd, unsigned long arg) | 2590 | cmd, unsigned long arg) |
2470 | { | 2591 | { |
@@ -2504,6 +2625,10 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
2504 | return btrfs_ioctl_add_dev(root, argp); | 2625 | return btrfs_ioctl_add_dev(root, argp); |
2505 | case BTRFS_IOC_RM_DEV: | 2626 | case BTRFS_IOC_RM_DEV: |
2506 | return btrfs_ioctl_rm_dev(root, argp); | 2627 | return btrfs_ioctl_rm_dev(root, argp); |
2628 | case BTRFS_IOC_FS_INFO: | ||
2629 | return btrfs_ioctl_fs_info(root, argp); | ||
2630 | case BTRFS_IOC_DEV_INFO: | ||
2631 | return btrfs_ioctl_dev_info(root, argp); | ||
2507 | case BTRFS_IOC_BALANCE: | 2632 | case BTRFS_IOC_BALANCE: |
2508 | return btrfs_balance(root->fs_info->dev_root); | 2633 | return btrfs_balance(root->fs_info->dev_root); |
2509 | case BTRFS_IOC_CLONE: | 2634 | case BTRFS_IOC_CLONE: |
@@ -2527,6 +2652,12 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
2527 | return btrfs_ioctl_start_sync(file, argp); | 2652 | return btrfs_ioctl_start_sync(file, argp); |
2528 | case BTRFS_IOC_WAIT_SYNC: | 2653 | case BTRFS_IOC_WAIT_SYNC: |
2529 | return btrfs_ioctl_wait_sync(file, argp); | 2654 | return btrfs_ioctl_wait_sync(file, argp); |
2655 | case BTRFS_IOC_SCRUB: | ||
2656 | return btrfs_ioctl_scrub(root, argp); | ||
2657 | case BTRFS_IOC_SCRUB_CANCEL: | ||
2658 | return btrfs_ioctl_scrub_cancel(root, argp); | ||
2659 | case BTRFS_IOC_SCRUB_PROGRESS: | ||
2660 | return btrfs_ioctl_scrub_progress(root, argp); | ||
2530 | } | 2661 | } |
2531 | 2662 | ||
2532 | return -ENOTTY; | 2663 | return -ENOTTY; |
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 37ac030d64b4..1a638ceeead8 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h | |||
@@ -32,6 +32,8 @@ struct btrfs_ioctl_vol_args { | |||
32 | 32 | ||
33 | #define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0) | 33 | #define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0) |
34 | #define BTRFS_SUBVOL_RDONLY (1ULL << 1) | 34 | #define BTRFS_SUBVOL_RDONLY (1ULL << 1) |
35 | #define BTRFS_FSID_SIZE 16 | ||
36 | #define BTRFS_UUID_SIZE 16 | ||
35 | 37 | ||
36 | #define BTRFS_SUBVOL_NAME_MAX 4039 | 38 | #define BTRFS_SUBVOL_NAME_MAX 4039 |
37 | struct btrfs_ioctl_vol_args_v2 { | 39 | struct btrfs_ioctl_vol_args_v2 { |
@@ -79,6 +81,33 @@ struct btrfs_scrub_progress { | |||
79 | * Intermittent error. */ | 81 | * Intermittent error. */ |
80 | }; | 82 | }; |
81 | 83 | ||
84 | struct btrfs_ioctl_scrub_args { | ||
85 | __u64 devid; /* in */ | ||
86 | __u64 start; /* in */ | ||
87 | __u64 end; /* in */ | ||
88 | __u64 flags; /* in */ | ||
89 | struct btrfs_scrub_progress progress; /* out */ | ||
90 | /* pad to 1k */ | ||
91 | __u64 unused[(1024-32-sizeof(struct btrfs_scrub_progress))/8]; | ||
92 | }; | ||
93 | |||
94 | #define BTRFS_DEVICE_PATH_NAME_MAX 1024 | ||
95 | struct btrfs_ioctl_dev_info_args { | ||
96 | __u64 devid; /* in/out */ | ||
97 | __u8 uuid[BTRFS_UUID_SIZE]; /* in/out */ | ||
98 | __u64 bytes_used; /* out */ | ||
99 | __u64 total_bytes; /* out */ | ||
100 | __u64 unused[379]; /* pad to 4k */ | ||
101 | __u8 path[BTRFS_DEVICE_PATH_NAME_MAX]; /* out */ | ||
102 | }; | ||
103 | |||
104 | struct btrfs_ioctl_fs_info_args { | ||
105 | __u64 max_id; /* out */ | ||
106 | __u64 num_devices; /* out */ | ||
107 | __u8 fsid[BTRFS_FSID_SIZE]; /* out */ | ||
108 | __u64 reserved[124]; /* pad to 1k */ | ||
109 | }; | ||
110 | |||
82 | #define BTRFS_INO_LOOKUP_PATH_MAX 4080 | 111 | #define BTRFS_INO_LOOKUP_PATH_MAX 4080 |
83 | struct btrfs_ioctl_ino_lookup_args { | 112 | struct btrfs_ioctl_ino_lookup_args { |
84 | __u64 treeid; | 113 | __u64 treeid; |
@@ -240,4 +269,13 @@ struct btrfs_ioctl_space_args { | |||
240 | struct btrfs_ioctl_vol_args_v2) | 269 | struct btrfs_ioctl_vol_args_v2) |
241 | #define BTRFS_IOC_SUBVOL_GETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 25, __u64) | 270 | #define BTRFS_IOC_SUBVOL_GETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 25, __u64) |
242 | #define BTRFS_IOC_SUBVOL_SETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 26, __u64) | 271 | #define BTRFS_IOC_SUBVOL_SETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 26, __u64) |
272 | #define BTRFS_IOC_SCRUB _IOWR(BTRFS_IOCTL_MAGIC, 27, \ | ||
273 | struct btrfs_ioctl_scrub_args) | ||
274 | #define BTRFS_IOC_SCRUB_CANCEL _IO(BTRFS_IOCTL_MAGIC, 28) | ||
275 | #define BTRFS_IOC_SCRUB_PROGRESS _IOWR(BTRFS_IOCTL_MAGIC, 29, \ | ||
276 | struct btrfs_ioctl_scrub_args) | ||
277 | #define BTRFS_IOC_DEV_INFO _IOWR(BTRFS_IOCTL_MAGIC, 30, \ | ||
278 | struct btrfs_ioctl_dev_info_args) | ||
279 | #define BTRFS_IOC_FS_INFO _IOR(BTRFS_IOCTL_MAGIC, 31, \ | ||
280 | struct btrfs_ioctl_fs_info_args) | ||
243 | #endif | 281 | #endif |