On 17.11.2011 01:27, Thomas Schmidt wrote:
> I wrote a small patch to improve allocation on differently sized raid devices.
> 
> With 2.6.38 I frequently ran into a no space left error that I attribute to
> this. But I'm not entierly sure. The fs was an 8 device -d raid0 -m raid10.
> The used space was the same across all devices. 5 were full and 3 bigger ones 
> still had plenty of space.
> I was unable to use the remaning space and a balance did not fix it for
> long.
> 

Did you also test with 3.0? In 3.0, the allocation strategy changed vastly.
In your setup, it should stripe to all 8 devices until the 5 smaller ones
are full, and from then on stripe to the 3 remaining devices.
See commit

commit 73c5de0051533cbdf2bb656586c3eb21a475aa7d
Author: Arne Jansen <sensi...@gmx.net>
Date:   Tue Apr 12 12:07:57 2011 +0200

    btrfs: quasi-round-robin for chunk allocation

Also using raid1 instead of raid10 will yield a better space utilization.

-Arne

> Now I tried to avoid getting there again.
> 
> The basic idea to not allocate space on the devices with the least free
> space. The amount of devices to leave out is calculated on each allocation
> to ajust to changing circumstances. It leaves the minimum number that still
> can achieve full space usage.
> 


> Additionally I tought leaving at least one out might be of use in device 
> removal.
> 
> Please take extra care with this. I'm new to btrfs, kernel and C in general.
> It was written and tested with 3.0.0.
> 
> 
> --- volumes.c.orig      2011-10-07 16:50:04.000000000 +0200
> +++ volumes.c   2011-11-16 23:49:08.097085568 +0100
> @@ -2329,6 +2329,8 @@ static int __btrfs_alloc_chunk(struct bt
>         u64 stripe_size;
>         u64 num_bytes;
>         int ndevs;
> +       u64 fs_total_avail;
> +       int opt_ndevs;
>         int i;
>         int j;
>  
> @@ -2404,6 +2406,7 @@ static int __btrfs_alloc_chunk(struct bt
>          * about the available holes on each device.
>          */
>         ndevs = 0;
> +       fs_total_avail = 0;
>         while (cur != &fs_devices->alloc_list) {
>                 struct btrfs_device *device;
>                 u64 max_avail;
> @@ -2448,6 +2451,7 @@ static int __btrfs_alloc_chunk(struct bt
>                 devices_info[ndevs].total_avail = total_avail;
>                 devices_info[ndevs].dev = device;
>                 ++ndevs;
> +               fs_total_avail += total_avail;
>         }
>  
>         /*
> @@ -2456,6 +2460,20 @@ static int __btrfs_alloc_chunk(struct bt
>         sort(devices_info, ndevs, sizeof(struct btrfs_device_info),
>              btrfs_cmp_device_info, NULL);
>  
> +       /*
> +        * do not allocate space on all devices
> +        * instead balance free space to maximise space utilization
> +        * (this needs tweaking if parity raid gets implemented
> +        * for n parity ignore the n first (after sort) devs in the sum and 
> division)
> +        */
> +       opt_ndevs = fs_total_avail / devices_info[0].total_avail;
> +       if (opt_ndevs >= ndevs)
> +               opt_ndevs = ndevs - 1; //optional, might be used for faster 
> dev remove?
> +       if (opt_ndevs < devs_min)
> +               opt_ndevs = devs_min;
> +       if (ndevs > opt_ndevs)
> +               ndevs = opt_ndevs;
> +
>         /* round down to number of usable stripes */
>         ndevs -= ndevs % devs_increment;
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to