error = xfs_trans_read_buf(
                        mp, tp, mp->m_ddev_targp,
                        XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
-                       XFS_FSS_TO_BB(mp, 1), 0, &bp);
+                       XFS_FSS_TO_BB(mp, 1), 0, &bp, NULL);
        if (error)
                return error;
        ASSERT(!xfs_buf_geterror(bp));
        error = xfs_trans_read_buf(
                        mp, tp, mp->m_ddev_targp,
                        XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
-                       XFS_FSS_TO_BB(mp, 1), flags, bpp);
+                       XFS_FSS_TO_BB(mp, 1), flags, bpp, NULL);
        if (error)
                return error;
        if (!*bpp)
 
                        dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock);
                        blkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
                        error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
-                                                  dblkno, blkcnt, 0, &bp);
+                                                  dblkno, blkcnt, 0, &bp, NULL);
                        if (error)
                                return(error);
 
 
        for (i = 0; i < new->bc_nlevels; i++) {
                new->bc_ptrs[i] = cur->bc_ptrs[i];
                new->bc_ra[i] = cur->bc_ra[i];
-               if ((bp = cur->bc_bufs[i])) {
-                       if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
-                               XFS_BUF_ADDR(bp), mp->m_bsize, 0, &bp))) {
+               bp = cur->bc_bufs[i];
+               if (bp) {
+                       error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
+                                                  XFS_BUF_ADDR(bp), mp->m_bsize,
+                                                  0, &bp, NULL);
+                       if (error) {
                                xfs_btree_del_cursor(new, error);
                                *ncur = NULL;
                                return error;
 
        ASSERT(fsbno != NULLFSBLOCK);
        d = XFS_FSB_TO_DADDR(mp, fsbno);
-       if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
-                       mp->m_bsize, lock, &bp))) {
+       error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
+                                  mp->m_bsize, lock, &bp, NULL);
+       if (error)
                return error;
-       }
        ASSERT(!xfs_buf_geterror(bp));
        if (bp)
                xfs_buf_set_ref(bp, refval);
 
        ASSERT(fsbno != NULLFSBLOCK);
        d = XFS_FSB_TO_DADDR(mp, fsbno);
