parent
ea8f4865c1
commit
46f580019c
@ -1 +1 @@
|
||||
SOURCES/xfsprogs-6.3.0.tar.xz
|
||||
SOURCES/xfsprogs-6.4.0.tar.xz
|
||||
|
@ -1 +1 @@
|
||||
e976c2c41a957ee16094690596ee210dd45951fa SOURCES/xfsprogs-6.3.0.tar.xz
|
||||
04935475fff6580d7e1919bf9a19331951edf529 SOURCES/xfsprogs-6.4.0.tar.xz
|
||||
|
@ -1,7 +0,0 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iIQEABYIAC0WIQT6QG4gav94c4l8aGS0VhjDaiT9IwUCZGs+kg8cY2VtQGtlcm5l
|
||||
bC5vcmcACgkQtFYYw2ok/SO6wgEAgMdBBcJsx/oEPKLXGZr+ueGZ81K7hGq8ueFF
|
||||
sXp69AEA+PiK4Bh/angpo2lhftgZhGaOHxmj8vIyH2jJSw53LgE=
|
||||
=+kzW
|
||||
-----END PGP SIGNATURE-----
|
@ -1,30 +0,0 @@
|
||||
From 965f91091e4442ea74132aa0c3c6795d922bda8c Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Reichl <preichl@redhat.com>
|
||||
Date: Thu, 8 Jun 2023 11:13:20 +0200
|
||||
Subject: [PATCH] mkfs: fix man's default value for sparse option
|
||||
|
||||
Fixes: 9cf846b51 ("mkfs: enable sparse inodes by default")
|
||||
Suggested-by: Lukas Herbolt <lukas@herbolt.com>
|
||||
Signed-off-by: Pavel Reichl <preichl@redhat.com>
|
||||
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Signed-off-by: Carlos Maiolino <cem@kernel.org>
|
||||
---
|
||||
man/man8/mkfs.xfs.8.in | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/man/man8/mkfs.xfs.8.in b/man/man8/mkfs.xfs.8.in
|
||||
index 01f9dc6e..ce6f1e2d 100644
|
||||
--- a/man/man8/mkfs.xfs.8.in
|
||||
+++ b/man/man8/mkfs.xfs.8.in
|
||||
@@ -631,7 +631,7 @@ Enable sparse inode chunk allocation. The
|
||||
.I value
|
||||
is either 0 or 1, with 1 signifying that sparse allocation is enabled.
|
||||
If the value is omitted, 1 is assumed. Sparse inode allocation is
|
||||
-disabled by default. This feature is only available for filesystems
|
||||
+enabled by default. This feature is only available for filesystems
|
||||
formatted with
|
||||
.B \-m crc=1.
|
||||
.IP
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,131 +0,0 @@
|
||||
From 7901c8c1a501de87c42bb1ed83456f99462538c6 Mon Sep 17 00:00:00 2001
|
||||
From: "Darrick J. Wong" <djwong@kernel.org>
|
||||
Date: Thu, 1 Jun 2023 11:41:10 +0200
|
||||
Subject: [PATCH] xfs: set bnobt/cntbt numrecs correctly when formatting new
|
||||
AGs
|
||||
|
||||
Source kernel commit: 8e698ee72c4ecbbf18264568eb310875839fd601
|
||||
|
||||
Through generic/300, I discovered that mkfs.xfs creates corrupt
|
||||
filesystems when given these parameters:
|
||||
|
||||
# mkfs.xfs -d size=512M /dev/sda -f -d su=128k,sw=4 --unsupported
|
||||
Filesystems formatted with --unsupported are not supported!!
|
||||
meta-data=/dev/sda isize=512 agcount=8, agsize=16352 blks
|
||||
= sectsz=512 attr=2, projid32bit=1
|
||||
= crc=1 finobt=1, sparse=1, rmapbt=1
|
||||
= reflink=1 bigtime=1 inobtcount=1 nrext64=1
|
||||
data = bsize=4096 blocks=130816, imaxpct=25
|
||||
= sunit=32 swidth=128 blks
|
||||
naming =version 2 bsize=4096 ascii-ci=0, ftype=1
|
||||
log =internal log bsize=4096 blocks=8192, version=2
|
||||
= sectsz=512 sunit=32 blks, lazy-count=1
|
||||
realtime =none extsz=4096 blocks=0, rtextents=0
|
||||
= rgcount=0 rgsize=0 blks
|
||||
Discarding blocks...Done.
|
||||
# xfs_repair -n /dev/sda
|
||||
Phase 1 - find and verify superblock...
|
||||
- reporting progress in intervals of 15 minutes
|
||||
Phase 2 - using internal log
|
||||
- zero log...
|
||||
- 16:30:50: zeroing log - 16320 of 16320 blocks done
|
||||
- scan filesystem freespace and inode maps...
|
||||
agf_freeblks 25, counted 0 in ag 4
|
||||
sb_fdblocks 8823, counted 8798
|
||||
|
||||
The root cause of this problem is the numrecs handling in
|
||||
xfs_freesp_init_recs, which is used to initialize a new AG. Prior to
|
||||
calling the function, we set up the new bnobt block with numrecs == 1
|
||||
and rely on _freesp_init_recs to format that new record. If the last
|
||||
record created has a blockcount of zero, then it sets numrecs = 0.
|
||||
|
||||
That last bit isn't correct if the AG contains the log, the start of the
|
||||
log is not immediately after the initial blocks due to stripe alignment,
|
||||
and the end of the log is perfectly aligned with the end of the AG. For
|
||||
this case, we actually formatted a single bnobt record to handle the
|
||||
free space before the start of the (stripe aligned) log, and incremented
|
||||
arec to try to format a second record. That second record turned out to
|
||||
be unnecessary, so what we really want is to leave numrecs at 1.
|
||||
|
||||
The numrecs handling itself is overly complicated because a different
|
||||
function sets numrecs == 1. Change the bnobt creation code to start
|
||||
with numrecs set to zero and only increment it after successfully
|
||||
formatting a free space extent into the btree block.
|
||||
|
||||
Fixes: f327a00745ff ("xfs: account for log space when formatting new AGs")
|
||||
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Dave Chinner <dchinner@redhat.com>
|
||||
Signed-off-by: Dave Chinner <david@fromorbit.com>
|
||||
Signed-off-by: Carlos Maiolino <cem@kernel.org>
|
||||
Signed-off-by: Pavel Reichl <preichl@redhat.com>
|
||||
---
|
||||
libxfs/xfs_ag.c | 19 +++++++++----------
|
||||
1 file changed, 9 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c
|
||||
index e3465e06..5d269312 100644
|
||||
--- a/libxfs/xfs_ag.c
|
||||
+++ b/libxfs/xfs_ag.c
|
||||
@@ -493,10 +493,12 @@ xfs_freesp_init_recs(
|
||||
ASSERT(start >= mp->m_ag_prealloc_blocks);
|
||||
if (start != mp->m_ag_prealloc_blocks) {
|
||||
/*
|
||||
- * Modify first record to pad stripe align of log
|
||||
+ * Modify first record to pad stripe align of log and
|
||||
+ * bump the record count.
|
||||
*/
|
||||
arec->ar_blockcount = cpu_to_be32(start -
|
||||
mp->m_ag_prealloc_blocks);
|
||||
+ be16_add_cpu(&block->bb_numrecs, 1);
|
||||
nrec = arec + 1;
|
||||
|
||||
/*
|
||||
@@ -507,7 +509,6 @@ xfs_freesp_init_recs(
|
||||
be32_to_cpu(arec->ar_startblock) +
|
||||
be32_to_cpu(arec->ar_blockcount));
|
||||
arec = nrec;
|
||||
- be16_add_cpu(&block->bb_numrecs, 1);
|
||||
}
|
||||
/*
|
||||
* Change record start to after the internal log
|
||||
@@ -516,15 +517,13 @@ xfs_freesp_init_recs(
|
||||
}
|
||||
|
||||
/*
|
||||
- * Calculate the record block count and check for the case where
|
||||
- * the log might have consumed all available space in the AG. If
|
||||
- * so, reset the record count to 0 to avoid exposure of an invalid
|
||||
- * record start block.
|
||||
+ * Calculate the block count of this record; if it is nonzero,
|
||||
+ * increment the record count.
|
||||
*/
|
||||
arec->ar_blockcount = cpu_to_be32(id->agsize -
|
||||
be32_to_cpu(arec->ar_startblock));
|
||||
- if (!arec->ar_blockcount)
|
||||
- block->bb_numrecs = 0;
|
||||
+ if (arec->ar_blockcount)
|
||||
+ be16_add_cpu(&block->bb_numrecs, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -536,7 +535,7 @@ xfs_bnoroot_init(
|
||||
struct xfs_buf *bp,
|
||||
struct aghdr_init_data *id)
|
||||
{
|
||||
- xfs_btree_init_block(mp, bp, XFS_BTNUM_BNO, 0, 1, id->agno);
|
||||
+ xfs_btree_init_block(mp, bp, XFS_BTNUM_BNO, 0, 0, id->agno);
|
||||
xfs_freesp_init_recs(mp, bp, id);
|
||||
}
|
||||
|
||||
@@ -546,7 +545,7 @@ xfs_cntroot_init(
|
||||
struct xfs_buf *bp,
|
||||
struct aghdr_init_data *id)
|
||||
{
|
||||
- xfs_btree_init_block(mp, bp, XFS_BTNUM_CNT, 0, 1, id->agno);
|
||||
+ xfs_btree_init_block(mp, bp, XFS_BTNUM_CNT, 0, 0, id->agno);
|
||||
xfs_freesp_init_recs(mp, bp, id);
|
||||
}
|
||||
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,178 +0,0 @@
|
||||
From 10a01bcdd748773c185255516a72e75a71295bd4 Mon Sep 17 00:00:00 2001
|
||||
From: "Darrick J. Wong" <djwong@kernel.org>
|
||||
Date: Thu, 15 Jun 2023 09:11:04 -0700
|
||||
Subject: [PATCH] xfs_db: fix metadump name obfuscation for ascii-ci
|
||||
filesystems
|
||||
|
||||
Now that we've stabilized the dirent hash function for ascii-ci
|
||||
filesystems, adapt the metadump name obfuscation code to detect when
|
||||
it's obfuscating a directory entry name on an ascii-ci filesystem and
|
||||
spit out names that actually have the same hash.
|
||||
|
||||
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
|
||||
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
|
||||
Signed-off-by: Carlos Maiolino <cem@kernel.org>
|
||||
Signed-off-by: Pavel Reichl <preichl@redhat.com>
|
||||
---
|
||||
db/metadump.c | 82 +++++++++++++++++++++++++++++++++++++++++++++------
|
||||
1 file changed, 73 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/db/metadump.c b/db/metadump.c
|
||||
index 317ff728..9ccee0b7 100644
|
||||
--- a/db/metadump.c
|
||||
+++ b/db/metadump.c
|
||||
@@ -817,13 +817,17 @@ static void
|
||||
obfuscate_name(
|
||||
xfs_dahash_t hash,
|
||||
size_t name_len,
|
||||
- unsigned char *name)
|
||||
+ unsigned char *name,
|
||||
+ bool is_dirent)
|
||||
{
|
||||
- unsigned char *newp = name;
|
||||
+ unsigned char *oldname = NULL;
|
||||
+ unsigned char *newp;
|
||||
int i;
|
||||
- xfs_dahash_t new_hash = 0;
|
||||
+ xfs_dahash_t new_hash;
|
||||
unsigned char *first;
|
||||
unsigned char high_bit;
|
||||
+ int tries = 0;
|
||||
+ bool is_ci_name = is_dirent && xfs_has_asciici(mp);
|
||||
int shift;
|
||||
|
||||
/*
|
||||
@@ -836,6 +840,26 @@ obfuscate_name(
|
||||
if (name_len < 5)
|
||||
return;
|
||||
|
||||
+ if (is_ci_name) {
|
||||
+ oldname = malloc(name_len);
|
||||
+ if (!oldname)
|
||||
+ return;
|
||||
+ memcpy(oldname, name, name_len);
|
||||
+ }
|
||||
+
|
||||
+again:
|
||||
+ newp = name;
|
||||
+ new_hash = 0;
|
||||
+
|
||||
+ /*
|
||||
+ * If we cannot generate a ci-compatible obfuscated name after 1000
|
||||
+ * tries, don't bother obfuscating the name.
|
||||
+ */
|
||||
+ if (tries++ > 1000) {
|
||||
+ memcpy(name, oldname, name_len);
|
||||
+ goto out_free;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* The beginning of the obfuscated name can be pretty much
|
||||
* anything, so fill it in with random characters.
|
||||
@@ -843,7 +867,11 @@ obfuscate_name(
|
||||
*/
|
||||
for (i = 0; i < name_len - 5; i++) {
|
||||
*newp = random_filename_char();
|
||||
- new_hash = *newp ^ rol32(new_hash, 7);
|
||||
+ if (is_ci_name)
|
||||
+ new_hash = xfs_ascii_ci_xfrm(*newp) ^
|
||||
+ rol32(new_hash, 7);
|
||||
+ else
|
||||
+ new_hash = *newp ^ rol32(new_hash, 7);
|
||||
newp++;
|
||||
}
|
||||
|
||||
@@ -867,6 +895,17 @@ obfuscate_name(
|
||||
high_bit = 0x80;
|
||||
} else
|
||||
high_bit = 0;
|
||||
+
|
||||
+ /*
|
||||
+ * If ascii-ci is enabled, uppercase characters are converted
|
||||
+ * to lowercase characters while computing the name hash. If
|
||||
+ * any of the necessary correction bytes are uppercase, the
|
||||
+ * hash of the new name will not match. Try again with a
|
||||
+ * different prefix.
|
||||
+ */
|
||||
+ if (is_ci_name && xfs_ascii_ci_need_xfrm(*newp))
|
||||
+ goto again;
|
||||
+
|
||||
ASSERT(!is_invalid_char(*newp));
|
||||
newp++;
|
||||
}
|
||||
@@ -880,8 +919,15 @@ obfuscate_name(
|
||||
*/
|
||||
if (high_bit) {
|
||||
*first ^= 0x10;
|
||||
+
|
||||
+ if (is_ci_name && xfs_ascii_ci_need_xfrm(*first))
|
||||
+ goto again;
|
||||
+
|
||||
ASSERT(!is_invalid_char(*first));
|
||||
}
|
||||
+
|
||||
+out_free:
|
||||
+ free(oldname);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1177,6 +1223,24 @@ handle_duplicate_name(xfs_dahash_t hash, size_t name_len, unsigned char *name)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static inline xfs_dahash_t
|
||||
+dirattr_hashname(
|
||||
+ bool is_dirent,
|
||||
+ const uint8_t *name,
|
||||
+ int namelen)
|
||||
+{
|
||||
+ if (is_dirent) {
|
||||
+ struct xfs_name xname = {
|
||||
+ .name = name,
|
||||
+ .len = namelen,
|
||||
+ };
|
||||
+
|
||||
+ return libxfs_dir2_hashname(mp, &xname);
|
||||
+ }
|
||||
+
|
||||
+ return libxfs_da_hashname(name, namelen);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
generate_obfuscated_name(
|
||||
xfs_ino_t ino,
|
||||
@@ -1205,9 +1269,9 @@ generate_obfuscated_name(
|
||||
|
||||
/* Obfuscate the name (if possible) */
|
||||
|
||||
- hash = libxfs_da_hashname(name, namelen);
|
||||
- obfuscate_name(hash, namelen, name);
|
||||
- ASSERT(hash == libxfs_da_hashname(name, namelen));
|
||||
+ hash = dirattr_hashname(ino != 0, name, namelen);
|
||||
+ obfuscate_name(hash, namelen, name, ino != 0);
|
||||
+ ASSERT(hash == dirattr_hashname(ino != 0, name, namelen));
|
||||
|
||||
/*
|
||||
* Make sure the name is not something already seen. If we
|
||||
@@ -1320,7 +1384,7 @@ obfuscate_path_components(
|
||||
/* last (or single) component */
|
||||
namelen = strnlen((char *)comp, len);
|
||||
hash = libxfs_da_hashname(comp, namelen);
|
||||
- obfuscate_name(hash, namelen, comp);
|
||||
+ obfuscate_name(hash, namelen, comp, false);
|
||||
ASSERT(hash == libxfs_da_hashname(comp, namelen));
|
||||
break;
|
||||
}
|
||||
@@ -1332,7 +1396,7 @@ obfuscate_path_components(
|
||||
continue;
|
||||
}
|
||||
hash = libxfs_da_hashname(comp, namelen);
|
||||
- obfuscate_name(hash, namelen, comp);
|
||||
+ obfuscate_name(hash, namelen, comp, false);
|
||||
ASSERT(hash == libxfs_da_hashname(comp, namelen));
|
||||
comp += namelen + 1;
|
||||
len -= namelen + 1;
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,56 +0,0 @@
|
||||
From cb8c70b017e30d4004373300bce488a9687166ac Mon Sep 17 00:00:00 2001
|
||||
From: "Darrick J. Wong" <djwong@kernel.org>
|
||||
Date: Mon, 5 Jun 2023 08:36:38 -0700
|
||||
Subject: [PATCH] xfs_db: move obfuscate_name assertion to callers
|
||||
|
||||
Currently, obfuscate_name asserts that the hash of the new name is the
|
||||
same as the old name. To enable bug fixes in the next patch, move this
|
||||
assertion to the callers.
|
||||
|
||||
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
Signed-off-by: Carlos Maiolino <cem@kernel.org>
|
||||
Signed-off-by: Pavel Reichl <preichl@redhat.com>
|
||||
---
|
||||
db/metadump.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/db/metadump.c b/db/metadump.c
|
||||
index 27d1df43..317ff728 100644
|
||||
--- a/db/metadump.c
|
||||
+++ b/db/metadump.c
|
||||
@@ -882,7 +882,6 @@ obfuscate_name(
|
||||
*first ^= 0x10;
|
||||
ASSERT(!is_invalid_char(*first));
|
||||
}
|
||||
- ASSERT(libxfs_da_hashname(name, name_len) == hash);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1208,6 +1207,7 @@ generate_obfuscated_name(
|
||||
|
||||
hash = libxfs_da_hashname(name, namelen);
|
||||
obfuscate_name(hash, namelen, name);
|
||||
+ ASSERT(hash == libxfs_da_hashname(name, namelen));
|
||||
|
||||
/*
|
||||
* Make sure the name is not something already seen. If we
|
||||
@@ -1321,6 +1321,7 @@ obfuscate_path_components(
|
||||
namelen = strnlen((char *)comp, len);
|
||||
hash = libxfs_da_hashname(comp, namelen);
|
||||
obfuscate_name(hash, namelen, comp);
|
||||
+ ASSERT(hash == libxfs_da_hashname(comp, namelen));
|
||||
break;
|
||||
}
|
||||
namelen = slash - (char *)comp;
|
||||
@@ -1332,6 +1333,7 @@ obfuscate_path_components(
|
||||
}
|
||||
hash = libxfs_da_hashname(comp, namelen);
|
||||
obfuscate_name(hash, namelen, comp);
|
||||
+ ASSERT(hash == libxfs_da_hashname(comp, namelen));
|
||||
comp += namelen + 1;
|
||||
len -= namelen + 1;
|
||||
}
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,41 +0,0 @@
|
||||
From aca02624815ca47c6fd4cafdb0aeaad641ca1915 Mon Sep 17 00:00:00 2001
|
||||
From: "Darrick J. Wong" <djwong@kernel.org>
|
||||
Date: Mon, 5 Jun 2023 08:37:24 -0700
|
||||
Subject: [PATCH] xfs_repair: don't add junked entries to the rebuilt directory
|
||||
|
||||
If a directory contains multiple entries with the same name, we create
|
||||
separate objects in the directory hashtab for each dirent. The first
|
||||
one has p->junkit==0, but the subsequent ones have p->junkit==1.
|
||||
Because these are duplicate names that are not garbage, the first
|
||||
character of p->name.name is not set to a slash.
|
||||
|
||||
Don't add these subsequent hashtab entries to the rebuilt directory.
|
||||
|
||||
Found by running xfs/155 with the parent pointers patchset enabled.
|
||||
|
||||
Fixes: 33165ec3b4b ("Fix dirv2 rebuild in phase6 Merge of master-melb:xfs-cmds:26664a by kenmcd.")
|
||||
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Pavel Reichl <preichl@redhat.com>
|
||||
Signed-off-by: Carlos Maiolino <cem@kernel.org>
|
||||
Signed-off-by: Pavel Reichl <preichl@redhat.com>
|
||||
---
|
||||
repair/phase6.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repair/phase6.c b/repair/phase6.c
|
||||
index 25bbcd10..3870c5c9 100644
|
||||
--- a/repair/phase6.c
|
||||
+++ b/repair/phase6.c
|
||||
@@ -1316,7 +1316,8 @@ longform_dir2_rebuild(
|
||||
/* go through the hash list and re-add the inodes */
|
||||
|
||||
for (p = hashtab->first; p; p = p->nextbyorder) {
|
||||
-
|
||||
+ if (p->junkit)
|
||||
+ continue;
|
||||
if (p->name.name[0] == '/' || (p->name.name[0] == '.' &&
|
||||
(p->name.len == 1 || (p->name.len == 2 &&
|
||||
p->name.name[1] == '.'))))
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,57 +0,0 @@
|
||||
From 67f541056f4dd3ba1ccc5d11464d67afdab0f2a3 Mon Sep 17 00:00:00 2001
|
||||
From: "Darrick J. Wong" <djwong@kernel.org>
|
||||
Date: Mon, 5 Jun 2023 08:37:39 -0700
|
||||
Subject: [PATCH] xfs_repair: don't spray correcting imap all by itself
|
||||
|
||||
In xfs/155, I occasionally see this in the xfs_repair output:
|
||||
|
||||
correcting imap
|
||||
correcting imap
|
||||
correcting imap
|
||||
...
|
||||
|
||||
This is completely useless, since we don't actually log which inode
|
||||
prompted this message. This logic has been here for a really long time,
|
||||
but ... I can't make heads nor tails of it. If we're running in verbose
|
||||
or dry-run mode, then print the inode number, but not if we're running
|
||||
in fixit mode?
|
||||
|
||||
A few lines later, if we're running in verbose dry-run mode, we print
|
||||
"correcting imap" even though we're not going to write anything.
|
||||
|
||||
If we get here, the inode looks like it's in use, but the inode index
|
||||
says it isn't. This is a corruption, so either we fix it or we say that
|
||||
we would fix it.
|
||||
|
||||
Fixes: 6c39a3cbda3 ("Don't trash lost+found in phase 4 Merge of master-melb:xfs-cmds:29144a by kenmcd.")
|
||||
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
|
||||
Signed-off-by: Carlos Maiolino <cem@kernel.org>
|
||||
Signed-off-by: Pavel Reichl <preichl@redhat.com>
|
||||
---
|
||||
repair/dino_chunks.c | 6 ++----
|
||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/repair/dino_chunks.c b/repair/dino_chunks.c
|
||||
index 0e09132b..0841e65b 100644
|
||||
--- a/repair/dino_chunks.c
|
||||
+++ b/repair/dino_chunks.c
|
||||
@@ -871,13 +871,11 @@ next_readbuf:
|
||||
*/
|
||||
if (is_used) {
|
||||
if (is_inode_free(ino_rec, irec_offset)) {
|
||||
- if (verbose || no_modify) {
|
||||
- do_warn(
|
||||
+ do_warn(
|
||||
_("imap claims in-use inode %" PRIu64 " is free, "),
|
||||
ino);
|
||||
- }
|
||||
|
||||
- if (verbose || !no_modify)
|
||||
+ if (!no_modify)
|
||||
do_warn(_("correcting imap\n"));
|
||||
else
|
||||
do_warn(_("would correct imap\n"));
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,39 +0,0 @@
|
||||
From 1e12a0751b99efd48cda501258e16f00bef9d13d Mon Sep 17 00:00:00 2001
|
||||
From: "Darrick J. Wong" <djwong@kernel.org>
|
||||
Date: Mon, 5 Jun 2023 08:38:01 -0700
|
||||
Subject: [PATCH] xfs_repair: fix messaging when fixing imap due to sparse
|
||||
cluster
|
||||
|
||||
This logic is wrong -- if we're in verbose dry-run mode, we do NOT want
|
||||
to say that we're correcting the imap. Otherwise, we print things like:
|
||||
|
||||
imap claims inode XXX is present, but inode cluster is sparse,
|
||||
|
||||
But then we can erroneously tell the user that we would correct the
|
||||
imap when in fact we /are/ correcting it.
|
||||
|
||||
Fixes: f4ff8086586 ("xfs_repair: don't crash on partially sparse inode clusters")
|
||||
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
|
||||
Signed-off-by: Carlos Maiolino <cem@kernel.org>
|
||||
Signed-off-by: Pavel Reichl <preichl@redhat.com>
|
||||
---
|
||||
repair/dino_chunks.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repair/dino_chunks.c b/repair/dino_chunks.c
|
||||
index 0841e65b1844..64ce2a323c8d 100644
|
||||
--- a/repair/dino_chunks.c
|
||||
+++ b/repair/dino_chunks.c
|
||||
@@ -834,7 +834,7 @@ next_readbuf:
|
||||
do_warn(
|
||||
_("imap claims inode %" PRIu64 " is present, but inode cluster is sparse, "),
|
||||
ino);
|
||||
- if (verbose || !no_modify)
|
||||
+ if (!no_modify)
|
||||
do_warn(_("correcting imap\n"));
|
||||
else
|
||||
do_warn(_("would correct imap\n"));
|
||||
--
|
||||
2.41.0
|
||||
|
@ -1,96 +0,0 @@
|
||||
From d159552bbb05de6998388b960f50e5e0012828ea Mon Sep 17 00:00:00 2001
|
||||
From: "Darrick J. Wong" <djwong@kernel.org>
|
||||
Date: Mon, 5 Jun 2023 08:37:50 -0700
|
||||
Subject: [PATCH] xfs_repair: fix messaging when shortform_dir2_junk is called
|
||||
|
||||
This function is called when we've decide to junk a shortform directory
|
||||
entry. This is obviously corruption of some kind, so we should always
|
||||
say something, particularly if we're in !verbose repair mode.
|
||||
Otherwise, if we're in non-verbose repair mode, we print things like:
|
||||
|
||||
entry "FOO" in shortform directory XXX references non-existent inode YYY
|
||||
|
||||
Without telling the sysadmin that we're removing the dirent.
|
||||
|
||||
Fixes: aaca101b1ae ("xfs_repair: add support for validating dirent ftype field")
|
||||
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
|
||||
Signed-off-by: Carlos Maiolino <cem@kernel.org>
|
||||
Signed-off-by: Pavel Reichl <preichl@redhat.com>
|
||||
---
|
||||
repair/phase6.c | 17 +++++++----------
|
||||
1 file changed, 7 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/repair/phase6.c b/repair/phase6.c
|
||||
index c6418534..be10d9b7 100644
|
||||
--- a/repair/phase6.c
|
||||
+++ b/repair/phase6.c
|
||||
@@ -2440,10 +2440,7 @@ shortform_dir2_junk(
|
||||
*/
|
||||
(*index)--;
|
||||
|
||||
- if (verbose)
|
||||
- do_warn(_("junking entry\n"));
|
||||
- else
|
||||
- do_warn("\n");
|
||||
+ do_warn(_("junking entry\n"));
|
||||
return sfep;
|
||||
}
|
||||
|
||||
@@ -2592,7 +2589,7 @@ shortform_dir2_entry_check(
|
||||
|
||||
if (irec == NULL) {
|
||||
do_warn(
|
||||
- _("entry \"%s\" in shortform directory %" PRIu64 " references non-existent inode %" PRIu64 "\n"),
|
||||
+ _("entry \"%s\" in shortform directory %" PRIu64 " references non-existent inode %" PRIu64 ", "),
|
||||
fname, ino, lino);
|
||||
next_sfep = shortform_dir2_junk(mp, sfp, sfep, lino,
|
||||
&max_size, &i, &bytes_deleted,
|
||||
@@ -2609,7 +2606,7 @@ shortform_dir2_entry_check(
|
||||
*/
|
||||
if (is_inode_free(irec, ino_offset)) {
|
||||
do_warn(
|
||||
- _("entry \"%s\" in shortform directory inode %" PRIu64 " points to free inode %" PRIu64 "\n"),
|
||||
+ _("entry \"%s\" in shortform directory inode %" PRIu64 " points to free inode %" PRIu64 ", "),
|
||||
fname, ino, lino);
|
||||
next_sfep = shortform_dir2_junk(mp, sfp, sfep, lino,
|
||||
&max_size, &i, &bytes_deleted,
|
||||
@@ -2625,7 +2622,7 @@ shortform_dir2_entry_check(
|
||||
*/
|
||||
if (!inode_isadir(irec, ino_offset)) {
|
||||
do_warn(
|
||||
- _("%s (ino %" PRIu64 ") in root (%" PRIu64 ") is not a directory"),
|
||||
+ _("%s (ino %" PRIu64 ") in root (%" PRIu64 ") is not a directory, "),
|
||||
ORPHANAGE, lino, ino);
|
||||
next_sfep = shortform_dir2_junk(mp, sfp, sfep,
|
||||
lino, &max_size, &i,
|
||||
@@ -2647,7 +2644,7 @@ shortform_dir2_entry_check(
|
||||
lino, sfep->namelen, sfep->name,
|
||||
libxfs_dir2_sf_get_ftype(mp, sfep))) {
|
||||
do_warn(
|
||||
-_("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is a duplicate name"),
|
||||
+_("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is a duplicate name, "),
|
||||
fname, lino, ino);
|
||||
next_sfep = shortform_dir2_junk(mp, sfp, sfep, lino,
|
||||
&max_size, &i, &bytes_deleted,
|
||||
@@ -2672,7 +2669,7 @@ _("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is a duplicate name"),
|
||||
if (is_inode_reached(irec, ino_offset)) {
|
||||
do_warn(
|
||||
_("entry \"%s\" in directory inode %" PRIu64
|
||||
- " references already connected inode %" PRIu64 ".\n"),
|
||||
+ " references already connected inode %" PRIu64 ", "),
|
||||
fname, ino, lino);
|
||||
next_sfep = shortform_dir2_junk(mp, sfp, sfep,
|
||||
lino, &max_size, &i,
|
||||
@@ -2696,7 +2693,7 @@ _("entry \"%s\" (ino %" PRIu64 ") in dir %" PRIu64 " is a duplicate name"),
|
||||
do_warn(
|
||||
_("entry \"%s\" in directory inode %" PRIu64
|
||||
" not consistent with .. value (%" PRIu64
|
||||
- ") in inode %" PRIu64 ",\n"),
|
||||
+ ") in inode %" PRIu64 ", "),
|
||||
fname, ino, parent, lino);
|
||||
next_sfep = shortform_dir2_junk(mp, sfp, sfep,
|
||||
lino, &max_size, &i,
|
||||
--
|
||||
2.41.0
|
||||
|
@ -0,0 +1,7 @@
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iIUEABYIAC0WIQT6QG4gav94c4l8aGS0VhjDaiT9IwUCZLfVMw8cY2VtQGtlcm5l
|
||||
bC5vcmcACgkQtFYYw2ok/SNKPwEA6fsxp1TRbPXQn6a605fU3cE6WjcqDLej3zYa
|
||||
lx91BnABAKIWP14Rd7KPbCH4ezAPydFZxSn26trKqPxzAFOZ/skP
|
||||
=mkU4
|
||||
-----END PGP SIGNATURE-----
|
@ -0,0 +1,57 @@
|
||||
From d096b26c33a858ad88db98306057da67e6d18611 Mon Sep 17 00:00:00 2001
|
||||
From: Dave Chinner <dchinner@redhat.com>
|
||||
Date: Wed, 6 Sep 2023 13:52:48 +0200
|
||||
Subject: [PATCH] xfs: fix bounds check in xfs_defer_agfl_block()
|
||||
|
||||
Source kernel commit: 2bed0d82c2f78b91a0a9a5a73da57ee883a0c070
|
||||
|
||||
Need to happen before we allocate and then leak the xefi. Found by
|
||||
coverity via an xfsprogs libxfs scan.
|
||||
|
||||
[djwong: This also fixes the type of the @agbno argument.]
|
||||
|
||||
Fixes: 7dfee17b13e5 ("xfs: validate block number being freed before adding to xefi")
|
||||
Signed-off-by: Dave Chinner <dchinner@redhat.com>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Signed-off-by: Carlos Maiolino <cem@kernel.org>
|
||||
---
|
||||
libxfs/xfs_alloc.c | 11 ++++++-----
|
||||
1 file changed, 6 insertions(+), 5 deletions(-)
|
||||
|
||||
Index: xfsprogs-6.4.0/libxfs/xfs_alloc.c
|
||||
===================================================================
|
||||
--- xfsprogs-6.4.0.orig/libxfs/xfs_alloc.c
|
||||
+++ xfsprogs-6.4.0/libxfs/xfs_alloc.c
|
||||
@@ -2431,24 +2431,25 @@ static int
|
||||
xfs_defer_agfl_block(
|
||||
struct xfs_trans *tp,
|
||||
xfs_agnumber_t agno,
|
||||
- xfs_fsblock_t agbno,
|
||||
+ xfs_agblock_t agbno,
|
||||
struct xfs_owner_info *oinfo)
|
||||
{
|
||||
struct xfs_mount *mp = tp->t_mountp;
|
||||
struct xfs_extent_free_item *xefi;
|
||||
+ xfs_fsblock_t fsbno = XFS_AGB_TO_FSB(mp, agno, agbno);
|
||||
|
||||
ASSERT(xfs_extfree_item_cache != NULL);
|
||||
ASSERT(oinfo != NULL);
|
||||
|
||||
+ if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbno(mp, fsbno)))
|
||||
+ return -EFSCORRUPTED;
|
||||
+
|
||||
xefi = kmem_cache_zalloc(xfs_extfree_item_cache,
|
||||
GFP_KERNEL | __GFP_NOFAIL);
|
||||
- xefi->xefi_startblock = XFS_AGB_TO_FSB(mp, agno, agbno);
|
||||
+ xefi->xefi_startblock = fsbno;
|
||||
xefi->xefi_blockcount = 1;
|
||||
xefi->xefi_owner = oinfo->oi_owner;
|
||||
|
||||
- if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbno(mp, xefi->xefi_startblock)))
|
||||
- return -EFSCORRUPTED;
|
||||
-
|
||||
trace_xfs_agfl_free_defer(mp, agno, 0, agbno, 1);
|
||||
|
||||
xfs_extent_free_get_group(mp, xefi);
|
@ -0,0 +1,102 @@
|
||||
From a21daa3a739194b929de644779c359949390d467 Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Albershteyn <aalbersh@redhat.com>
|
||||
Date: Wed, 17 Apr 2024 18:19:30 +0200
|
||||
Subject: [PATCH] xfs_db: add helper for flist_find_type for clearer field
|
||||
matching
|
||||
|
||||
Make flist_find_type() more readable by unloading field type
|
||||
matching to the helper.
|
||||
|
||||
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
|
||||
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
---
|
||||
db/flist.c | 60 ++++++++++++++++++++++++++++++++++--------------------
|
||||
1 file changed, 38 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/db/flist.c b/db/flist.c
|
||||
index 0a6cc5fc..ab0a0f13 100644
|
||||
--- a/db/flist.c
|
||||
+++ b/db/flist.c
|
||||
@@ -400,6 +400,40 @@ flist_split(
|
||||
return v;
|
||||
}
|
||||
|
||||
+static flist_t *
|
||||
+flist_field_match(
|
||||
+ const field_t *field,
|
||||
+ fldt_t type,
|
||||
+ void *obj,
|
||||
+ int startoff)
|
||||
+{
|
||||
+ flist_t *fl;
|
||||
+ int count;
|
||||
+ const ftattr_t *fa;
|
||||
+ flist_t *nfl;
|
||||
+
|
||||
+ fl = flist_make(field->name);
|
||||
+ fl->fld = field;
|
||||
+ if (field->ftyp == type)
|
||||
+ return fl;
|
||||
+ count = fcount(field, obj, startoff);
|
||||
+ if (!count)
|
||||
+ goto out;
|
||||
+ fa = &ftattrtab[field->ftyp];
|
||||
+ if (!fa->subfld)
|
||||
+ goto out;
|
||||
+
|
||||
+ nfl = flist_find_ftyp(fa->subfld, type, obj, startoff);
|
||||
+ if (nfl) {
|
||||
+ fl->child = nfl;
|
||||
+ return fl;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ flist_free(fl);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Given a set of fields, scan for a field of the given type.
|
||||
* Return an flist leading to the first found field
|
||||
@@ -413,33 +447,15 @@ flist_find_ftyp(
|
||||
void *obj,
|
||||
int startoff)
|
||||
{
|
||||
- flist_t *fl;
|
||||
const field_t *f;
|
||||
- int count;
|
||||
- const ftattr_t *fa;
|
||||
+ flist_t *fl;
|
||||
|
||||
for (f = fields; f->name; f++) {
|
||||
- fl = flist_make(f->name);
|
||||
- fl->fld = f;
|
||||
- if (f->ftyp == type)
|
||||
+ fl = flist_field_match(f, type, obj, startoff);
|
||||
+ if (fl)
|
||||
return fl;
|
||||
- count = fcount(f, obj, startoff);
|
||||
- if (!count) {
|
||||
- flist_free(fl);
|
||||
- continue;
|
||||
- }
|
||||
- fa = &ftattrtab[f->ftyp];
|
||||
- if (fa->subfld) {
|
||||
- flist_t *nfl;
|
||||
-
|
||||
- nfl = flist_find_ftyp(fa->subfld, type, obj, startoff);
|
||||
- if (nfl) {
|
||||
- fl->child = nfl;
|
||||
- return fl;
|
||||
- }
|
||||
- }
|
||||
- flist_free(fl);
|
||||
}
|
||||
+
|
||||
return NULL;
|
||||
}
|
||||
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,35 @@
|
||||
From 21dc682a3842eb7e4c79f7e511d840e708d7e757 Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Albershteyn <aalbersh@redhat.com>
|
||||
Date: Tue, 23 Apr 2024 14:36:14 +0200
|
||||
Subject: [PATCH] xfs_db: fix leak in flist_find_ftyp()
|
||||
|
||||
When count is zero fl reference is lost. Fix it by freeing the list.
|
||||
|
||||
Fixes: a0d79cb37a36 ("xfs_db: make flist_find_ftyp() to check for field existance on disk")
|
||||
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Bill O'Donnell <bodonnel@redhat.com>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
|
||||
---
|
||||
db/flist.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/db/flist.c b/db/flist.c
|
||||
index c81d229a..0a6cc5fc 100644
|
||||
--- a/db/flist.c
|
||||
+++ b/db/flist.c
|
||||
@@ -424,8 +424,10 @@ flist_find_ftyp(
|
||||
if (f->ftyp == type)
|
||||
return fl;
|
||||
count = fcount(f, obj, startoff);
|
||||
- if (!count)
|
||||
+ if (!count) {
|
||||
+ flist_free(fl);
|
||||
continue;
|
||||
+ }
|
||||
fa = &ftattrtab[f->ftyp];
|
||||
if (fa->subfld) {
|
||||
flist_t *nfl;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,56 @@
|
||||
From 9c6e9d8de2d236f630efdd6fddb6277e8664989b Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Albershteyn <aalbersh@redhat.com>
|
||||
Date: Tue, 23 Apr 2024 14:36:17 +0200
|
||||
Subject: [PATCH] xfs_fsr: convert fsrallfs to use time_t instead of int
|
||||
|
||||
Convert howlong argument to a time_t as it's truncated to int, but in
|
||||
practice this is not an issue as duration will never be this big.
|
||||
|
||||
Add check for howlong to fit into int (printf can use int format
|
||||
specifier). Even longer interval doesn't make much sense.
|
||||
|
||||
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
|
||||
---
|
||||
fsr/xfs_fsr.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
|
||||
index 3077d8f4..02d61ef9 100644
|
||||
--- a/fsr/xfs_fsr.c
|
||||
+++ b/fsr/xfs_fsr.c
|
||||
@@ -72,7 +72,7 @@ static int packfile(char *fname, char *tname, int fd,
|
||||
static void fsrdir(char *dirname);
|
||||
static int fsrfs(char *mntdir, xfs_ino_t ino, int targetrange);
|
||||
static void initallfs(char *mtab);
|
||||
-static void fsrallfs(char *mtab, int howlong, char *leftofffile);
|
||||
+static void fsrallfs(char *mtab, time_t howlong, char *leftofffile);
|
||||
static void fsrall_cleanup(int timeout);
|
||||
static int getnextents(int);
|
||||
int xfsrtextsize(int fd);
|
||||
@@ -165,6 +165,12 @@ main(int argc, char **argv)
|
||||
break;
|
||||
case 't':
|
||||
howlong = atoi(optarg);
|
||||
+ if (howlong > INT_MAX) {
|
||||
+ fprintf(stderr,
|
||||
+ _("%s: the maximum runtime is %d seconds.\n"),
|
||||
+ optarg, INT_MAX);
|
||||
+ exit(1);
|
||||
+ }
|
||||
break;
|
||||
case 'f':
|
||||
leftofffile = optarg;
|
||||
@@ -387,7 +393,7 @@ initallfs(char *mtab)
|
||||
}
|
||||
|
||||
static void
|
||||
-fsrallfs(char *mtab, int howlong, char *leftofffile)
|
||||
+fsrallfs(char *mtab, time_t howlong, char *leftofffile)
|
||||
{
|
||||
int fd;
|
||||
int error;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,64 @@
|
||||
From 652f8066b7ca7dc1e08c2c40cdd9ba593a9de568 Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Albershteyn <aalbersh@redhat.com>
|
||||
Date: Wed, 17 Apr 2024 18:19:29 +0200
|
||||
Subject: [PATCH] xfs_fsr: replace atoi() with strtol()
|
||||
|
||||
Replace atoi() which silently fails with strtol() and report the
|
||||
error.
|
||||
|
||||
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
|
||||
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
---
|
||||
fsr/xfs_fsr.c | 26 +++++++++++++++++++++++---
|
||||
1 file changed, 23 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
|
||||
index 02d61ef9..fdd37756 100644
|
||||
--- a/fsr/xfs_fsr.c
|
||||
+++ b/fsr/xfs_fsr.c
|
||||
@@ -164,7 +164,13 @@ main(int argc, char **argv)
|
||||
usage(1);
|
||||
break;
|
||||
case 't':
|
||||
- howlong = atoi(optarg);
|
||||
+ errno = 0;
|
||||
+ howlong = strtol(optarg, NULL, 10);
|
||||
+ if (errno) {
|
||||
+ fprintf(stderr, _("%s: invalid runtime: %s\n"),
|
||||
+ optarg, strerror(errno));
|
||||
+ exit(1);
|
||||
+ }
|
||||
if (howlong > INT_MAX) {
|
||||
fprintf(stderr,
|
||||
_("%s: the maximum runtime is %d seconds.\n"),
|
||||
@@ -179,10 +185,24 @@ main(int argc, char **argv)
|
||||
mtab = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
- argv_blksz_dio = atoi(optarg);
|
||||
+ errno = 0;
|
||||
+ argv_blksz_dio = strtol(optarg, NULL, 10);
|
||||
+ if (errno) {
|
||||
+ fprintf(stderr,
|
||||
+ _("%s: invalid block size: %s\n"),
|
||||
+ optarg, strerror(errno));
|
||||
+ exit(1);
|
||||
+ }
|
||||
break;
|
||||
case 'p':
|
||||
- npasses = atoi(optarg);
|
||||
+ errno = 0;
|
||||
+ npasses = strtol(optarg, NULL, 10);
|
||||
+ if (errno) {
|
||||
+ fprintf(stderr,
|
||||
+ _("%s: invalid number of passes: %s\n"),
|
||||
+ optarg, strerror(errno));
|
||||
+ exit(1);
|
||||
+ }
|
||||
break;
|
||||
case 'C':
|
||||
/* Testing opt: coerses frag count in result */
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,129 @@
|
||||
From d03b73d240dc7f5b4c02700c79c2c4eeeb94b08b Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Albershteyn <aalbersh@redhat.com>
|
||||
Date: Wed, 17 Apr 2024 18:19:31 +0200
|
||||
Subject: [PATCH] xfs_repair: catch strtol() errors
|
||||
|
||||
strtol() sets errno if string parsing. Abort and tell user which
|
||||
parameter is wrong.
|
||||
|
||||
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
|
||||
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
---
|
||||
repair/xfs_repair.c | 40 +++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 39 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
|
||||
index 2ceea87d..2fc89dac 100644
|
||||
--- a/repair/xfs_repair.c
|
||||
+++ b/repair/xfs_repair.c
|
||||
@@ -252,14 +252,22 @@ process_args(int argc, char **argv)
|
||||
if (!val)
|
||||
do_abort(
|
||||
_("-o bhash requires a parameter\n"));
|
||||
+ errno = 0;
|
||||
libxfs_bhash_size = (int)strtol(val, NULL, 0);
|
||||
+ if (errno)
|
||||
+ do_abort(
|
||||
+ _("-o bhash invalid parameter: %s\n"), strerror(errno));
|
||||
bhash_option_used = 1;
|
||||
break;
|
||||
case AG_STRIDE:
|
||||
if (!val)
|
||||
do_abort(
|
||||
_("-o ag_stride requires a parameter\n"));
|
||||
+ errno = 0;
|
||||
ag_stride = (int)strtol(val, NULL, 0);
|
||||
+ if (errno)
|
||||
+ do_abort(
|
||||
+ _("-o ag_stride invalid parameter: %s\n"), strerror(errno));
|
||||
break;
|
||||
case FORCE_GEO:
|
||||
if (val)
|
||||
@@ -272,19 +280,31 @@ process_args(int argc, char **argv)
|
||||
if (!val)
|
||||
do_abort(
|
||||
_("-o phase2_threads requires a parameter\n"));
|
||||
+ errno = 0;
|
||||
phase2_threads = (int)strtol(val, NULL, 0);
|
||||
+ if (errno)
|
||||
+ do_abort(
|
||||
+ _("-o phase2_threads invalid parameter: %s\n"), strerror(errno));
|
||||
break;
|
||||
case BLOAD_LEAF_SLACK:
|
||||
if (!val)
|
||||
do_abort(
|
||||
_("-o debug_bload_leaf_slack requires a parameter\n"));
|
||||
+ errno = 0;
|
||||
bload_leaf_slack = (int)strtol(val, NULL, 0);
|
||||
+ if (errno)
|
||||
+ do_abort(
|
||||
+ _("-o debug_bload_leaf_slack invalid parameter: %s\n"), strerror(errno));
|
||||
break;
|
||||
case BLOAD_NODE_SLACK:
|
||||
if (!val)
|
||||
do_abort(
|
||||
_("-o debug_bload_node_slack requires a parameter\n"));
|
||||
+ errno = 0;
|
||||
bload_node_slack = (int)strtol(val, NULL, 0);
|
||||
+ if (errno)
|
||||
+ do_abort(
|
||||
+ _("-o debug_bload_node_slack invalid parameter: %s\n"), strerror(errno));
|
||||
break;
|
||||
case NOQUOTA:
|
||||
quotacheck_skip();
|
||||
@@ -305,7 +325,11 @@ process_args(int argc, char **argv)
|
||||
if (!val)
|
||||
do_abort(
|
||||
_("-c lazycount requires a parameter\n"));
|
||||
+ errno = 0;
|
||||
lazy_count = (int)strtol(val, NULL, 0);
|
||||
+ if (errno)
|
||||
+ do_abort(
|
||||
+ _("-o lazycount invalid parameter: %s\n"), strerror(errno));
|
||||
convert_lazy_count = 1;
|
||||
break;
|
||||
case CONVERT_INOBTCOUNT:
|
||||
@@ -356,7 +380,11 @@ process_args(int argc, char **argv)
|
||||
if (bhash_option_used)
|
||||
do_abort(_("-m option cannot be used with "
|
||||
"-o bhash option\n"));
|
||||
+ errno = 0;
|
||||
max_mem_specified = strtol(optarg, NULL, 0);
|
||||
+ if (errno)
|
||||
+ do_abort(
|
||||
+ _("%s: invalid memory amount: %s\n"), optarg, strerror(errno));
|
||||
break;
|
||||
case 'L':
|
||||
zap_log = 1;
|
||||
@@ -377,7 +405,11 @@ process_args(int argc, char **argv)
|
||||
do_prefetch = 0;
|
||||
break;
|
||||
case 't':
|
||||
+ errno = 0;
|
||||
report_interval = strtol(optarg, NULL, 0);
|
||||
+ if (errno)
|
||||
+ do_abort(
|
||||
+ _("%s: invalid interval: %s\n"), optarg, strerror(errno));
|
||||
break;
|
||||
case 'e':
|
||||
report_corrected = true;
|
||||
@@ -397,8 +429,14 @@ process_args(int argc, char **argv)
|
||||
usage();
|
||||
|
||||
p = getenv("XFS_REPAIR_FAIL_AFTER_PHASE");
|
||||
- if (p)
|
||||
+ if (p) {
|
||||
+ errno = 0;
|
||||
fail_after_phase = (int)strtol(p, NULL, 0);
|
||||
+ if (errno)
|
||||
+ do_abort(
|
||||
+ _("%s: invalid phase in XFS_REPAIR_FAIL_AFTER_PHASE: %s\n"),
|
||||
+ p, strerror(errno));
|
||||
+ }
|
||||
}
|
||||
|
||||
void __attribute__((noreturn))
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,110 @@
|
||||
From fcac184ccf342a345ea8fe4d842415841af89e64 Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Albershteyn <aalbersh@redhat.com>
|
||||
Date: Tue, 23 Apr 2024 14:36:15 +0200
|
||||
Subject: [PATCH] xfs_repair: make duration take time_t
|
||||
|
||||
In most of the uses of duration() takes time_t instead of int.
|
||||
Convert the rest to use time_t and make duration() take time_t to
|
||||
not truncate it to int.
|
||||
|
||||
While at it remove unnecessary parentheses around 'elapsed'.
|
||||
|
||||
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
|
||||
---
|
||||
repair/globals.c | 2 +-
|
||||
repair/globals.h | 2 +-
|
||||
repair/progress.c | 9 +++++----
|
||||
repair/progress.h | 2 +-
|
||||
repair/xfs_repair.c | 2 +-
|
||||
5 files changed, 9 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/repair/globals.c b/repair/globals.c
|
||||
index a68929bd..24f720c4 100644
|
||||
--- a/repair/globals.c
|
||||
+++ b/repair/globals.c
|
||||
@@ -116,7 +116,7 @@ uint32_t sb_width;
|
||||
struct aglock *ag_locks;
|
||||
struct aglock rt_lock;
|
||||
|
||||
-int report_interval;
|
||||
+time_t report_interval;
|
||||
uint64_t *prog_rpt_done;
|
||||
|
||||
int ag_stride;
|
||||
diff --git a/repair/globals.h b/repair/globals.h
|
||||
index a67e384a..b83a8ae6 100644
|
||||
--- a/repair/globals.h
|
||||
+++ b/repair/globals.h
|
||||
@@ -160,7 +160,7 @@ struct aglock {
|
||||
extern struct aglock *ag_locks;
|
||||
extern struct aglock rt_lock;
|
||||
|
||||
-extern int report_interval;
|
||||
+extern time_t report_interval;
|
||||
extern uint64_t *prog_rpt_done;
|
||||
|
||||
extern int ag_stride;
|
||||
diff --git a/repair/progress.c b/repair/progress.c
|
||||
index f6c4d988..2ce36cef 100644
|
||||
--- a/repair/progress.c
|
||||
+++ b/repair/progress.c
|
||||
@@ -265,15 +265,16 @@ progress_rpt_thread (void *p)
|
||||
(current_phase == 7))) {
|
||||
/* for inode phase report % complete */
|
||||
do_log(
|
||||
- _("\t- %02d:%02d:%02d: Phase %d: elapsed time %s - processed %d %s per minute\n"),
|
||||
+ _("\t- %02d:%02d:%02d: Phase %d: elapsed time %s - processed %ld %s per minute\n"),
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec,
|
||||
current_phase, duration(elapsed, msgbuf),
|
||||
- (int) (60*sum/(elapsed)), *msgp->format->type);
|
||||
+ 60 * sum / elapsed, *msgp->format->type);
|
||||
do_log(
|
||||
_("\t- %02d:%02d:%02d: Phase %d: %" PRIu64 "%% done - estimated remaining time %s\n"),
|
||||
tmp->tm_hour, tmp->tm_min, tmp->tm_sec,
|
||||
current_phase, percent,
|
||||
- duration((int) ((*msgp->total - sum) * (elapsed)/sum), msgbuf));
|
||||
+ duration((*msgp->total - sum) * elapsed / sum,
|
||||
+ msgbuf));
|
||||
}
|
||||
|
||||
if (pthread_mutex_unlock(&msgp->mutex) != 0) {
|
||||
@@ -420,7 +421,7 @@ timestamp(int end, int phase, char *buf)
|
||||
}
|
||||
|
||||
char *
|
||||
-duration(int length, char *buf)
|
||||
+duration(time_t length, char *buf)
|
||||
{
|
||||
int sum;
|
||||
int weeks;
|
||||
diff --git a/repair/progress.h b/repair/progress.h
|
||||
index 2c1690db..9575df16 100644
|
||||
--- a/repair/progress.h
|
||||
+++ b/repair/progress.h
|
||||
@@ -38,7 +38,7 @@ extern void summary_report(void);
|
||||
extern int set_progress_msg(int report, uint64_t total);
|
||||
extern uint64_t print_final_rpt(void);
|
||||
extern char *timestamp(int end, int phase, char *buf);
|
||||
-extern char *duration(int val, char *buf);
|
||||
+extern char *duration(time_t val, char *buf);
|
||||
extern int do_parallel;
|
||||
|
||||
#define PROG_RPT_INC(a,b) if (ag_stride && prog_rpt_done) (a) += (b)
|
||||
diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
|
||||
index ba9d2833..2ceea87d 100644
|
||||
--- a/repair/xfs_repair.c
|
||||
+++ b/repair/xfs_repair.c
|
||||
@@ -377,7 +377,7 @@ process_args(int argc, char **argv)
|
||||
do_prefetch = 0;
|
||||
break;
|
||||
case 't':
|
||||
- report_interval = (int)strtol(optarg, NULL, 0);
|
||||
+ report_interval = strtol(optarg, NULL, 0);
|
||||
break;
|
||||
case 'e':
|
||||
report_corrected = true;
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,43 @@
|
||||
From c4dd920b8a8900046e0785e55a43c7190b82c59a Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Albershteyn <aalbersh@redhat.com>
|
||||
Date: Tue, 23 Apr 2024 14:36:16 +0200
|
||||
Subject: [PATCH] xfs_scrub: don't call phase_end if phase_rusage was not
|
||||
initialized
|
||||
|
||||
If unicrash_load() fails, all_pi can be used uninitialized in
|
||||
phase_end(). Fix it by going to the unload: section if unicrash_load
|
||||
fails and just go with unicrash_unload() (the is_service won't be
|
||||
initialized here).
|
||||
|
||||
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Bill O'Donnell <bodonnel@redhat.com>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
|
||||
---
|
||||
scrub/xfs_scrub.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/scrub/xfs_scrub.c b/scrub/xfs_scrub.c
|
||||
index 752180d6..50565857 100644
|
||||
--- a/scrub/xfs_scrub.c
|
||||
+++ b/scrub/xfs_scrub.c
|
||||
@@ -631,7 +631,7 @@ main(
|
||||
fprintf(stderr,
|
||||
_("%s: couldn't initialize Unicode library.\n"),
|
||||
progname);
|
||||
- goto out;
|
||||
+ goto out_unicrash;
|
||||
}
|
||||
|
||||
pthread_mutex_init(&ctx.lock, NULL);
|
||||
@@ -828,6 +828,7 @@ out:
|
||||
phase_end(&all_pi, 0);
|
||||
if (progress_fp)
|
||||
fclose(progress_fp);
|
||||
+out_unicrash:
|
||||
unicrash_unload();
|
||||
|
||||
/*
|
||||
--
|
||||
2.45.2
|
||||
|
@ -0,0 +1,80 @@
|
||||
From 5a43a00432ebe9ab8b54155703a9eb9e1a1dd4ec Mon Sep 17 00:00:00 2001
|
||||
From: "Darrick J. Wong" <djwong@kernel.org>
|
||||
Date: Mon, 29 Jul 2024 16:23:31 -0700
|
||||
Subject: [PATCH] xfs_repair: allow symlinks with short remote targets
|
||||
|
||||
Symbolic links can have extended attributes. If the attr fork consumes
|
||||
enough space in the inode record, a shortform symlink can become a
|
||||
remote symlink. However, if we delete those extended attributes, the
|
||||
target is not moved back into the inode core.
|
||||
|
||||
IOWs, we can end up with a symlink inode that looks like this:
|
||||
|
||||
core.magic = 0x494e
|
||||
core.mode = 0120777
|
||||
core.version = 3
|
||||
core.format = 2 (extents)
|
||||
core.nlinkv2 = 1
|
||||
core.nextents = 1
|
||||
core.size = 297
|
||||
core.nblocks = 1
|
||||
core.naextents = 0
|
||||
core.forkoff = 0
|
||||
core.aformat = 2 (extents)
|
||||
u3.bmx[0] = [startoff,startblock,blockcount,extentflag]
|
||||
0:[0,12,1,0]
|
||||
|
||||
This is a symbolic link with a 297-byte target stored in a disk block,
|
||||
which is to say this is a symlink with a remote target. The forkoff is
|
||||
0, which is to say that there's 512 - 176 == 336 bytes in the inode core
|
||||
to store the data fork.
|
||||
|
||||
Prior to kernel commit 1eb70f54c445f, the kernel was ok with this
|
||||
arrangement, but the change to symlink validation in that patch now
|
||||
produces corruption errors on filesystems written by older kernels that
|
||||
are not otherwise inconsistent. Those changes were inspired by reports
|
||||
of illegal memory accesses, which I think were a result of making data
|
||||
fork access decisions based on symlink di_size and not on di_format.
|
||||
|
||||
Unfortunately, for a very long time xfs_repair has flagged these inodes
|
||||
as being corrupt, even though the kernel has historically been willing
|
||||
to read and write symlinks with these properties. Resolve the conflict
|
||||
by adjusting the xfs_repair corruption tests to allow extents format.
|
||||
This change matches the kernel patch "xfs: allow symlinks with short
|
||||
remote targets".
|
||||
|
||||
While we're at it, fix a lurking bad symlink fork access.
|
||||
|
||||
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
Signed-off-by: Pavel Reichl <preichl@redhat.com>
|
||||
---
|
||||
repair/dinode.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/repair/dinode.c b/repair/dinode.c
|
||||
index 168cbf48..e36de9bf 100644
|
||||
--- a/repair/dinode.c
|
||||
+++ b/repair/dinode.c
|
||||
@@ -1036,7 +1036,8 @@ process_symlink_extlist(
|
||||
int max_blocks;
|
||||
|
||||
if (be64_to_cpu(dino->di_size) <= XFS_DFORK_DSIZE(dino, mp)) {
|
||||
- if (dino->di_format == XFS_DINODE_FMT_LOCAL)
|
||||
+ if (dino->di_format == XFS_DINODE_FMT_LOCAL ||
|
||||
+ dino->di_format == XFS_DINODE_FMT_EXTENTS)
|
||||
return 0;
|
||||
do_warn(
|
||||
_("mismatch between format (%d) and size (%" PRId64 ") in symlink ino %" PRIu64 "\n"),
|
||||
@@ -1368,7 +1369,7 @@ process_symlink(
|
||||
* get symlink contents into data area
|
||||
*/
|
||||
symlink = &data[0];
|
||||
- if (be64_to_cpu(dino->di_size) <= XFS_DFORK_DSIZE(dino, mp)) {
|
||||
+ if (dino->di_format == XFS_DINODE_FMT_LOCAL) {
|
||||
/*
|
||||
* local symlink, just copy the symlink out of the
|
||||
* inode into the data area
|
||||
--
|
||||
2.46.0
|
||||
|
@ -0,0 +1,25 @@
|
||||
jdm_parentpaths() doesn't initialize count. If count happens to be
|
||||
non-zero, following loop can result in access overflow.
|
||||
|
||||
Signed-off-by: Andrey Albershteyn <aalbersh@redhat.com>
|
||||
---
|
||||
io/parent.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/io/parent.c b/io/parent.c
|
||||
index 8f63607ffec2..5750d98a3b75 100644
|
||||
--- a/io/parent.c
|
||||
+++ b/io/parent.c
|
||||
@@ -112,7 +112,7 @@ check_parents(parent_t *parentbuf, size_t *parentbuf_size,
|
||||
jdm_fshandle_t *fshandlep, struct xfs_bstat *statp)
|
||||
{
|
||||
int error, i;
|
||||
- __u32 count;
|
||||
+ __u32 count = 0;
|
||||
parent_t *entryp;
|
||||
|
||||
do {
|
||||
--
|
||||
2.42.0
|
||||
|
||||
|
Loading…
Reference in new issue