summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_export.c
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2023-09-24 17:35:53 +0200
committerDarrick J. Wong <djwong@kernel.org>2023-09-25 03:12:13 +0200
commit537c013b140d373d1ffe6290b841dc00e67effaa (patch)
tree2a9b076ead1be5eb3d90030a7f5ef4b87f3961ae /fs/xfs/xfs_export.c
parentLinux 6.6-rc3 (diff)
downloadlinux-537c013b140d373d1ffe6290b841dc00e67effaa.tar.xz
linux-537c013b140d373d1ffe6290b841dc00e67effaa.zip
xfs: fix reloading entire unlinked bucket lists
During review of the patcheset that provided reloading of the incore iunlink list, Dave made a few suggestions, and I updated the copy in my dev tree. Unfortunately, I then got distracted by ... who even knows what ... and forgot to backport those changes from my dev tree to my release candidate branch. I then sent multiple pull requests with stale patches, and that's what was merged into -rc3. So. This patch re-adds the use of an unlocked iunlink list check to determine if we want to allocate the resources to recreate the incore list. Since lost iunlinked inodes are supposed to be rare, this change helps us avoid paying the transaction and AGF locking costs every time we open any inode. This also re-adds the shutdowns on failure, and re-applies the restructuring of the inner loop in xfs_inode_reload_unlinked_bucket, and re-adds a requested comment about the quotachecking code. Retain the original RVB tag from Dave since there's no code change from the last submission. Fixes: 68b957f64fca1 ("xfs: load uncached unlinked inodes into memory on demand") Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Dave Chinner <dchinner@redhat.com>
Diffstat (limited to 'fs/xfs/xfs_export.c')
-rw-r--r--fs/xfs/xfs_export.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c
index f71ea786a6d2..7cd09c3a82cb 100644
--- a/fs/xfs/xfs_export.c
+++ b/fs/xfs/xfs_export.c
@@ -146,10 +146,18 @@ xfs_nfs_get_inode(
return ERR_PTR(error);
}
- error = xfs_inode_reload_unlinked(ip);
- if (error) {
- xfs_irele(ip);
- return ERR_PTR(error);
+ /*
+ * Reload the incore unlinked list to avoid failure in inodegc.
+ * Use an unlocked check here because unrecovered unlinked inodes
+ * should be somewhat rare.
+ */
+ if (xfs_inode_unlinked_incomplete(ip)) {
+ error = xfs_inode_reload_unlinked(ip);
+ if (error) {
+ xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
+ xfs_irele(ip);
+ return ERR_PTR(error);
+ }
}
if (VFS_I(ip)->i_generation != generation) {