Hi all,
Here's a bunch of hand-ported bug fixes for 6.12 LTS.
If you're going to start using this code, I strongly recommend pulling from my git trees, which are linked below.
With a bit of luck, this should all go splendidly. Comments and questions are, as always, welcome.
--D
kernel git tree: https://git.kernel.org/cgit/linux/kernel/git/djwong/xfs-linux.git/log/?h=nex... --- Commits in this patchset: * xfs: do not check NEEDSREPAIR if ro,norecovery mount. * xfs: Do not allow norecovery mount with quotacheck * xfs: rename xfs_iomap_swapfile_activate to xfs_vm_swap_activate * xfs: flush inodegc before swapon --- fs/xfs/xfs_aops.c | 41 +++++++++++++++++++++++++++++++++++++---- fs/xfs/xfs_qm_bhv.c | 49 ++++++++++++++++++++++++++++++++++--------------- fs/xfs/xfs_super.c | 8 ++++++-- 3 files changed, 77 insertions(+), 21 deletions(-)
From: Lukas Herbolt lukas@herbolt.com
Commit 9e00163c31676c6b43d2334fdf5b406232f42dee upstream
If there is corrutpion on the filesystem andxfs_repair fails to repair it. The last resort of getting the data is to use norecovery,ro mount. But if the NEEDSREPAIR is set the filesystem cannot be mounted. The flag must be cleared out manually using xfs_db, to get access to what left over of the corrupted fs.
Signed-off-by: Lukas Herbolt lukas@herbolt.com Reviewed-by: Dave Chinner dchinner@redhat.com Reviewed-by: Eric Sandeen sandeen@redhat.com Signed-off-by: Carlos Maiolino cem@kernel.org --- fs/xfs/xfs_super.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 8f7c9eaeb36090..201a86b3574da5 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1619,8 +1619,12 @@ xfs_fs_fill_super( #endif }
- /* Filesystem claims it needs repair, so refuse the mount. */ - if (xfs_has_needsrepair(mp)) { + /* + * Filesystem claims it needs repair, so refuse the mount unless + * norecovery is also specified, in which case the filesystem can + * be mounted with no risk of further damage. + */ + if (xfs_has_needsrepair(mp) && !xfs_has_norecovery(mp)) { xfs_warn(mp, "Filesystem needs repair. Please run xfs_repair."); error = -EFSCORRUPTED; goto out_free_sb;
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: 9e00163c31676c6b43d2334fdf5b406232f42dee
WARNING: Author mismatch between patch and upstream commit: Backport author: "Darrick J. Wong"djwong@kernel.org Commit author: Lukas Herboltlukas@herbolt.com
Note: The patch differs from the upstream commit: --- 1: 9e00163c31676 < -: ------------- xfs: do not check NEEDSREPAIR if ro,norecovery mount. -: ------------- > 1: ea061bad207e1 Linux 6.14.4 ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.4.y | Success | Success |
From: Carlos Maiolino cem@kernel.org
Commit 9f0902091c332b2665951cfb970f60ae7cbdc0f3 upstream
Mounting a filesystem that requires quota state changing will generate a transaction.
We already check for a read-only device; we should do that for norecovery too.
A quotacheck on a norecovery mount, and with the right log size, will cause the mount process to hang on:
[<0>] xlog_grant_head_wait+0x5d/0x2a0 [xfs] [<0>] xlog_grant_head_check+0x112/0x180 [xfs] [<0>] xfs_log_reserve+0xe3/0x260 [xfs] [<0>] xfs_trans_reserve+0x179/0x250 [xfs] [<0>] xfs_trans_alloc+0x101/0x260 [xfs] [<0>] xfs_sync_sb+0x3f/0x80 [xfs] [<0>] xfs_qm_mount_quotas+0xe3/0x2f0 [xfs] [<0>] xfs_mountfs+0x7ad/0xc20 [xfs] [<0>] xfs_fs_fill_super+0x762/0xa50 [xfs] [<0>] get_tree_bdev_flags+0x131/0x1d0 [<0>] vfs_get_tree+0x26/0xd0 [<0>] vfs_cmd_create+0x59/0xe0 [<0>] __do_sys_fsconfig+0x4e3/0x6b0 [<0>] do_syscall_64+0x82/0x160 [<0>] entry_SYSCALL_64_after_hwframe+0x76/0x7e
This is caused by a transaction running with bogus initialized head/tail
I initially hit this while running generic/050, with random log sizes, but I managed to reproduce it reliably here with the steps below:
mkfs.xfs -f -lsize=1025M -f -b size=4096 -m crc=1,reflink=1,rmapbt=1, -i sparse=1 /dev/vdb2 > /dev/null mount -o usrquota,grpquota,prjquota /dev/vdb2 /mnt xfs_io -x -c 'shutdown -f' /mnt umount /mnt mount -o ro,norecovery,usrquota,grpquota,prjquota /dev/vdb2 /mnt
Last mount hangs up
As we add yet another validation if quota state is changing, this also add a new helper named xfs_qm_validate_state_change(), factoring the quota state changes out of xfs_qm_newmount() to reduce cluttering within it.
Signed-off-by: Carlos Maiolino cmaiolino@redhat.com Reviewed-by: Darrick J. Wong djwong@kernel.org Signed-off-by: Carlos Maiolino cem@kernel.org --- fs/xfs/xfs_qm_bhv.c | 49 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 15 deletions(-)
diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c index ed1d597c30ca25..dabb1d6d7e463e 100644 --- a/fs/xfs/xfs_qm_bhv.c +++ b/fs/xfs/xfs_qm_bhv.c @@ -79,6 +79,28 @@ xfs_qm_statvfs( } }
+STATIC int +xfs_qm_validate_state_change( + struct xfs_mount *mp, + uint uqd, + uint gqd, + uint pqd) +{ + int state; + + /* Is quota state changing? */ + state = ((uqd && !XFS_IS_UQUOTA_ON(mp)) || + (!uqd && XFS_IS_UQUOTA_ON(mp)) || + (gqd && !XFS_IS_GQUOTA_ON(mp)) || + (!gqd && XFS_IS_GQUOTA_ON(mp)) || + (pqd && !XFS_IS_PQUOTA_ON(mp)) || + (!pqd && XFS_IS_PQUOTA_ON(mp))); + + return state && + (xfs_dev_is_read_only(mp, "changing quota state") || + xfs_has_norecovery(mp)); +} + int xfs_qm_newmount( xfs_mount_t *mp, @@ -98,24 +120,21 @@ xfs_qm_newmount( }
/* - * If the device itself is read-only, we can't allow - * the user to change the state of quota on the mount - - * this would generate a transaction on the ro device, - * which would lead to an I/O error and shutdown + * If the device itself is read-only and/or in norecovery + * mode, we can't allow the user to change the state of + * quota on the mount - this would generate a transaction + * on the ro device, which would lead to an I/O error and + * shutdown. */
- if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) || - (!uquotaondisk && XFS_IS_UQUOTA_ON(mp)) || - (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) || - (!gquotaondisk && XFS_IS_GQUOTA_ON(mp)) || - (pquotaondisk && !XFS_IS_PQUOTA_ON(mp)) || - (!pquotaondisk && XFS_IS_PQUOTA_ON(mp))) && - xfs_dev_is_read_only(mp, "changing quota state")) { + if (xfs_qm_validate_state_change(mp, uquotaondisk, + gquotaondisk, pquotaondisk)) { + xfs_warn(mp, "please mount with%s%s%s%s.", - (!quotaondisk ? "out quota" : ""), - (uquotaondisk ? " usrquota" : ""), - (gquotaondisk ? " grpquota" : ""), - (pquotaondisk ? " prjquota" : "")); + (!quotaondisk ? "out quota" : ""), + (uquotaondisk ? " usrquota" : ""), + (gquotaondisk ? " grpquota" : ""), + (pquotaondisk ? " prjquota" : "")); return -EPERM; }
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: 9f0902091c332b2665951cfb970f60ae7cbdc0f3
WARNING: Author mismatch between patch and upstream commit: Backport author: "Darrick J. Wong"djwong@kernel.org Commit author: Carlos Maiolinocem@kernel.org
Note: The patch differs from the upstream commit: --- 1: 9f0902091c332 < -: ------------- xfs: Do not allow norecovery mount with quotacheck -: ------------- > 1: ea061bad207e1 Linux 6.14.4 ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.4.y | Success | Success |
From: Christoph Hellwig hch@lst.de
Commit 3cd6a8056f5a2e794c42fc2114ee2611e358b357 upstream
Match the method name and the naming convention or address_space operations.
Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Darrick J. Wong djwong@kernel.org Reviewed-by: Dave Chinner dchinner@redhat.com Signed-off-by: Carlos Maiolino cem@kernel.org --- fs/xfs/xfs_aops.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 559a3a57709748..d2c7be12f5666b 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -528,7 +528,7 @@ xfs_vm_readahead( }
static int -xfs_iomap_swapfile_activate( +xfs_vm_swap_activate( struct swap_info_struct *sis, struct file *swap_file, sector_t *span) @@ -549,11 +549,11 @@ const struct address_space_operations xfs_address_space_operations = { .migrate_folio = filemap_migrate_folio, .is_partially_uptodate = iomap_is_partially_uptodate, .error_remove_folio = generic_error_remove_folio, - .swap_activate = xfs_iomap_swapfile_activate, + .swap_activate = xfs_vm_swap_activate, };
const struct address_space_operations xfs_dax_aops = { .writepages = xfs_dax_writepages, .dirty_folio = noop_dirty_folio, - .swap_activate = xfs_iomap_swapfile_activate, + .swap_activate = xfs_vm_swap_activate, };
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: 3cd6a8056f5a2e794c42fc2114ee2611e358b357
WARNING: Author mismatch between patch and upstream commit: Backport author: "Darrick J. Wong"djwong@kernel.org Commit author: Christoph Hellwighch@lst.de
Note: The patch differs from the upstream commit: --- 1: 3cd6a8056f5a2 < -: ------------- xfs: rename xfs_iomap_swapfile_activate to xfs_vm_swap_activate -: ------------- > 1: ea061bad207e1 Linux 6.14.4 ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.4.y | Success | Success |
From: Christoph Hellwig hch@lst.de
Commit 2d873efd174bae9005776937d5ac6a96050266db upstream
Fix the brand new xfstest that tries to swapon on a recently unshared file and use the chance to document the other bit of magic in this function.
The big comment is taken from a mailinglist post by Dave Chinner.
Fixes: 5e672cd69f0a53 ("xfs: introduce xfs_inodegc_push()") Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Darrick J. Wong djwong@kernel.org Reviewed-by: Dave Chinner dchinner@redhat.com Signed-off-by: Carlos Maiolino cem@kernel.org --- fs/xfs/xfs_aops.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index d2c7be12f5666b..ba6b4a180e8081 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -19,6 +19,7 @@ #include "xfs_reflink.h" #include "xfs_errortag.h" #include "xfs_error.h" +#include "xfs_icache.h"
struct xfs_writepage_ctx { struct iomap_writepage_ctx ctx; @@ -533,7 +534,39 @@ xfs_vm_swap_activate( struct file *swap_file, sector_t *span) { - sis->bdev = xfs_inode_buftarg(XFS_I(file_inode(swap_file)))->bt_bdev; + struct xfs_inode *ip = XFS_I(file_inode(swap_file)); + + /* + * Swap file activation can race against concurrent shared extent + * removal in files that have been cloned. If this happens, + * iomap_swapfile_iter() can fail because it encountered a shared + * extent even though an operation is in progress to remove those + * shared extents. + * + * This race becomes problematic when we defer extent removal + * operations beyond the end of a syscall (i.e. use async background + * processing algorithms). Users think the extents are no longer + * shared, but iomap_swapfile_iter() still sees them as shared + * because the refcountbt entries for the extents being removed have + * not yet been updated. Hence the swapon call fails unexpectedly. + * + * The race condition is currently most obvious from the unlink() + * operation as extent removal is deferred until after the last + * reference to the inode goes away. We then process the extent + * removal asynchronously, hence triggers the "syscall completed but + * work not done" condition mentioned above. To close this race + * window, we need to flush any pending inodegc operations to ensure + * they have updated the refcountbt records before we try to map the + * swapfile. + */ + xfs_inodegc_flush(ip->i_mount); + + /* + * Direct the swap code to the correct block device when this file + * sits on the RT device. + */ + sis->bdev = xfs_inode_buftarg(ip)->bt_bdev; + return iomap_swapfile_activate(sis, swap_file, span, &xfs_read_iomap_ops); }
[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: 2d873efd174bae9005776937d5ac6a96050266db
WARNING: Author mismatch between patch and upstream commit: Backport author: "Darrick J. Wong"djwong@kernel.org Commit author: Christoph Hellwighch@lst.de
Note: The patch differs from the upstream commit: --- 1: 2d873efd174ba < -: ------------- xfs: flush inodegc before swapon -: ------------- > 1: ea061bad207e1 Linux 6.14.4 ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.4.y | Success | Success |
linux-stable-mirror@lists.linaro.org