Separate the validation of inodes found by the radix
tree walk from the radix tree lookup.
Signed-off-by: Dave Chinner <david@xxxxxxxxxxxxx>
---
fs/xfs/linux-2.6/xfs_sync.c | 56 ++++++++++++++++++++++++++----------------
1 files changed, 35 insertions(+), 21 deletions(-)
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index b3d4f7a..a83438a 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -120,6 +120,37 @@ out:
return error;
}
+int
+xfs_sync_inode_valid(
+ xfs_mount_t *mp,
+ xfs_inode_t *ip)
+{
+ struct inode *inode;
+ int error;
+
+ /* nothing to sync during shutdown */
+ if (XFS_FORCED_SHUTDOWN(mp))
+ return EFSCORRUPTED;
+
+ /*
+ * If we can't get a reference on the inode, it must be in reclaim.
+ * Leave it for the reclaim code to flush. Also avoid inodes that
+ * haven't been fully initialised.
+ */
+ error = ENOENT;
+ inode = VFS_I(ip);
+ if (!igrab(inode))
+ goto error;
+ if (is_bad_inode(inode) ||
+ xfs_iflags_test(ip, XFS_INEW))
+ goto rele;
+ return 0;
+rele:
+ IRELE(ip);
+error:
+ return error;
+}
+
/*
* Sync all the inodes in the given AG according to the
* direction given by the flags.
@@ -137,7 +168,6 @@ xfs_sync_inodes_ag(
int last_error = 0;
do {
- struct inode *inode;
xfs_inode_t *ip = NULL;
/*
@@ -166,27 +196,11 @@ xfs_sync_inodes_ag(
break;
}
- /* nothing to sync during shutdown */
- if (XFS_FORCED_SHUTDOWN(mp)) {
+ error = xfs_sync_inode_valid(mp, ip);
+ if (error) {
read_unlock(&pag->pag_ici_lock);
- return 0;
- }
-
- /*
- * If we can't get a reference on the inode, it must be
- * in reclaim. Leave it for the reclaim code to flush.
- */
- inode = VFS_I(ip);
- if (!igrab(inode)) {
- read_unlock(&pag->pag_ici_lock);
- continue;
- }
- read_unlock(&pag->pag_ici_lock);
-
- /* avoid new or bad inodes */
- if (is_bad_inode(inode) ||
- xfs_iflags_test(ip, XFS_INEW)) {
- IRELE(ip);
+ if (error == EFSCORRUPTED)
+ return 0;
continue;
}
--
1.6.2
|