diff options
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 9aaba6e472d3..9213d39d36cc 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -1843,6 +1843,49 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) | |||
1843 | return 0; | 1843 | return 0; |
1844 | } | 1844 | } |
1845 | 1845 | ||
1846 | long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) | ||
1847 | { | ||
1848 | struct btrfs_ioctl_space_args space_args; | ||
1849 | struct btrfs_ioctl_space_info space; | ||
1850 | struct btrfs_ioctl_space_info *dest; | ||
1851 | struct btrfs_space_info *info; | ||
1852 | int ret = 0; | ||
1853 | |||
1854 | if (copy_from_user(&space_args, | ||
1855 | (struct btrfs_ioctl_space_args __user *)arg, | ||
1856 | sizeof(space_args))) | ||
1857 | return -EFAULT; | ||
1858 | |||
1859 | space_args.total_spaces = 0; | ||
1860 | dest = (struct btrfs_ioctl_space_info *) | ||
1861 | (arg + sizeof(struct btrfs_ioctl_space_args)); | ||
1862 | |||
1863 | rcu_read_lock(); | ||
1864 | list_for_each_entry_rcu(info, &root->fs_info->space_info, list) { | ||
1865 | if (!space_args.space_slots) { | ||
1866 | space_args.total_spaces++; | ||
1867 | continue; | ||
1868 | } | ||
1869 | if (space_args.total_spaces >= space_args.space_slots) | ||
1870 | break; | ||
1871 | space.flags = info->flags; | ||
1872 | space.total_bytes = info->total_bytes; | ||
1873 | space.used_bytes = info->bytes_used; | ||
1874 | if (copy_to_user(dest, &space, sizeof(space))) { | ||
1875 | ret = -EFAULT; | ||
1876 | break; | ||
1877 | } | ||
1878 | dest++; | ||
1879 | space_args.total_spaces++; | ||
1880 | } | ||
1881 | rcu_read_unlock(); | ||
1882 | |||
1883 | if (copy_to_user(arg, &space_args, sizeof(space_args))) | ||
1884 | ret = -EFAULT; | ||
1885 | |||
1886 | return ret; | ||
1887 | } | ||
1888 | |||
1846 | /* | 1889 | /* |
1847 | * there are many ways the trans_start and trans_end ioctls can lead | 1890 | * there are many ways the trans_start and trans_end ioctls can lead |
1848 | * to deadlocks. They should only be used by applications that | 1891 | * to deadlocks. They should only be used by applications that |
@@ -1915,6 +1958,8 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
1915 | return btrfs_ioctl_tree_search(file, argp); | 1958 | return btrfs_ioctl_tree_search(file, argp); |
1916 | case BTRFS_IOC_INO_LOOKUP: | 1959 | case BTRFS_IOC_INO_LOOKUP: |
1917 | return btrfs_ioctl_ino_lookup(file, argp); | 1960 | return btrfs_ioctl_ino_lookup(file, argp); |
1961 | case BTRFS_IOC_SPACE_INFO: | ||
1962 | return btrfs_ioctl_space_info(root, argp); | ||
1918 | case BTRFS_IOC_SYNC: | 1963 | case BTRFS_IOC_SYNC: |
1919 | btrfs_sync_fs(file->f_dentry->d_sb, 1); | 1964 | btrfs_sync_fs(file->f_dentry->d_sb, 1); |
1920 | return 0; | 1965 | return 0; |