Skip to content

Commit 9ed851f

Browse files
author
Darrick J. Wong
committed
xfs: allow scanning ranges of the buffer cache for live buffers
After an online repair, we need to invalidate buffers representing the blocks from the old metadata that we're replacing. It's possible that parts of a tree that were previously cached in memory are no longer accessible due to media failure or other corruption on interior nodes, so repair figures out the old blocks from the reverse mapping data and scans the buffer cache directly. In other words, online fsck needs to find all the live (i.e. non-stale) buffers for a range of fsblocks so that it can invalidate them. Unfortunately, the current buffer cache code triggers asserts if the rhashtable lookup finds a non-stale buffer of a different length than the key we searched for. For regular operation this is desirable, but for this repair procedure, we don't care since we're going to forcibly stale the buffer anyway. Add an internal lookup flag to avoid the assert. Skip buffers that are already XBF_STALE. Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Dave Chinner <[email protected]>
1 parent 77a1396 commit 9ed851f

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

fs/xfs/scrub/reap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ xrep_block_reap_binval(
149149
*/
150150
error = xfs_buf_incore(sc->mp->m_ddev_targp,
151151
XFS_FSB_TO_DADDR(sc->mp, fsbno),
152-
XFS_FSB_TO_BB(sc->mp, 1), 0, &bp);
152+
XFS_FSB_TO_BB(sc->mp, 1), XBF_LIVESCAN, &bp);
153153
if (error)
154154
return;
155155

fs/xfs/xfs_buf.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,8 @@ _xfs_buf_obj_cmp(
481481
* reallocating a busy extent. Skip this buffer and
482482
* continue searching for an exact match.
483483
*/
484-
ASSERT(bp->b_flags & XBF_STALE);
484+
if (!(map->bm_flags & XBM_LIVESCAN))
485+
ASSERT(bp->b_flags & XBF_STALE);
485486
return 1;
486487
}
487488
return 0;
@@ -559,6 +560,10 @@ xfs_buf_find_lock(
559560
* intact here.
560561
*/
561562
if (bp->b_flags & XBF_STALE) {
563+
if (flags & XBF_LIVESCAN) {
564+
xfs_buf_unlock(bp);
565+
return -ENOENT;
566+
}
562567
ASSERT((bp->b_flags & _XBF_DELWRI_Q) == 0);
563568
bp->b_flags &= _XBF_KMEM | _XBF_PAGES;
564569
bp->b_ops = NULL;
@@ -682,6 +687,8 @@ xfs_buf_get_map(
682687
int error;
683688
int i;
684689

690+
if (flags & XBF_LIVESCAN)
691+
cmap.bm_flags |= XBM_LIVESCAN;
685692
for (i = 0; i < nmaps; i++)
686693
cmap.bm_len += map[i].bm_len;
687694

fs/xfs/xfs_buf.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ struct xfs_buf;
4444
#define _XBF_DELWRI_Q (1u << 22)/* buffer on a delwri queue */
4545

4646
/* flags used only as arguments to access routines */
47+
/*
48+
* Online fsck is scanning the buffer cache for live buffers. Do not warn
49+
* about length mismatches during lookups and do not return stale buffers.
50+
*/
51+
#define XBF_LIVESCAN (1u << 28)
4752
#define XBF_INCORE (1u << 29)/* lookup only, return if found in cache */
4853
#define XBF_TRYLOCK (1u << 30)/* lock requested, but do not wait */
4954
#define XBF_UNMAPPED (1u << 31)/* do not map the buffer */
@@ -67,6 +72,7 @@ typedef unsigned int xfs_buf_flags_t;
6772
{ _XBF_KMEM, "KMEM" }, \
6873
{ _XBF_DELWRI_Q, "DELWRI_Q" }, \
6974
/* The following interface flags should never be set */ \
75+
{ XBF_LIVESCAN, "LIVESCAN" }, \
7076
{ XBF_INCORE, "INCORE" }, \
7177
{ XBF_TRYLOCK, "TRYLOCK" }, \
7278
{ XBF_UNMAPPED, "UNMAPPED" }
@@ -114,8 +120,15 @@ typedef struct xfs_buftarg {
114120
struct xfs_buf_map {
115121
xfs_daddr_t bm_bn; /* block number for I/O */
116122
int bm_len; /* size of I/O */
123+
unsigned int bm_flags;
117124
};
118125

126+
/*
127+
* Online fsck is scanning the buffer cache for live buffers. Do not warn
128+
* about length mismatches during lookups and do not return stale buffers.
129+
*/
130+
#define XBM_LIVESCAN (1U << 0)
131+
119132
#define DEFINE_SINGLE_BUF_MAP(map, blkno, numblk) \
120133
struct xfs_buf_map (map) = { .bm_bn = (blkno), .bm_len = (numblk) };
121134

0 commit comments

Comments
 (0)