92 lines
3.4 KiB
Diff
92 lines
3.4 KiB
Diff
From b6a7b627b1211f87e3bac3dc0111d056e70aa773 Mon Sep 17 00:00:00 2001
|
|
From: "Darrick J. Wong" <djwong@kernel.org>
|
|
Date: Tue, 17 May 2022 22:48:12 -0400
|
|
Subject: [PATCH] mkfs: fix missing validation of -l size against maximum
|
|
internal log size
|
|
|
|
If a sysadmin specifies a log size explicitly, we don't actually check
|
|
that against the maximum internal log size that we compute for the
|
|
default log size computation. We're going to add more validation soon,
|
|
so refactor the max internal log blocks into a common variable and
|
|
add a check.
|
|
|
|
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
|
|
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
|
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
|
|
---
|
|
mkfs/xfs_mkfs.c | 36 ++++++++++++++++++++++--------------
|
|
1 file changed, 22 insertions(+), 14 deletions(-)
|
|
|
|
diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c
|
|
index b7e335f..f7006af 100644
|
|
--- a/mkfs/xfs_mkfs.c
|
|
+++ b/mkfs/xfs_mkfs.c
|
|
@@ -3268,6 +3268,7 @@ calculate_log_size(
|
|
{
|
|
struct xfs_sb *sbp = &mp->m_sb;
|
|
int min_logblocks;
|
|
+ int max_logblocks; /* absolute max for this AG */
|
|
struct xfs_mount mount;
|
|
|
|
/* we need a temporary mount to calculate the minimum log size. */
|
|
@@ -3307,6 +3308,18 @@ _("external log device size %lld blocks too small, must be at least %lld blocks\
|
|
return;
|
|
}
|
|
|
|
+ /*
|
|
+ * 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.
|
|
+ */
|
|
+ max_logblocks = libxfs_alloc_ag_max_usable(mp) - 1;
|
|
+
|
|
/* internal log - if no size specified, calculate automatically */
|
|
if (!cfg->logblocks) {
|
|
if (cfg->dblocks < GIGABYTES(1, cfg->blocklog)) {
|
|
@@ -3332,21 +3345,9 @@ _("external log device size %lld blocks too small, must be at least %lld blocks\
|
|
cfg->logblocks = cfg->logblocks >> cfg->blocklog;
|
|
}
|
|
|
|
- /* Ensure the chosen size meets minimum log size requirements */
|
|
+ /* Ensure the chosen size fits within log size requirements */
|
|
cfg->logblocks = max(min_logblocks, cfg->logblocks);
|
|
-
|
|
- /*
|
|
- * 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.
|
|
- */
|
|
- cfg->logblocks = min(cfg->logblocks,
|
|
- libxfs_alloc_ag_max_usable(mp) - 1);
|
|
+ cfg->logblocks = min(cfg->logblocks, max_logblocks);
|
|
|
|
/* and now clamp the size to the maximum supported size */
|
|
cfg->logblocks = min(cfg->logblocks, XFS_MAX_LOG_BLOCKS);
|
|
@@ -3354,6 +3355,13 @@ _("external log device size %lld blocks too small, must be at least %lld blocks\
|
|
cfg->logblocks = XFS_MAX_LOG_BYTES >> cfg->blocklog;
|
|
|
|
validate_log_size(cfg->logblocks, cfg->blocklog, min_logblocks);
|
|
+ } else if (cfg->logblocks > max_logblocks) {
|
|
+ /* check specified log size */
|
|
+ fprintf(stderr,
|
|
+_("internal log size %lld too large, must be less than %d\n"),
|
|
+ (long long)cfg->logblocks,
|
|
+ max_logblocks);
|
|
+ usage();
|
|
}
|
|
|
|
if (cfg->logblocks > sbp->sb_agblocks - libxfs_prealloc_blocks(mp)) {
|
|
--
|
|
1.8.3.1
|
|
|