]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
mkfs: don't let internal logs consume more than 95% of an AG
authorDarrick J. Wong <djwong@kernel.org>
Sat, 12 Mar 2022 01:32:02 +0000 (17:32 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Thu, 17 Mar 2022 21:40:26 +0000 (14:40 -0700)
Currently, we don't let an internal log consume every last block in an
AG.  According to the comment, we're doing this to avoid tripping AGF
verifiers if freeblks==0, but on a modern filesystem this isn't
sufficient to avoid problems.  First, the per-AG reservations for
reflink and rmap claim up to about 1.7% of each AG for btree expansion,
and secondly, we need to have enough space in the AG to allocate the
root inode chunk, if it should be the case that the log ends up in AG 0.
We don't care about nonredundant (i.e. agcount==1) filesystems, but it
can also happen if the user passes in -lagnum=0.

Change this constraint so that we can't leave less than 5% free space
after allocating the log.  This is perhaps a bit much, but as we're
about to disallow tiny filesystems anyway, it seems unlikely to cause
problems with scenarios that we care about.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
mkfs/xfs_mkfs.c

index b97bd360d5c826d1f3fbb24b657507dfe303bf44..ad776492ba87741fc3fba408820a37e7dddbd390 100644 (file)
@@ -3271,15 +3271,18 @@ clamp_internal_log_size(
        /*
         * Make sure the log fits wholly within an AG
         *
-        * XXX: If agf->freeblks ends up as 0 because the log uses all
-        * the free space, it causes the kernel all sorts of problems
-        * with per-ag reservations. Right now just back it off one
-        * block, but there's a whole can of worms here that needs to be
-        * opened to decide what is the valid maximum size of a log in
-        * an AG.
+        * XXX: If agf->freeblks ends up as 0 because the log uses all the free
+        * space, it causes the kernel all sorts of problems with per-AG
+        * reservations.  The reservations are only supposed to take 2% of the
+        * AG, but there's a further problem that if the log ends up in AG 0,
+        * we also need space to allocate the root directory inode chunk.
+        *
+        * Right now just back it off by 5%, but there's a whole can of worms
+        * here that needs to be opened to decide what is the valid maximum
+        * size of a log in an AG.
         */
        cfg->logblocks = min(cfg->logblocks,
-                            libxfs_alloc_ag_max_usable(mp) - 1);
+                            libxfs_alloc_ag_max_usable(mp) * 95 / 100);
 
        /* and now clamp the size to the maximum supported size */
        cfg->logblocks = min(cfg->logblocks, XFS_MAX_LOG_BLOCKS);