-       xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count);
+       xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, NULL);
 }
 
 /*
        ASSERT(agno != NULLAGNUMBER);
        ASSERT(agbno != NULLAGBLOCK);
        d = XFS_AGB_TO_DADDR(mp, agno, agbno);
-       xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count);
+       xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, NULL);
 }
 
 STATIC int
 
        d = xfs_btree_ptr_to_daddr(cur, ptr);
        error = xfs_trans_read_buf(mp, cur->bc_tp, mp->m_ddev_targp, d,
-                                  mp->m_bsize, flags, bpp);
+                                  mp->m_bsize, flags, bpp, NULL);
        if (error)
                return error;
 
 
        struct xfs_buftarg      *target,
        struct xfs_buf_map      *map,
        int                     nmaps,
-       xfs_buf_flags_t         flags)
+       xfs_buf_flags_t         flags,
+       xfs_buf_iodone_t        verify)
 {
        struct xfs_buf          *bp;
 
 
                if (!XFS_BUF_ISDONE(bp)) {
                        XFS_STATS_INC(xb_get_read);
+                       bp->b_iodone = verify;
                        _xfs_buf_read(bp, flags);
                } else if (flags & XBF_ASYNC) {
                        /*
 xfs_buf_readahead_map(
        struct xfs_buftarg      *target,
        struct xfs_buf_map      *map,
-       int                     nmaps)
+       int                     nmaps,
+       xfs_buf_iodone_t        verify)
 {
        if (bdi_read_congested(target->bt_bdi))
                return;
 
        xfs_buf_read_map(target, map, nmaps,
-                    XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD);
+                    XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD, verify);
 }
 
 /*
        struct xfs_buftarg      *target,
        xfs_daddr_t             daddr,
        size_t                  numblks,
-       int                     flags)
+       int                     flags,
+       xfs_buf_iodone_t        verify)
 {
        xfs_buf_t               *bp;
        int                     error;
        bp->b_bn = daddr;
        bp->b_maps[0].bm_bn = daddr;
        bp->b_flags |= XBF_READ;
+       bp->b_iodone = verify;
 
        xfsbdstrat(target->bt_mount, bp);
        error = xfs_buf_iowait(bp);
 
 struct xfs_buf;
 typedef void (*xfs_buf_iodone_t)(struct xfs_buf *);
 
+
 #define XB_PAGES       2
 
 struct xfs_buf_map {
 #endif
 } xfs_buf_t;
 
-
 /* Finding and Reading Buffers */
 struct xfs_buf *_xfs_buf_find(struct xfs_buftarg *target,
                              struct xfs_buf_map *map, int nmaps,
                               xfs_buf_flags_t flags);
 struct xfs_buf *xfs_buf_read_map(struct xfs_buftarg *target,
                               struct xfs_buf_map *map, int nmaps,
-                              xfs_buf_flags_t flags);
+                              xfs_buf_flags_t flags, xfs_buf_iodone_t verify);
 void xfs_buf_readahead_map(struct xfs_buftarg *target,
-                              struct xfs_buf_map *map, int nmaps);
+                              struct xfs_buf_map *map, int nmaps,
+                              xfs_buf_iodone_t verify);
 
 static inline struct xfs_buf *
 xfs_buf_get(
        struct xfs_buftarg      *target,
        xfs_daddr_t             blkno,
        size_t                  numblks,
-       xfs_buf_flags_t         flags)
+       xfs_buf_flags_t         flags,
+       xfs_buf_iodone_t        verify)
 {
        DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
-       return xfs_buf_read_map(target, &map, 1, flags);
+       return xfs_buf_read_map(target, &map, 1, flags, verify);
 }
 
 static inline void
 xfs_buf_readahead(
        struct xfs_buftarg      *target,
        xfs_daddr_t             blkno,
-       size_t                  numblks)
+       size_t                  numblks,
+       xfs_buf_iodone_t        verify)
 {
        DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
-       return xfs_buf_readahead_map(target, &map, 1);
+       return xfs_buf_readahead_map(target, &map, 1, verify);
 }
 
 struct xfs_buf *xfs_buf_get_empty(struct xfs_buftarg *target, size_t numblks);
 struct xfs_buf *xfs_buf_get_uncached(struct xfs_buftarg *target, size_t numblks,
                                int flags);
 struct xfs_buf *xfs_buf_read_uncached(struct xfs_buftarg *target,
-                               xfs_daddr_t daddr, size_t numblks, int flags);
+                               xfs_daddr_t daddr, size_t numblks, int flags,
+                               xfs_buf_iodone_t verify);
 void xfs_buf_hold(struct xfs_buf *bp);
 
 /* Releasing Buffers */
 
 
        error = xfs_trans_read_buf_map(dp->i_mount, trans,
                                        dp->i_mount->m_ddev_targp,
-                                       mapp, nmap, 0, &bp);
+                                       mapp, nmap, 0, &bp, NULL);
        if (error)
                goto out_free;
 
        }
 
        mappedbno = mapp[0].bm_bn;
-       xfs_buf_readahead_map(dp->i_mount->m_ddev_targp, mapp, nmap);
+       xfs_buf_readahead_map(dp->i_mount->m_ddev_targp, mapp, nmap, NULL);
 
 out_free:
        if (mapp != &map)
 
                                XFS_FSB_TO_DADDR(mp,
                                        map[mip->ra_index].br_startblock +
                                                        mip->ra_offset),
-                               (int)BTOBB(mp->m_dirblksize));
+                               (int)BTOBB(mp->m_dirblksize), NULL);
                        mip->ra_current = i;
                }
 
 
                error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
                                           dqp->q_blkno,
                                           mp->m_quotainfo->qi_dqchunklen,
-                                          0, &bp);
+                                          0, &bp, NULL);
                if (error || !bp)
                        return XFS_ERROR(error);
        }
         * Get the buffer containing the on-disk dquot
         */
        error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno,
