summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.h
diff options
context:
space:
mode:
authorArne Jansen <sensille@gmx.net>2011-04-12 12:07:57 +0200
committerArne Jansen <sensille@gmx.net>2011-05-13 15:36:14 +0200
commit73c5de0051533cbdf2bb656586c3eb21a475aa7d (patch)
tree296ad014c04ed44d9b89ac6b3818d5e98b34dd4f /fs/btrfs/volumes.h
parenta9c9bf68276c36898e23db770a65bd9b75bfac58 (diff)
btrfs: quasi-round-robin for chunk allocation
In a multi device setup, the chunk allocator currently always allocates chunks on the devices in the same order. This leads to a very uneven distribution, especially with RAID1 or RAID10 and an uneven number of devices. This patch always sorts the devices before allocating, and allocates the stripes on the devices with the most available space, as long as there is enough space available. In a low space situation, it first tries to maximize striping. The patch also simplifies the allocator and reduces the checks for corner cases. The simplification is done by several means. First, it defines the properties of each RAID type upfront. These properties are used afterwards instead of differentiating cases in several places. Second, the old allocator defined a minimum stripe size for each block group type, tried to find a large enough chunk, and if this fails just allocates a smaller one. This is now done in one step. The largest possible chunk (up to max_chunk_size) is searched and allocated. Because we now have only one pass, the allocation of the map (struct map_lookup) is moved down to the point where the number of stripes is already known. This way we avoid reallocation of the map. We still avoid allocating stripes that are not a multiple of STRIPE_SIZE.
Diffstat (limited to 'fs/btrfs/volumes.h')
-rw-r--r--fs/btrfs/volumes.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index b502f01f79e..37ae6e2126a 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -144,6 +144,7 @@ struct btrfs_device_info {
struct btrfs_device *dev;
u64 dev_offset;
u64 max_avail;
+ u64 total_avail;
};
struct map_lookup {