Skip to content

Commit

Permalink
Btrfs: fix inaccurate available space on raid0 profile
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Chris Mason <[email protected]>
  • Loading branch information
Miao Xie authored and chrismason-xx committed Dec 15, 2011
1 parent 3642320 commit 39fb26c
Showing 1 changed file with 13 additions and 6 deletions.
19 changes: 13 additions & 6 deletions fs/btrfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1079,7 +1079,7 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
u64 avail_space;
u64 used_space;
u64 min_stripe_size;
int min_stripes = 1;
int min_stripes = 1, num_stripes = 1;
int i = 0, nr_devices;
int ret;

Expand All @@ -1093,12 +1093,16 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)

/* calc min stripe number for data space alloction */
type = btrfs_get_alloc_profile(root, 1);
if (type & BTRFS_BLOCK_GROUP_RAID0)
if (type & BTRFS_BLOCK_GROUP_RAID0) {
min_stripes = 2;
else if (type & BTRFS_BLOCK_GROUP_RAID1)
num_stripes = nr_devices;
} else if (type & BTRFS_BLOCK_GROUP_RAID1) {
min_stripes = 2;
else if (type & BTRFS_BLOCK_GROUP_RAID10)
num_stripes = 2;
} else if (type & BTRFS_BLOCK_GROUP_RAID10) {
min_stripes = 4;
num_stripes = 4;
}

if (type & BTRFS_BLOCK_GROUP_DUP)
min_stripe_size = 2 * BTRFS_STRIPE_LEN;
Expand Down Expand Up @@ -1167,13 +1171,16 @@ static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes)
i = nr_devices - 1;
avail_space = 0;
while (nr_devices >= min_stripes) {
if (num_stripes > nr_devices)
num_stripes = nr_devices;

if (devices_info[i].max_avail >= min_stripe_size) {
int j;
u64 alloc_size;

avail_space += devices_info[i].max_avail * min_stripes;
avail_space += devices_info[i].max_avail * num_stripes;
alloc_size = devices_info[i].max_avail;
for (j = i + 1 - min_stripes; j <= i; j++)
for (j = i + 1 - num_stripes; j <= i; j++)
devices_info[j].max_avail -= alloc_size;
}
i--;
Expand Down

0 comments on commit 39fb26c

Please sign in to comment.