aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_buf.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2012-11-12 06:54:01 -0500
committerBen Myers <bpm@sgi.com>2012-11-15 22:34:02 -0500
commitc3f8fc73ac97b76a12692088ef9cace9af8422c0 (patch)
treea90e132507842b7ed8c5d93e0c002e0dc0f99a5c /fs/xfs/xfs_buf.c
parentfb59581404ab7ec5075299065c22cb211a9262a9 (diff)
xfs: make buffer read verication an IO completion function
Add a verifier function callback capability to the buffer read interfaces. This will be used by the callers to supply a function that verifies the contents of the buffer when it is read from disk. This patch does not provide callback functions, but simply modifies the interfaces to allow them to be called. The reason for adding this to the read interfaces is that it is very difficult to tell fom the outside is a buffer was just read from disk or whether we just pulled it out of cache. Supplying a callbck allows the buffer cache to use it's internal knowledge of the buffer to execute it only when the buffer is read from disk. It is intended that the verifier functions will mark the buffer with an EFSCORRUPTED error when verification fails. This allows the reading context to distinguish a verification error from an IO error, and potentially take further actions on the buffer (e.g. attempt repair) based on the error reported. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Phil White <pwhite@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_buf.c')
-rw-r--r--fs/xfs/xfs_buf.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 4b0b8dd1b7b..0298dd68479 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -654,7 +654,8 @@ xfs_buf_read_map(
654 struct xfs_buftarg *target, 654 struct xfs_buftarg *target,
655 struct xfs_buf_map *map, 655 struct xfs_buf_map *map,
656 int nmaps, 656 int nmaps,
657 xfs_buf_flags_t flags) 657 xfs_buf_flags_t flags,
658 xfs_buf_iodone_t verify)
658{ 659{
659 struct xfs_buf *bp; 660 struct xfs_buf *bp;
660 661
@@ -666,6 +667,7 @@ xfs_buf_read_map(
666 667
667 if (!XFS_BUF_ISDONE(bp)) { 668 if (!XFS_BUF_ISDONE(bp)) {
668 XFS_STATS_INC(xb_get_read); 669 XFS_STATS_INC(xb_get_read);
670 bp->b_iodone = verify;
669 _xfs_buf_read(bp, flags); 671 _xfs_buf_read(bp, flags);
670 } else if (flags & XBF_ASYNC) { 672 } else if (flags & XBF_ASYNC) {
671 /* 673 /*
@@ -691,13 +693,14 @@ void
691xfs_buf_readahead_map( 693xfs_buf_readahead_map(
692 struct xfs_buftarg *target, 694 struct xfs_buftarg *target,
693 struct xfs_buf_map *map, 695 struct xfs_buf_map *map,
694 int nmaps) 696 int nmaps,
697 xfs_buf_iodone_t verify)
695{ 698{
696 if (bdi_read_congested(target->bt_bdi)) 699 if (bdi_read_congested(target->bt_bdi))
697 return; 700 return;
698 701
699 xfs_buf_read_map(target, map, nmaps, 702 xfs_buf_read_map(target, map, nmaps,
700 XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD); 703 XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD, verify);
701} 704}
702 705
703/* 706/*
@@ -709,7 +712,8 @@ xfs_buf_read_uncached(
709 struct xfs_buftarg *target, 712 struct xfs_buftarg *target,
710 xfs_daddr_t daddr, 713 xfs_daddr_t daddr,
711 size_t numblks, 714 size_t numblks,
712 int flags) 715 int flags,
716 xfs_buf_iodone_t verify)
713{ 717{
714 xfs_buf_t *bp; 718 xfs_buf_t *bp;
715 int error; 719 int error;
@@ -723,6 +727,7 @@ xfs_buf_read_uncached(
723 bp->b_bn = daddr; 727 bp->b_bn = daddr;
724 bp->b_maps[0].bm_bn = daddr; 728 bp->b_maps[0].bm_bn = daddr;
725 bp->b_flags |= XBF_READ; 729 bp->b_flags |= XBF_READ;
730 bp->b_iodone = verify;
726 731
727 xfsbdstrat(target->bt_mount, bp); 732 xfsbdstrat(target->bt_mount, bp);
728 error = xfs_buf_iowait(bp); 733 error = xfs_buf_iowait(bp);