diff options
-rw-r--r-- | fs/xfs/xfs_buf.c | 35 | ||||
-rw-r--r-- | fs/xfs/xfs_buf.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_buf.c | 2 |
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 | */ |
800 | int | 795 | int |
801 | xfs_buf_ensure_ops( | 796 | xfs_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 | ||
388 | int xfs_buf_ensure_ops(struct xfs_buf *bp, const struct xfs_buf_ops *ops); | 388 | int 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 | ||