aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_buf.c35
-rw-r--r--fs/xfs/xfs_buf.h2
-rw-r--r--fs/xfs/xfs_trans_buf.c2
3 files changed, 17 insertions, 22 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 4f5f2ff3f70f..d29246ac3721 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -776,29 +776,24 @@ _xfs_buf_read(
776} 776}
777 777
778/* 778/*
779 * Set buffer ops on an unchecked buffer and validate it, if possible. 779 * Reverify a buffer found in cache without an attached ->b_ops.
780 * 780 *
781 * If the caller passed in an ops structure and the buffer doesn't have ops 781 * If the caller passed an ops structure and the buffer doesn't have ops
782 * assigned, set the ops and use them to verify the contents. If the contents 782 * assigned, set the ops and use it to verify the contents. If verification
783 * cannot be verified, we'll clear XBF_DONE. We assume the buffer has no 783 * fails, clear XBF_DONE. We assume the buffer has no recorded errors and is
784 * recorded errors and is already in XBF_DONE state. 784 * already in XBF_DONE state on entry.
785 * 785 *
786 * Under normal operations, every in-core buffer must have buffer ops assigned 786 * Under normal operations, every in-core buffer is verified on read I/O
787 * to them when the buffer is read in from disk so that we can validate the 787 * completion. There are two scenarios that can lead to in-core buffers without
788 * metadata. 788 * an assigned ->b_ops. The first is during log recovery of buffers on a V4
789 * 789 * filesystem, though these buffers are purged at the end of recovery. The
790 * However, there are two scenarios where one can encounter in-core buffers 790 * other is online repair, which intentionally reads with a NULL buffer ops to
791 * that don't have buffer ops. The first is during log recovery of buffers on 791 * run several verifiers across an in-core buffer in order to establish buffer
792 * a V4 filesystem, though these buffers are purged at the end of recovery. 792 * type. If repair can't establish that, the buffer will be left in memory
793 * 793 * with NULL buffer ops.
794 * The other is online repair, which tries to match arbitrary metadata blocks
795 * with btree types in order to find the root. If online repair doesn't match
796 * the buffer with /any/ btree type, the buffer remains in memory in DONE state
797 * with no ops, and a subsequent read_buf call from elsewhere will not set the
798 * ops. This function helps us fix this situation.
799 */ 794 */
800int 795int
801xfs_buf_ensure_ops( 796xfs_buf_reverify(
802 struct xfs_buf *bp, 797 struct xfs_buf *bp,
803 const struct xfs_buf_ops *ops) 798 const struct xfs_buf_ops *ops)
804{ 799{
@@ -840,7 +835,7 @@ xfs_buf_read_map(
840 return bp; 835 return bp;
841 } 836 }
842 837
843 xfs_buf_ensure_ops(bp, ops); 838 xfs_buf_reverify(bp, ops);
844 839
845 if (flags & XBF_ASYNC) { 840 if (flags & XBF_ASYNC) {
846 /* 841 /*
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
index b9f5511ea998..1c436a85b71d 100644
--- a/fs/xfs/xfs_buf.h
+++ b/fs/xfs/xfs_buf.h
@@ -385,6 +385,6 @@ extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int);
385#define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev) 385#define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev)
386#define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev) 386#define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev)
387 387
388int xfs_buf_ensure_ops(struct xfs_buf *bp, const struct xfs_buf_ops *ops); 388int xfs_buf_reverify(struct xfs_buf *bp, const struct xfs_buf_ops *ops);
389 389
390#endif /* __XFS_BUF_H__ */ 390#endif /* __XFS_BUF_H__ */
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index 629f1479c9d2..7d65ebf1e847 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -277,7 +277,7 @@ xfs_trans_read_buf_map(
277 * release this buffer when it kills the tranaction. 277 * release this buffer when it kills the tranaction.
278 */ 278 */
279 ASSERT(bp->b_ops != NULL); 279 ASSERT(bp->b_ops != NULL);
280 error = xfs_buf_ensure_ops(bp, ops); 280 error = xfs_buf_reverify(bp, ops);
281 if (error) { 281 if (error) {
282 xfs_buf_ioerror_alert(bp, __func__); 282 xfs_buf_ioerror_alert(bp, __func__);
283 283