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