aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2010-09-29 11:22:36 -0400
committerJosef Bacik <josef@redhat.com>2010-10-22 15:54:53 -0400
commitbf5fc093c5b625e4259203f1cee7ca73488a5620 (patch)
tree099385541c534c1adcdb4251277ee4364562d5ec /fs/btrfs
parenta1f765061e1491d5ec467429d0d6adfd9df2f6d9 (diff)
Btrfs: fix the df ioctl to report raid types
The new ENOSPC stuff broke the df ioctl since we no longer create seperate space info's for each RAID type. So instead, loop through each space info's raid lists so we can get the right RAID information which will allow the df ioctl to tell us RAID types again. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs/btrfs')
-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 9254b3d58dbe..db0b8fc59235 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));