aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
authorJan Schmidt <list.btrfs@jan-o-sch.net>2011-03-11 09:41:01 -0500
committerArne Jansen <sensille@gmx.net>2011-05-12 08:45:38 -0400
commit475f63874d739d7842a56da94687f18d583ae654 (patch)
tree096902bd87353d1e8be3cf6a9ecadb66fc620d11 /fs/btrfs/ioctl.c
parenta2de733c78fa7af51ba9670482fa7d392aa67c57 (diff)
btrfs: new ioctls for scrub
adds ioctls necessary to start and cancel scrubs, to get current progress and to get info about devices to be scrubbed. Note that the scrub is done per-device and that the ioctl only returns after the scrub for this devices is finished or has been canceled. Signed-off-by: Arne Jansen <sensille@gmx.net>
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c131
1 files changed, 131 insertions, 0 deletions
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;