-                                  mp->m_quotainfo->qi_dqchunklen, 0, &bp);
+                                  mp->m_quotainfo->qi_dqchunklen, 0, &bp, NULL);
        if (error)
                goto out_unlock;
 
 
        dpct = pct - mp->m_sb.sb_imax_pct;
        bp = xfs_buf_read_uncached(mp->m_ddev_targp,
                                XFS_FSB_TO_BB(mp, nb) - XFS_FSS_TO_BB(mp, 1),
-                               XFS_FSS_TO_BB(mp, 1), 0);
+                               XFS_FSS_TO_BB(mp, 1), 0, NULL);
        if (!bp)
                return EIO;
        xfs_buf_relse(bp);
                if (agno < oagcount) {
                        error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
                                  XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
-                                 XFS_FSS_TO_BB(mp, 1), 0, &bp);
+                                 XFS_FSS_TO_BB(mp, 1), 0, &bp, NULL);
                } else {
                        bp = xfs_trans_get_buf(NULL, mp->m_ddev_targp,
                                  XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
 
 
        error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
                        XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
-                       XFS_FSS_TO_BB(mp, 1), 0, bpp);
+                       XFS_FSS_TO_BB(mp, 1), 0, bpp, NULL);
        if (error)
                return error;
 
 
 
        buf_flags |= XBF_UNMAPPED;
        error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno,
-                                  (int)imap->im_len, buf_flags, &bp);
+                                  (int)imap->im_len, buf_flags, &bp, NULL);
        if (error) {
                if (error != EAGAIN) {
                        xfs_warn(mp,
 
         * with it being freed after writing the unmount record to the
         * log.
         */
-
-}      /* xlog_iodone */
+}
 
 /*
  * Return size of each in-core log record buffer.
 
                buf_flags |= XBF_UNMAPPED;
 
        bp = xfs_buf_read(mp->m_ddev_targp, buf_f->blf_blkno, buf_f->blf_len,
-                         buf_flags);
+                         buf_flags, NULL);
        if (!bp)
                return XFS_ERROR(ENOMEM);
        error = bp->b_error;
        }
        trace_xfs_log_recover_inode_recover(log, in_f);
 
-       bp = xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len, 0);
+       bp = xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len, 0,
+                         NULL);
        if (!bp) {
                error = ENOMEM;
                goto error;
        ASSERT(dq_f->qlf_len == 1);
 
        error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dq_f->qlf_blkno,
-                                  XFS_FSB_TO_BB(mp, dq_f->qlf_len), 0, &bp);
+                                  XFS_FSB_TO_BB(mp, dq_f->qlf_len), 0, &bp,
+                                  NULL);
        if (error)
                return error;
 
 
 
 reread:
        bp = xfs_buf_read_uncached(mp->m_ddev_targp, XFS_SB_DADDR,
-                                       BTOBB(sector_size), 0);
+                                       BTOBB(sector_size), 0, NULL);
        if (!bp) {
                if (loud)
                        xfs_warn(mp, "SB buffer read failed");
        }
        bp = xfs_buf_read_uncached(mp->m_ddev_targp,
                                        d - XFS_FSS_TO_BB(mp, 1),
-                                       XFS_FSS_TO_BB(mp, 1), 0);
+                                       XFS_FSS_TO_BB(mp, 1), 0, NULL);
        if (!bp) {
                xfs_warn(mp, "last sector read failed");
                return EIO;
                }
                bp = xfs_buf_read_uncached(mp->m_logdev_targp,
                                        d - XFS_FSB_TO_BB(mp, 1),
-                                       XFS_FSB_TO_BB(mp, 1), 0);
+                                       XFS_FSB_TO_BB(mp, 1), 0, NULL);
                if (!bp) {
                        xfs_warn(mp, "log device read failed");
                        return EIO;
 
        while (blkcnt--) {
                error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
                              XFS_FSB_TO_DADDR(mp, bno),
-                             mp->m_quotainfo->qi_dqchunklen, 0, &bp);
+                             mp->m_quotainfo->qi_dqchunklen, 0, &bp, NULL);
                if (error)
                        break;
 
                                while (rablkcnt--) {
                                        xfs_buf_readahead(mp->m_ddev_targp,
                                               XFS_FSB_TO_DADDR(mp, rablkno),
-                                              mp->m_quotainfo->qi_dqchunklen);
+                                              mp->m_quotainfo->qi_dqchunklen,
+                                              NULL);
                                        rablkno++;
                                }
                        }
 
        ASSERT(map.br_startblock != NULLFSBLOCK);
        error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
                                   XFS_FSB_TO_DADDR(mp, map.br_startblock),
-                                  mp->m_bsize, 0, &bp);
+                                  mp->m_bsize, 0, &bp, NULL);
        if (error)
                return error;
        ASSERT(!xfs_buf_geterror(bp));
         */
        bp = xfs_buf_read_uncached(mp->m_rtdev_targp,
                                XFS_FSB_TO_BB(mp, nrblocks - 1),
-                               XFS_FSB_TO_BB(mp, 1), 0);
+                               XFS_FSB_TO_BB(mp, 1), 0, NULL);
        if (!bp)
                return EIO;
        xfs_buf_relse(bp);
        }
        bp = xfs_buf_read_uncached(mp->m_rtdev_targp,
                                        d - XFS_FSB_TO_BB(mp, 1),
-                                       XFS_FSB_TO_BB(mp, 1), 0);
+                                       XFS_FSB_TO_BB(mp, 1), 0, NULL);
        if (!bp) {
                xfs_warn(mp, "realtime device size check failed");
                return EIO;
 
        int                     numblks,
        uint                    flags)
 {
-       struct xfs_buf_map      map = {
-               .bm_bn = blkno,
-               .bm_len = numblks,
-       };
+       DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
        return xfs_trans_get_buf_map(tp, target, &map, 1, flags);
 }
 
                                       struct xfs_buftarg *target,
                                       struct xfs_buf_map *map, int nmaps,
                                       xfs_buf_flags_t flags,
