summaryrefslogtreecommitdiff
path: root/fs/xfs/scrub/iscan.h
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-10-19 15:18:42 -0700
committerDarrick J. Wong <djwong@kernel.org>2021-12-15 17:28:53 -0800
commit2fbbe2f56eaf6da1cae10b209ed2e01035f7a78c (patch)
treeac87ccd2dbdc2a39237c9f121d2a2eb598bbb9e4 /fs/xfs/scrub/iscan.h
parent6b039a38ecceea9f3af7f4fc882cfcb8c5544e51 (diff)
xfs: implement live inode scan for scrub
This patch implements a live file scanner for online fsck functions that require the ability to walk a filesystem to gather metadata records and stay informed about metadata changes to files that have already been visited. The iscan structure consists of two inode number cursors: one to track which inode we want to visit next, and a second one to track which inodes have already been visited. This second cursor is key to capturing live updates to files previously scanned while the main thread continues scanning -- any inode greater than this value hasn't been scanned and can go on its way; any other update must be incorporated into the collected data. It is critical for the scanning thraad to hold exclusive access on the inode until after marking the inode visited. This new code is split out as a separate patch from its initial user for the sake of enabling the author to move patches around his tree with ease. The intended usage model for this code is roughly: xchk_iscan_start(iscan); while ((error = xchk_iscan_advance(sc, iscan)) == 1) { struct xfs_inode *ip; error = xchk_iscan_iget(sc, iscan, &ip); if (error == -EAGAIN) continue; if (error) break; xfs_ilock(ip, ...); /* capture inode metadata */ xchk_iscan_mark_visited(iscan, ip); xfs_iunlock(ip, ...); xfs_irele(ip); } xchk_iscan_stop(iscan); Hook functions for live updates can then do: if (xchk_iscan_want_live_update(...)) /* update the captured inode metadata */ Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs/xfs/scrub/iscan.h')
-rw-r--r--fs/xfs/scrub/iscan.h62
1 files changed, 62 insertions, 0 deletions
diff --git a/fs/xfs/scrub/iscan.h b/fs/xfs/scrub/iscan.h
new file mode 100644
index 000000000000..d9839414a103
--- /dev/null
+++ b/fs/xfs/scrub/iscan.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2021 Oracle. All Rights Reserved.
+ * Author: Darrick J. Wong <djwong@kernel.org>
+ */
+#ifndef __XFS_SCRUB_ISCAN_H__
+#define __XFS_SCRUB_ISCAN_H__
+
+struct xchk_iscan {
+ /* Lock to protect the scan cursor. */
+ struct mutex lock;
+
+ /* This is the inode that is being scanned. */
+ xfs_ino_t cursor_ino;
+
+ /*
+ * This is the last inode that we've successfully scanned, either
+ * because the caller scanned it, or we moved the cursor past an empty
+ * part of the inode address space. Scan callers should only use the
+ * xchk_iscan_visit function to modify this.
+ */
+ xfs_ino_t __visited_ino;
+
+ /* Operational state of the livescan. */
+ unsigned long __opstate;
+
+ /* Number of times to try iget calls for any inode. */
+ unsigned int iget_tries;
+
+ /* Wait this many jiffies for an iget retry. */
+ unsigned int iget_retry_delay;
+
+ /* Number of tries remaining for iget of cursor_ino. Do not modify. */
+ unsigned int __cursor_tries;
+};
+
+/* Set if the scan has been aborted due to some event in the fs. */
+#define XCHK_ISCAN_OPSTATE_ABORTED (1)
+
+static inline bool
+xchk_iscan_aborted(const struct xchk_iscan *iscan)
+{
+ return test_bit(XCHK_ISCAN_OPSTATE_ABORTED, &iscan->__opstate);
+}
+
+static inline void
+xchk_iscan_abort(struct xchk_iscan *iscan)
+{
+ set_bit(XCHK_ISCAN_OPSTATE_ABORTED, &iscan->__opstate);
+}
+
+void xchk_iscan_start(struct xchk_iscan *iscan);
+void xchk_iscan_finish(struct xchk_iscan *iscan);
+
+int xchk_iscan_advance(struct xfs_scrub *sc, struct xchk_iscan *iscan);
+int xchk_iscan_iget(struct xfs_scrub *sc, struct xchk_iscan *iscan,
+ struct xfs_inode **ipp);
+
+void xchk_iscan_mark_visited(struct xchk_iscan *iscan, struct xfs_inode *ip);
+bool xchk_iscan_want_live_update(struct xchk_iscan *iscan, xfs_ino_t ino);
+
+#endif /* __XFS_SCRUB_ISCAN_H__ */