xfsprogs: update to v6.5.0 #3

Closed
ailiopoulos wants to merge 2 commits from (deleted):factory into factory
8 changed files with 38 additions and 360 deletions
Showing only changes of commit 54dbfa97c1 - Show all commits

View File

@ -1,65 +0,0 @@
From 73ae943b19e658295140f56cb0f0fada2294921d Mon Sep 17 00:00:00 2001
From: "Darrick J. Wong" <djwong@kernel.org>
Date: Tue, 12 Sep 2023 12:40:10 -0700
Subject: [PATCH] libxfs: fix atomic64_t detection on x86 32-bit architectures
References: bsc#1214416
xfsprogs during compilation tries to detect if liburcu supports atomic
64-bit ops on the platform it is being compiled on, and if not it falls
back to using pthread mutex locks.
The detection logic for that fallback relies on _uatomic_link_error()
which is a link-time trick used by liburcu that will cause compilation
errors on archs that lack the required support. That only works for the
generic liburcu code though, and it is not implemented for the
x86-specific code.
In practice this means that when xfsprogs is compiled on 32-bit x86
archs will successfully link to liburcu for atomic ops, but liburcu does
not support atomic64_t on those archs. It indicates this during runtime
by generating an illegal instruction that aborts execution, and thus
causes various xfsprogs utils to be segfaulting.
Fix this by executing the liburcu atomic64_t detection code during
configure instead of only relying on the linker error, so that
compilation will properly fall back to pthread mutexes on those archs.
Fixes: 7448af588a2e ("libxfs: fix atomic64_t poorly for 32-bit architectures")
Reported-by: Anthony Iliopoulos <ailiop@suse.com>
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
---
m4/package_urcu.m4 | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/m4/package_urcu.m4 b/m4/package_urcu.m4
index ef116e0cda76..4bb2b886f068 100644
--- a/m4/package_urcu.m4
+++ b/m4/package_urcu.m4
@@ -26,7 +26,11 @@ rcu_init();
#
# Make sure that calling uatomic_inc on a 64-bit integer doesn't cause a link
# error on _uatomic_link_error, which is how liburcu signals that it doesn't
-# support atomic operations on 64-bit data types.
+# support atomic operations on 64-bit data types for its generic
+# implementation (which relies on compiler builtins). For certain archs
+# where liburcu carries its own implementation (such as x86_32), it
+# signals lack of support during runtime by emitting an illegal
+# instruction, so we also need to check CAA_BITS_PER_LONG to detect that.
#
AC_DEFUN([AC_HAVE_LIBURCU_ATOMIC64],
[ AC_MSG_CHECKING([for atomic64_t support in liburcu])
@@ -34,8 +38,11 @@ AC_DEFUN([AC_HAVE_LIBURCU_ATOMIC64],
[ AC_LANG_PROGRAM([[
#define _GNU_SOURCE
#include <urcu.h>
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
]], [[
long long f = 3;
+
+BUILD_BUG_ON(CAA_BITS_PER_LONG < 64);
uatomic_inc(&f);
]])
], have_liburcu_atomic64=yes
--
2.42.0

View File

@ -1,280 +0,0 @@
From e2239ef552a48edd33740fec8a005a7ac12dcc80 Mon Sep 17 00:00:00 2001
From: Jeffrey Mahoney <jeffm@suse.com>
Date: Tue, 21 Aug 2018 13:41:20 -0400
Subject: [PATCH] repair: shift inode back into place if corrupted by bad log
replay
References: bsc#1105396
SUSE kernels 3.12.74-60.64.40 through 3.12.74-60.64.99 contained
a regression where xfs_icdinode_t modified di_dmstate to be
an atomic_t. Since we only complain if an inode item is too large,
if a kernel with this patch applied mounted a file system with inode
items in the log formatted by a kernel without this patch, they would
be used but would be interpreted using the structure with the atomic_t.
As a result, the inode would be copied incorrectly, corrupting di_dmstate
and the members that follow it.
For v3 inodes, we can detect that the UUID is shifted forward
8 bytes and recover di_uuid, di_ino, di_crtime, di_pad2, di_cowextsize,
di_flags2, and di_lsn. The UUID and inode number being incorrect
will trip the verifier on iread, but it will have been flushed from the
log in a broken state.
di_changecount is lost entirely since half is overwritten by the CRC
being updated and the other half fell in a hole in the structure.
di_flags is lost entirely since it is overwritten by the half of
the generation number. Half of the generation number is lost since
it falls in a hole in the structure.
For v2 inodes, the corruption is more limited but impossible to
detect beyond invalid flags being in use.
Without this fix, xfs_repair will clear the affected inodes, causing
big problems.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
repair/dinode.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 180 insertions(+), 6 deletions(-)
diff --git a/repair/dinode.c b/repair/dinode.c
index 8ea919698d14..81238568ac8e 100644
--- a/repair/dinode.c
+++ b/repair/dinode.c
@@ -2239,6 +2239,160 @@ _("Bad extent size hint %u on inode %" PRIu64 ", "),
}
}
+static int
+check_shifted_uuid(struct xfs_dinode *dino, xfs_mount_t *mp)
+{
+ uint64_t tmp64;
+ char tmpuuid[16];
+ uuid_t uuid;
+
+ tmp64 = be64_to_cpu(dino->di_ino);
+ memcpy(tmpuuid, &tmp64, sizeof(tmp64));
+ memcpy(tmpuuid + 8, &dino->di_uuid, 8);
+ memcpy(uuid, tmpuuid, 16);
+
+ return !platform_uuid_compare(&uuid, &mp->m_sb.sb_meta_uuid);
+}
+
+/*
+ * There was a kernel that would use incorrectly-formatted log items.
+ * If it recovered a dirty log, corrupted inodes would result.
+ * 12 bytes of the inode are completely unrecoverable. Those are
+ * documented below.
+ */
+static void
+repair_inode_with_bad_atomic(struct xfs_dinode *dino, xfs_mount_t *mp)
+{
+ struct xfs_dinode fixed;
+ struct xfs_legacy_timestamp *lts;
+ uint64_t tmp64;
+ uint32_t tmp32;
+ char tmpuuid[16];
+ char *tmpptr;
+
+ uuid_t uuid;
+
+ tmp64 = be64_to_cpu(dino->di_ino);
+ memcpy(tmpuuid, &tmp64, sizeof(tmp64));
+ tmpptr = (char *)dino->di_uuid;
+ memcpy(tmpuuid + 8, tmpptr, 8);
+ memcpy(uuid, tmpuuid, 16);
+
+ memcpy(&fixed, dino, sizeof(fixed));
+ memcpy(&fixed.di_uuid, uuid, sizeof(uuid));
+
+ tmp32 = *(uint32_t *)&dino->di_pad2[4];
+ lts = (struct xfs_legacy_timestamp *)&(fixed.di_crtime);
+ lts->t_sec = cpu_to_be32(tmp32);
+ tmp32 = *(uint32_t *)&dino->di_pad2[8];
+ lts->t_nsec = cpu_to_be32(tmp32);
+
+ tmp64 = be32_to_cpu(((struct xfs_legacy_timestamp *)(&(dino->di_crtime)))->t_nsec);
+ tmp64 <<= 32;
+ tmp64 |= be32_to_cpu(((struct xfs_legacy_timestamp *)(&(dino->di_crtime)))->t_sec);
+ fixed.di_ino = cpu_to_be64(tmp64);
+
+ tmp64 = be64_to_cpu(fixed.di_ino);
+
+ memcpy(fixed.di_pad2 + 8, dino->di_pad2, 4);
+
+ tmp32 = be32_to_cpu(dino->di_cowextsize);
+ memcpy(fixed.di_pad2 + 4, &tmp32, 4);
+
+ tmp64 = be64_to_cpu(dino->di_flags2);
+ tmp32 = tmp64 >> 32;
+ memcpy(fixed.di_pad2, &tmp32, 4);
+
+ fixed.di_cowextsize = cpu_to_be32(tmp64);
+ fixed.di_flags2 = dino->di_lsn;
+ fixed.di_lsn = dino->di_changecount;
+
+ /*
+ * This is lost entirely. Half falls in padding and half
+ * is overwritten by the CRC.
+ */
+ fixed.di_changecount = 0;
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ /*
+ * Half of the generation number is lost, but it's the high bits.
+ * Pick a high number and hope for the best.
+ */
+ tmp32 = 0xff000000;
+ tmp32 |= be16_to_cpu(dino->di_flags);
+ fixed.di_gen = cpu_to_be32(tmp32);
+#else
+ /*
+ * Half of the generation number is lost, but it's the low bits,
+ * so we can fake it.
+ */
+ tmp32 = be16_to_cpu(dino->di_flags) + 1;
+ tmp32 <<= 16;
+ fixed.di_gen = cpu_to_be32(tmp32);
+#endif
+
+ /*
+ * The flags are lost since the atomic_t was 32-bit and we
+ * only keep 16.
+ */
+ fixed.di_flags = 0;
+
+ memcpy(dino, &fixed, sizeof(*dino));
+ xfs_dinode_calc_crc(mp, dino);
+}
+
+static int
+process_dinode_int(xfs_mount_t *mp, struct xfs_dinode *dino, xfs_agnumber_t agno,
+ xfs_agino_t ino, int was_free, int *dirty, int *used,
+ int verify_mode, int uncertain, int ino_discovery,
+ int check_dups, int extra_attr_check, int *isa_dir,
+ xfs_ino_t *parent, int recurse);
+
+static int
+handle_malformed_inode(xfs_mount_t *mp, struct xfs_dinode *dino,
+ xfs_agnumber_t agno, xfs_agino_t ino, int was_free,
+ int *dirty, int *used, int verify_mode, int uncertain,
+ int ino_discovery, int check_dups, int extra_attr_check,
+ int *isa_dir, xfs_ino_t *parent)
+{
+ struct xfs_dinode save;
+ int retval;
+ xfs_ino_t lino = XFS_AGINO_TO_INO(mp, agno, ino);
+
+ if (!uncertain)
+ do_warn(_("malformed inode %" PRIu64 " found%c"),
+ lino, verify_mode ? '\n' : ',');
+
+ /*
+ * We can't just pass a local copy to verify since we need the
+ * data fork to check directories.
+ */
+ if (verify_mode || no_modify)
+ memcpy(&save, dino, sizeof(*dino));
+
+ repair_inode_with_bad_atomic(dino, mp);
+ retval = process_dinode_int(mp, dino, agno, ino, was_free, dirty,
+ used, verify_mode, uncertain, ino_discovery,
+ check_dups, extra_attr_check,
+ isa_dir, parent, 1);
+
+ if (verify_mode || no_modify) {
+ memcpy(dino, &save, sizeof(*dino));
+ *dirty = 0;
+ }
+
+ if (retval == 0 && !verify_mode) {
+ if (no_modify)
+ do_warn(_(" would repair\n"));
+ else {
+ do_warn(_(" repairing\n"));
+ *dirty = 1;
+ }
+ }
+
+ return retval;
+}
+
/*
* returns 0 if the inode is ok, 1 if the inode is corrupt
* check_dups can be set to 1 *only* when called by the
@@ -2263,7 +2417,8 @@ process_dinode_int(xfs_mount_t *mp,
* duplicate blocks */
int extra_attr_check, /* 1 == do attribute format and value checks */
int *isa_dir, /* out == 1 if inode is a directory */
- xfs_ino_t *parent) /* out -- parent if ino is a dir */
+ xfs_ino_t *parent, /* out -- parent if ino is a dir */
+ int recurse)
{
xfs_rfsblock_t totblocks = 0;
xfs_rfsblock_t atotblocks = 0;
@@ -2379,6 +2534,25 @@ process_dinode_int(xfs_mount_t *mp,
* memory and hence invalidated the CRC.
*/
if (xfs_has_crc(mp)) {
+ int good_uuid = 1;
+
+ if (platform_uuid_compare(&dino->di_uuid,
+ &mp->m_sb.sb_meta_uuid))
+ good_uuid = 0;
+
+ /*
+ * Only check to see if it's a malformed inode if it has
+ * a valid magic, crc, and version and an invalid uuid.
+ */
+ if (!good_uuid && !retval && !recurse &&
+ check_shifted_uuid(dino, mp))
+ return handle_malformed_inode(mp, dino, agno, ino,
+ was_free, dirty, used,
+ verify_mode, uncertain,
+ ino_discovery, check_dups,
+ extra_attr_check,
+ isa_dir, parent);
+
if (be64_to_cpu(dino->di_ino) != lino) {
if (!uncertain)
do_warn(
@@ -2389,8 +2563,7 @@ _("inode identifier %llu mismatch on inode %" PRIu64 "\n"),
return 1;
goto clear_bad_out;
}
- if (platform_uuid_compare(&dino->di_uuid,
- &mp->m_sb.sb_meta_uuid)) {
+ if (!good_uuid) {
if (!uncertain)
do_warn(
_("UUID mismatch on inode %" PRIu64 "\n"), lino);
@@ -2952,7 +3125,8 @@ process_dinode(
#endif
return process_dinode_int(mp, dino, agno, ino, was_free, dirty, used,
verify_mode, uncertain, ino_discovery,
- check_dups, extra_attr_check, isa_dir, parent);
+ check_dups, extra_attr_check, isa_dir, parent,
+ 0);
}
/*
@@ -2979,7 +3153,7 @@ verify_dinode(
return process_dinode_int(mp, dino, agno, ino, 0, &dirty, &used,
verify_mode, uncertain, ino_discovery,
- check_dups, 0, &isa_dir, &parent);
+ check_dups, 0, &isa_dir, &parent, 0);
}
/*
@@ -3005,5 +3179,5 @@ verify_uncertain_dinode(
return process_dinode_int(mp, dino, agno, ino, 0, &dirty, &used,
verify_mode, uncertain, ino_discovery,
- check_dups, 0, &isa_dir, &parent);
+ check_dups, 0, &isa_dir, &parent, 0);
}
--
2.36.1

View File

@ -1,7 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iIUEABYIAC0WIQT6QG4gav94c4l8aGS0VhjDaiT9IwUCZLfVMw8cY2VtQGtlcm5l
bC5vcmcACgkQtFYYw2ok/SNKPwEA6fsxp1TRbPXQn6a605fU3cE6WjcqDLej3zYa
lx91BnABAKIWP14Rd7KPbCH4ezAPydFZxSn26trKqPxzAFOZ/skP
=mkU4
-----END PGP SIGNATURE-----

BIN
xfsprogs-6.4.0.tar.xz (Stored with Git LFS)

Binary file not shown.

7
xfsprogs-6.5.0.tar.sign Normal file
View File

@ -0,0 +1,7 @@
-----BEGIN PGP SIGNATURE-----
iIUEABYIAC0WIQT6QG4gav94c4l8aGS0VhjDaiT9IwUCZSfZXQ8cY2VtQGtlcm5l
bC5vcmcACgkQtFYYw2ok/SOFogD+MZ4LooqWPZ9aNEfw/GEtiJJzlVMwYHFcgqDK
xgilyusBAKOZeJc4SiFarTv2PnIRuMDxhwaFm0Sy+ngiFn0whlED
=k6/7
-----END PGP SIGNATURE-----

BIN
xfsprogs-6.5.0.tar.xz (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -1,3 +1,30 @@
-------------------------------------------------------------------
Fri Oct 13 14:45:05 UTC 2023 - Anthony Iliopoulos <ailiop@suse.com>
- update to 6.5.0
- libxfs: fix atomic64_t detection on x86_32
- libxfs: use XFS_IGET_CREATE when creating new files
- libfrog: fix overly sleep workqueues
- xfs_db: use directio for device access
- libxfs: make platform_set_blocksize optional with directio
- mkfs: add a config file for 6.6 LTS kernels
- mkfs: enable reverse mapping by default
- mkfs: enable large extent counts by default
- xfs_db: create unlinked inodes
- xfs_db: dump unlinked buckets
- xfsprogs: don't allow udisks to automount XFS filesystems with no prompt
- xfs_repair: fix repair failure caused by dirty flag being abnormally set on buffer
- drop 0001-repair-shift-inode-back-into-place-if-corrupted-by-b.patch
This is now upstream.
- drop 0001-repair-shift-inode-back-into-place-if-corrupted-by-b.patch
This was a fix for a regression that occurred in SLE12 SP1. We can
safely drop this, as upgrading to SLE15 (and later) is only supported
from SLE12-SP4.
-------------------------------------------------------------------
Fri Sep 22 12:56:31 UTC 2023 - Anthony Iliopoulos <ailiop@suse.com>

View File

@ -25,7 +25,7 @@
%endif
%define libname libhandle1
Name: xfsprogs
Version: 6.4.0
Version: 6.5.0
Release: 0
Summary: Utilities for managing the XFS file system
License: GPL-2.0-or-later
@ -37,8 +37,6 @@ Source2: %{name}.keyring
Source3: module-setup.sh.in
Source4: dracut-fsck-help.txt
Patch0: xfsprogs-docdir.diff
Patch1: 0001-repair-shift-inode-back-into-place-if-corrupted-by-b.patch
Patch2: 0001-libxfs-fix-atomic64_t-detection-on-x86-32-bit-archit.patch
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: libblkid-devel
@ -111,8 +109,6 @@ on xfs filesystems.
%prep
%setup -q
%patch0 -p1
%patch1 -p1
%patch2 -p1
%build
aclocal -I m4