aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2011-12-14 20:12:02 -0500
committerChris Mason <chris.mason@oracle.com>2011-12-15 10:50:36 -0500
commit39fb26c398ddf8d7794a85e896cfe1a42e55524b (patch)
tree6a7c1132f8ad0b9b70a2e5cccf55d74ab3095b48 /fs/btrfs/super.c
parent3642320e07444cc46327b24977d752f99706dac2 (diff)
Btrfs: fix inaccurate available space on raid0 profile
When we use raid0 as the data profile, df command may show us a very inaccurate value of the available space, which may be much less than the real one. It may make the users puzzled. Fix it by changing the calculation of the available space, and making it be more similar to a fake chunk allocation. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r--fs/btrfs/super.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 1a3ce9e0b495..41495dce4db0 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1079,7 +1079,7 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
1079 u64 avail_space; 1079 u64 avail_space;
1080 u64 used_space; 1080 u64 used_space;
1081 u64 min_stripe_size; 1081 u64 min_stripe_size;
1082 int min_stripes = 1; 1082 int min_stripes = 1, num_stripes = 1;
1083 int i = 0, nr_devices; 1083 int i = 0, nr_devices;
1084 int ret; 1084 int ret;
1085 1085
@@ -1093,12 +1093,16 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
1093 1093
1094 /* calc min stripe number for data space alloction */ 1094 /* calc min stripe number for data space alloction */
1095 type = btrfs_get_alloc_profile(root, 1); 1095 type = btrfs_get_alloc_profile(root, 1);
1096 if (type & BTRFS_BLOCK_GROUP_RAID0) 1096 if (type & BTRFS_BLOCK_GROUP_RAID0) {
1097 min_stripes = 2; 1097 min_stripes = 2;
1098 else if (type & BTRFS_BLOCK_GROUP_RAID1) 1098 num_stripes = nr_devices;
1099 } else if (type & BTRFS_BLOCK_GROUP_RAID1) {
1099 min_stripes = 2; 1100 min_stripes = 2;
1100 else if (type & BTRFS_BLOCK_GROUP_RAID10) 1101 num_stripes = 2;
1102 } else if (type & BTRFS_BLOCK_GROUP_RAID10) {
1101 min_stripes = 4; 1103 min_stripes = 4;
1104 num_stripes = 4;
1105 }
1102 1106
1103 if (type & BTRFS_BLOCK_GROUP_DUP) 1107 if (type & BTRFS_BLOCK_GROUP_DUP)
1104 min_stripe_size = 2 * BTRFS_STRIPE_LEN; 1108 min_stripe_size = 2 * BTRFS_STRIPE_LEN;
@@ -1167,13 +1171,16 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
1167 i = nr_devices - 1; 1171 i = nr_devices - 1;
1168 avail_space = 0; 1172 avail_space = 0;
1169 while (nr_devices >= min_stripes) { 1173 while (nr_devices >= min_stripes) {
1174 if (num_stripes > nr_devices)
1175 num_stripes = nr_devices;
1176
1170 if (devices_info[i].max_avail >= min_stripe_size) { 1177 if (devices_info[i].max_avail >= min_stripe_size) {
1171 int j; 1178 int j;
1172 u64 alloc_size; 1179 u64 alloc_size;
1173 1180
1174 avail_space += devices_info[i].max_avail * min_stripes; 1181 avail_space += devices_info[i].max_avail * num_stripes;
1175 alloc_size = devices_info[i].max_avail; 1182 alloc_size = devices_info[i].max_avail;
1176 for (j = i + 1 - min_stripes; j <= i; j++) 1183 for (j = i + 1 - num_stripes; j <= i; j++)
1177 devices_info[j].max_avail -= alloc_size; 1184 devices_info[j].max_avail -= alloc_size;
1178 } 1185 }
1179 i--; 1186 i--;