]> git.hungrycats.org Git - linux/commitdiff
zygo: btrfs: prefer aligned dev_extent holes when allocating chunks (v4, handle last... zygo-6.7.x-zb64
authorZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Wed, 14 Feb 2024 05:10:23 +0000 (00:10 -0500)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Thu, 4 Apr 2024 04:27:42 +0000 (00:27 -0400)
zygo: btrfs: prefer aligned dev_extent holes when allocating chunks (v2, right end of the hole)

(cherry picked from commit ded252ea39093671390a526a76c6def61d7e6ac1)

zygo: btrfs: prefer aligned dev_extent holes when allocating chunks (v3, handle last hole correctly)

(cherry picked from commit 825cb15cd8a02a083042cc6fa12767ec1805f92d)

(cherry picked from commit 4ca76de09f5ac2c9354df4effd4bcea41830eb47)

fs/btrfs/volumes.c

index 20a0ac1e145082a40671c9dcca50a68048d56532..7a23feb068cbd6793294d6c632958dbe4820b250 100644 (file)
@@ -1685,21 +1685,25 @@ again:
                        dev_extent_hole_check(device, &search_start, &hole_size,
                                              num_bytes);
 
-                       if (hole_size > max_hole_size) {
+                       /*
+                        * Once we find a hole of sufficient size we
+                        * ignore any larger holes that may appear at
+                        * higher device offsets.  If we later find a
+                        * hole that is sufficiently large, but aligned,
+                        * we'll use that instead.
+                        */
+                       if (hole_size > max_hole_size && max_hole_size < num_bytes) {
                                max_hole_start = search_start;
                                max_hole_size = hole_size;
                        }
 
                        /*
-                        * If this free space is greater than which we need,
-                        * it must be the max free space that we have found
-                        * until now, so max_hole_start must point to the start
-                        * of this free space and the length of this free space
-                        * is stored in max_hole_size. Thus, we return
-                        * max_hole_start and max_hole_size and go back to the
-                        * caller.
+                        * If we find a hole that is aligned and as large
+                        * as we need, then exit early with that hole.
                         */
-                       if (hole_size >= num_bytes) {
+                       if (hole_size >= num_bytes && (search_start & (SZ_1G - 1)) == SZ_1M) {
+                               max_hole_start = search_start;
+                               max_hole_size = hole_size;
                                ret = 0;
                                goto out;
                        }
@@ -1728,9 +1732,24 @@ next:
                        goto again;
                }
 
-               if (hole_size > max_hole_size) {
+               /*
+                * If this is a larger hole it might not be aligned.
+                * Keep the hole we found above if it was large enough.
+                */
+               if (hole_size > max_hole_size && max_hole_size < num_bytes) {
+                       max_hole_start = search_start;
+                       max_hole_size = hole_size;
+               }
+
+               /*
+                * The last hole may be aligned and longer than any other,
+                * so do the aligned check and exit early again.
+                */
+               if (hole_size >= num_bytes && (search_start & (SZ_1G - 1)) == SZ_1M) {
                        max_hole_start = search_start;
                        max_hole_size = hole_size;
+                       ret = 0;
+                       goto out;
                }
        }