aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ioctl.c100
1 files changed, 76 insertions, 24 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 9254b3d58db..db0b8fc5923 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1879,6 +1879,22 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
1879 return 0; 1879 return 0;
1880} 1880}
1881 1881
1882static void get_block_group_info(struct list_head *groups_list,
1883 struct btrfs_ioctl_space_info *space)
1884{
1885 struct btrfs_block_group_cache *block_group;
1886
1887 space->total_bytes = 0;
1888 space->used_bytes = 0;
1889 space->flags = 0;
1890 list_for_each_entry(block_group, groups_list, list) {
1891 space->flags = block_group->flags;
1892 space->total_bytes += block_group->key.offset;
1893 space->used_bytes +=
1894 btrfs_block_group_used(&block_group->item);
1895 }
1896}
1897
1882long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) 1898long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
1883{ 1899{
1884 struct btrfs_ioctl_space_args space_args; 1900 struct btrfs_ioctl_space_args space_args;
@@ -1887,27 +1903,56 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
1887 struct btrfs_ioctl_space_info *dest_orig; 1903 struct btrfs_ioctl_space_info *dest_orig;
1888 struct btrfs_ioctl_space_info *user_dest; 1904 struct btrfs_ioctl_space_info *user_dest;
1889 struct btrfs_space_info *info; 1905 struct btrfs_space_info *info;
1906 u64 types[] = {BTRFS_BLOCK_GROUP_DATA,
1907 BTRFS_BLOCK_GROUP_SYSTEM,
1908 BTRFS_BLOCK_GROUP_METADATA,
1909 BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA};
1910 int num_types = 4;
1890 int alloc_size; 1911 int alloc_size;
1891 int ret = 0; 1912 int ret = 0;
1892 int slot_count = 0; 1913 int slot_count = 0;
1914 int i, c;
1893 1915
1894 if (copy_from_user(&space_args, 1916 if (copy_from_user(&space_args,
1895 (struct btrfs_ioctl_space_args __user *)arg, 1917 (struct btrfs_ioctl_space_args __user *)arg,
1896 sizeof(space_args))) 1918 sizeof(space_args)))
1897 return -EFAULT; 1919 return -EFAULT;
1898 1920
1899 /* first we count slots */ 1921 for (i = 0; i < num_types; i++) {
1900 rcu_read_lock(); 1922 struct btrfs_space_info *tmp;
1901 list_for_each_entry_rcu(info, &root->fs_info->space_info, list) 1923
1902 slot_count++; 1924 info = NULL;
1903 rcu_read_unlock(); 1925 rcu_read_lock();
1926 list_for_each_entry_rcu(tmp, &root->fs_info->space_info,
1927 list) {
1928 if (tmp->flags == types[i]) {
1929 info = tmp;
1930 break;
1931 }
1932 }
1933 rcu_read_unlock();
1934
1935 if (!info)
1936 continue;
1937
1938 down_read(&info->groups_sem);
1939 for (c = 0; c < BTRFS_NR_RAID_TYPES; c++) {
1940 if (!list_empty(&info->block_groups[c]))
1941 slot_count++;
1942 }
1943 up_read(&info->groups_sem);
1944 }
1904 1945
1905 /* space_slots == 0 means they are asking for a count */ 1946 /* space_slots == 0 means they are asking for a count */
1906 if (space_args.space_slots == 0) { 1947 if (space_args.space_slots == 0) {
1907 space_args.total_spaces = slot_count; 1948 space_args.total_spaces = slot_count;
1908 goto out; 1949 goto out;
1909 } 1950 }
1951
1952 slot_count = min_t(int, space_args.space_slots, slot_count);
1953
1910 alloc_size = sizeof(*dest) * slot_count; 1954 alloc_size = sizeof(*dest) * slot_count;
1955
1911 /* we generally have at most 6 or so space infos, one for each raid 1956 /* we generally have at most 6 or so space infos, one for each raid
1912 * level. So, a whole page should be more than enough for everyone 1957 * level. So, a whole page should be more than enough for everyone
1913 */ 1958 */
@@ -1921,27 +1966,34 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
1921 dest_orig = dest; 1966 dest_orig = dest;
1922 1967
1923 /* now we have a buffer to copy into */ 1968 /* now we have a buffer to copy into */
1924 rcu_read_lock(); 1969 for (i = 0; i < num_types; i++) {
1925 list_for_each_entry_rcu(info, &root->fs_info->space_info, list) { 1970 struct btrfs_space_info *tmp;
1926 /* make sure we don't copy more than we allocated 1971
1927 * in our buffer 1972 info = NULL;
1928 */ 1973 rcu_read_lock();
1929 if (slot_count == 0) 1974 list_for_each_entry_rcu(tmp, &root->fs_info->space_info,
1930 break; 1975 list) {
1931 slot_count--; 1976 if (tmp->flags == types[i]) {
1932 1977 info = tmp;
1933 /* make sure userland has enough room in their buffer */ 1978 break;
1934 if (space_args.total_spaces >= space_args.space_slots) 1979 }
1935 break; 1980 }
1981 rcu_read_unlock();
1936 1982
1937 space.flags = info->flags; 1983 if (!info)
1938 space.total_bytes = info->total_bytes; 1984 continue;
1939 space.used_bytes = info->bytes_used; 1985 down_read(&info->groups_sem);
1940 memcpy(dest, &space, sizeof(space)); 1986 for (c = 0; c < BTRFS_NR_RAID_TYPES; c++) {
1941 dest++; 1987 if (!list_empty(&info->block_groups[c])) {
1942 space_args.total_spaces++; 1988 get_block_group_info(&info->block_groups[c],
1989 &space);
1990 memcpy(dest, &space, sizeof(space));
1991 dest++;
1992 space_args.total_spaces++;
1993 }
1994 }
1995 up_read(&info->groups_sem);
1943 } 1996 }
1944 rcu_read_unlock();
1945 1997
1946 user_dest = (struct btrfs_ioctl_space_info *) 1998 user_dest = (struct btrfs_ioctl_space_info *)
1947 (arg + sizeof(struct btrfs_ioctl_space_args)); 1999 (arg + sizeof(struct btrfs_ioctl_space_args));