aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ctree.h2
-rw-r--r--fs/btrfs/ioctl.c131
-rw-r--r--fs/btrfs/ioctl.h38
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
193struct btrfs_dev_item { 192struct 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
1806static 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
1833static 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
1867out:
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
1806static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, 1875static 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
2537static 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
2559static 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
2567static 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
2468long btrfs_ioctl(struct file *file, unsigned int 2589long 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
37struct btrfs_ioctl_vol_args_v2 { 39struct btrfs_ioctl_vol_args_v2 {
@@ -79,6 +81,33 @@ struct btrfs_scrub_progress {
79 * Intermittent error. */ 81 * Intermittent error. */
80}; 82};
81 83
84struct 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
95struct 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
104struct 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
83struct btrfs_ioctl_ino_lookup_args { 112struct 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