-                                      struct xfs_buf **bpp);
+                                      struct xfs_buf **bpp,
+                                      xfs_buf_iodone_t verify);
 
 static inline int
 xfs_trans_read_buf(
        xfs_daddr_t             blkno,
        int                     numblks,
        xfs_buf_flags_t         flags,
-       struct xfs_buf          **bpp)
+       struct xfs_buf          **bpp,
+       xfs_buf_iodone_t        verify)
 {
-       struct xfs_buf_map      map = {
-               .bm_bn = blkno,
-               .bm_len = numblks,
-       };
-       return xfs_trans_read_buf_map(mp, tp, target, &map, 1, flags, bpp);
+       DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
+       return xfs_trans_read_buf_map(mp, tp, target, &map, 1,
+                                     flags, bpp, verify);
 }
 
 struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int);
 
        struct xfs_buf_map      *map,
        int                     nmaps,
        xfs_buf_flags_t         flags,
-       struct xfs_buf          **bpp)
+       struct xfs_buf          **bpp,
+       xfs_buf_iodone_t        verify)
 {
        xfs_buf_t               *bp;
        xfs_buf_log_item_t      *bip;
 
        *bpp = NULL;
        if (!tp) {
-               bp = xfs_buf_read_map(target, map, nmaps, flags);
+               bp = xfs_buf_read_map(target, map, nmaps, flags, verify);
                if (!bp)
                        return (flags & XBF_TRYLOCK) ?
                                        EAGAIN : XFS_ERROR(ENOMEM);
                if (!(XFS_BUF_ISDONE(bp))) {
                        trace_xfs_trans_read_buf_io(bp, _RET_IP_);
                        ASSERT(!XFS_BUF_ISASYNC(bp));
+                       ASSERT(bp->b_iodone == NULL);
                        XFS_BUF_READ(bp);
+                       bp->b_iodone = verify;
                        xfsbdstrat(tp->t_mountp, bp);
                        error = xfs_buf_iowait(bp);
                        if (error) {
                return 0;
        }
 
-       bp = xfs_buf_read_map(target, map, nmaps, flags);
+       bp = xfs_buf_read_map(target, map, nmaps, flags, verify);
        if (bp == NULL) {
                *bpp = NULL;
                return (flags & XBF_TRYLOCK) ?
 
                d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
                byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
 
-               bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0);
+               bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0, NULL);
                if (!bp)
                        return XFS_ERROR(ENOMEM);
                error = bp->b_error;