aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2012-11-14 01:54:40 -0500
committerBen Myers <bpm@sgi.com>2012-11-15 22:35:12 -0500
commit1813dd64057490e7a0678a885c4fe6d02f78bdc1 (patch)
treecaf95e2be7881b771da65561b2f1664d73588401 /fs
parentb0f539de9fcc543a3ffa40bc22bf51aca6ea6183 (diff)
xfs: convert buffer verifiers to an ops structure.
To separate the verifiers from iodone functions and associate read and write verifiers at the same time, introduce a buffer verifier operations structure to the xfs_buf. This avoids the need for assigning the write verifier, clearing the iodone function and re-running ioend processing in the read verifier, and gets rid of the nasty "b_pre_io" name for the write verifier function pointer. If we ever need to, it will also be easier to add further content specific callbacks to a buffer with an ops structure in place. We also avoid needing to export verifier functions, instead we can simply export the ops structures for those that are needed outside the function they are defined in. This patch also fixes a directory block readahead verifier issue it exposed. This patch also adds ops callbacks to the inode/alloc btree blocks initialised by growfs. These will need more work before they will work with CRCs. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Phil White <pwhite@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_ag.h4
-rw-r--r--fs/xfs/xfs_alloc.c28
-rw-r--r--fs/xfs/xfs_alloc.h4
-rw-r--r--fs/xfs/xfs_alloc_btree.c18
-rw-r--r--fs/xfs/xfs_alloc_btree.h2
-rw-r--r--fs/xfs/xfs_attr_leaf.c19
-rw-r--r--fs/xfs/xfs_attr_leaf.h3
-rw-r--r--fs/xfs/xfs_bmap.c22
-rw-r--r--fs/xfs/xfs_bmap_btree.c20
-rw-r--r--fs/xfs/xfs_bmap_btree.h3
-rw-r--r--fs/xfs/xfs_btree.c26
-rw-r--r--fs/xfs/xfs_btree.h9
-rw-r--r--fs/xfs/xfs_buf.c63
-rw-r--r--fs/xfs/xfs_buf.h24
-rw-r--r--fs/xfs/xfs_da_btree.c40
-rw-r--r--fs/xfs/xfs_da_btree.h4
-rw-r--r--fs/xfs/xfs_dir2_block.c20
-rw-r--r--fs/xfs/xfs_dir2_data.c52
-rw-r--r--fs/xfs/xfs_dir2_leaf.c36
-rw-r--r--fs/xfs/xfs_dir2_node.c26
-rw-r--r--fs/xfs/xfs_dir2_priv.h10
-rw-r--r--fs/xfs/xfs_dquot.c18
-rw-r--r--fs/xfs/xfs_dquot.h3
-rw-r--r--fs/xfs/xfs_fsops.c29
-rw-r--r--fs/xfs/xfs_ialloc.c18
-rw-r--r--fs/xfs/xfs_ialloc.h2
-rw-r--r--fs/xfs/xfs_ialloc_btree.c17
-rw-r--r--fs/xfs/xfs_ialloc_btree.h2
-rw-r--r--fs/xfs/xfs_inode.c22
-rw-r--r--fs/xfs/xfs_inode.h3
-rw-r--r--fs/xfs/xfs_itable.c2
-rw-r--r--fs/xfs/xfs_log_recover.c2
-rw-r--r--fs/xfs/xfs_mount.c35
-rw-r--r--fs/xfs/xfs_mount.h4
-rw-r--r--fs/xfs/xfs_qm.c2
-rw-r--r--fs/xfs/xfs_trans.h6
-rw-r--r--fs/xfs/xfs_trans_buf.c8
37 files changed, 357 insertions, 249 deletions
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
index 22bd4db011c8..f2aeedb6a579 100644
--- a/fs/xfs/xfs_ag.h
+++ b/fs/xfs/xfs_ag.h
@@ -108,6 +108,8 @@ typedef struct xfs_agf {
108extern int xfs_read_agf(struct xfs_mount *mp, struct xfs_trans *tp, 108extern int xfs_read_agf(struct xfs_mount *mp, struct xfs_trans *tp,
109 xfs_agnumber_t agno, int flags, struct xfs_buf **bpp); 109 xfs_agnumber_t agno, int flags, struct xfs_buf **bpp);
110 110
111extern const struct xfs_buf_ops xfs_agf_buf_ops;
112
111/* 113/*
112 * Size of the unlinked inode hash table in the agi. 114 * Size of the unlinked inode hash table in the agi.
113 */ 115 */
@@ -161,6 +163,8 @@ typedef struct xfs_agi {
161extern int xfs_read_agi(struct xfs_mount *mp, struct xfs_trans *tp, 163extern int xfs_read_agi(struct xfs_mount *mp, struct xfs_trans *tp,
162 xfs_agnumber_t agno, struct xfs_buf **bpp); 164 xfs_agnumber_t agno, struct xfs_buf **bpp);
163 165
166extern const struct xfs_buf_ops xfs_agi_buf_ops;
167
164/* 168/*
165 * The third a.g. block contains the a.g. freelist, an array 169 * The third a.g. block contains the a.g. freelist, an array
166 * of block pointers to blocks owned by the allocation btree code. 170 * of block pointers to blocks owned by the allocation btree code.
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index 545a6c4c2366..393055fe3aef 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -465,7 +465,7 @@ xfs_agfl_verify(
465#endif 465#endif
466} 466}
467 467
468void 468static void
469xfs_agfl_write_verify( 469xfs_agfl_write_verify(
470 struct xfs_buf *bp) 470 struct xfs_buf *bp)
471{ 471{
@@ -477,11 +477,13 @@ xfs_agfl_read_verify(
477 struct xfs_buf *bp) 477 struct xfs_buf *bp)
478{ 478{
479 xfs_agfl_verify(bp); 479 xfs_agfl_verify(bp);
480 bp->b_pre_io = xfs_agfl_write_verify;
481 bp->b_iodone = NULL;
482 xfs_buf_ioend(bp, 0);
483} 480}
484 481
482const struct xfs_buf_ops xfs_agfl_buf_ops = {
483 .verify_read = xfs_agfl_read_verify,
484 .verify_write = xfs_agfl_write_verify,
485};
486
485/* 487/*
486 * Read in the allocation group free block array. 488 * Read in the allocation group free block array.
487 */ 489 */
@@ -499,7 +501,7 @@ xfs_alloc_read_agfl(
499 error = xfs_trans_read_buf( 501 error = xfs_trans_read_buf(
500 mp, tp, mp->m_ddev_targp, 502 mp, tp, mp->m_ddev_targp,
501 XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), 503 XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
502 XFS_FSS_TO_BB(mp, 1), 0, &bp, xfs_agfl_read_verify); 504 XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_agfl_buf_ops);
503 if (error) 505 if (error)
504 return error; 506 return error;
505 ASSERT(!xfs_buf_geterror(bp)); 507 ASSERT(!xfs_buf_geterror(bp));
@@ -2181,23 +2183,25 @@ xfs_agf_verify(
2181 } 2183 }
2182} 2184}
2183 2185
2184void 2186static void
2185xfs_agf_write_verify( 2187xfs_agf_read_verify(
2186 struct xfs_buf *bp) 2188 struct xfs_buf *bp)
2187{ 2189{
2188 xfs_agf_verify(bp); 2190 xfs_agf_verify(bp);
2189} 2191}
2190 2192
2191static void 2193static void
2192xfs_agf_read_verify( 2194xfs_agf_write_verify(
2193 struct xfs_buf *bp) 2195 struct xfs_buf *bp)
2194{ 2196{
2195 xfs_agf_verify(bp); 2197 xfs_agf_verify(bp);
2196 bp->b_pre_io = xfs_agf_write_verify;
2197 bp->b_iodone = NULL;
2198 xfs_buf_ioend(bp, 0);
2199} 2198}
2200 2199
2200const struct xfs_buf_ops xfs_agf_buf_ops = {
2201 .verify_read = xfs_agf_read_verify,
2202 .verify_write = xfs_agf_write_verify,
2203};
2204
2201/* 2205/*
2202 * Read in the allocation group header (free/alloc section). 2206 * Read in the allocation group header (free/alloc section).
2203 */ 2207 */
@@ -2215,7 +2219,7 @@ xfs_read_agf(
2215 error = xfs_trans_read_buf( 2219 error = xfs_trans_read_buf(
2216 mp, tp, mp->m_ddev_targp, 2220 mp, tp, mp->m_ddev_targp,
2217 XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), 2221 XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
2218 XFS_FSS_TO_BB(mp, 1), flags, bpp, xfs_agf_read_verify); 2222 XFS_FSS_TO_BB(mp, 1), flags, bpp, &xfs_agf_buf_ops);
2219 if (error) 2223 if (error)
2220 return error; 2224 return error;
2221 if (!*bpp) 2225 if (!*bpp)
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h
index f32811f50f43..99d0a6101558 100644
--- a/fs/xfs/xfs_alloc.h
+++ b/fs/xfs/xfs_alloc.h
@@ -231,7 +231,7 @@ xfs_alloc_get_rec(
231 xfs_extlen_t *len, /* output: length of extent */ 231 xfs_extlen_t *len, /* output: length of extent */
232 int *stat); /* output: success/failure */ 232 int *stat); /* output: success/failure */
233 233
234void xfs_agf_write_verify(struct xfs_buf *bp); 234extern const struct xfs_buf_ops xfs_agf_buf_ops;
235void xfs_agfl_write_verify(struct xfs_buf *bp); 235extern const struct xfs_buf_ops xfs_agfl_buf_ops;
236 236
237#endif /* __XFS_ALLOC_H__ */ 237#endif /* __XFS_ALLOC_H__ */
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c
index b83396524913..b1ddef6b2689 100644
--- a/fs/xfs/xfs_alloc_btree.c
+++ b/fs/xfs/xfs_alloc_btree.c
@@ -329,22 +329,25 @@ xfs_allocbt_verify(
329} 329}
330 330
331static void 331static void
332xfs_allocbt_write_verify( 332xfs_allocbt_read_verify(
333 struct xfs_buf *bp) 333 struct xfs_buf *bp)
334{ 334{
335 xfs_allocbt_verify(bp); 335 xfs_allocbt_verify(bp);
336} 336}
337 337
338void 338static void
339xfs_allocbt_read_verify( 339xfs_allocbt_write_verify(
340 struct xfs_buf *bp) 340 struct xfs_buf *bp)
341{ 341{
342 xfs_allocbt_verify(bp); 342 xfs_allocbt_verify(bp);
343 bp->b_pre_io = xfs_allocbt_write_verify;
344 bp->b_iodone = NULL;
345 xfs_buf_ioend(bp, 0);
346} 343}
347 344
345const struct xfs_buf_ops xfs_allocbt_buf_ops = {
346 .verify_read = xfs_allocbt_read_verify,
347 .verify_write = xfs_allocbt_write_verify,
348};
349
350
348#ifdef DEBUG 351#ifdef DEBUG
349STATIC int 352STATIC int
350xfs_allocbt_keys_inorder( 353xfs_allocbt_keys_inorder(
@@ -400,8 +403,7 @@ static const struct xfs_btree_ops xfs_allocbt_ops = {
400 .init_rec_from_cur = xfs_allocbt_init_rec_from_cur, 403 .init_rec_from_cur = xfs_allocbt_init_rec_from_cur,
401 .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur, 404 .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur,
402 .key_diff = xfs_allocbt_key_diff, 405 .key_diff = xfs_allocbt_key_diff,
403 .read_verify = xfs_allocbt_read_verify, 406 .buf_ops = &xfs_allocbt_buf_ops,
404 .write_verify = xfs_allocbt_write_verify,
405#ifdef DEBUG 407#ifdef DEBUG
406 .keys_inorder = xfs_allocbt_keys_inorder, 408 .keys_inorder = xfs_allocbt_keys_inorder,
407 .recs_inorder = xfs_allocbt_recs_inorder, 409 .recs_inorder = xfs_allocbt_recs_inorder,
diff --git a/fs/xfs/xfs_alloc_btree.h b/fs/xfs/xfs_alloc_btree.h
index 359fb86ed876..7e89a2b429dd 100644
--- a/fs/xfs/xfs_alloc_btree.h
+++ b/fs/xfs/xfs_alloc_btree.h
@@ -93,4 +93,6 @@ extern struct xfs_btree_cur *xfs_allocbt_init_cursor(struct xfs_mount *,
93 xfs_agnumber_t, xfs_btnum_t); 93 xfs_agnumber_t, xfs_btnum_t);
94extern int xfs_allocbt_maxrecs(struct xfs_mount *, int, int); 94extern int xfs_allocbt_maxrecs(struct xfs_mount *, int, int);
95 95
96extern const struct xfs_buf_ops xfs_allocbt_buf_ops;
97
96#endif /* __XFS_ALLOC_BTREE_H__ */ 98#endif /* __XFS_ALLOC_BTREE_H__ */
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index 5cd5b0c1d17a..ee24993c7d12 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -104,22 +104,23 @@ xfs_attr_leaf_verify(
104} 104}
105 105
106static void 106static void
107xfs_attr_leaf_write_verify( 107xfs_attr_leaf_read_verify(
108 struct xfs_buf *bp) 108 struct xfs_buf *bp)
109{ 109{
110 xfs_attr_leaf_verify(bp); 110 xfs_attr_leaf_verify(bp);
111} 111}
112 112
113void 113static void
114xfs_attr_leaf_read_verify( 114xfs_attr_leaf_write_verify(
115 struct xfs_buf *bp) 115 struct xfs_buf *bp)
116{ 116{
117 xfs_attr_leaf_verify(bp); 117 xfs_attr_leaf_verify(bp);
118 bp->b_pre_io = xfs_attr_leaf_write_verify;
119 bp->b_iodone = NULL;
120 xfs_buf_ioend(bp, 0);
121} 118}
122 119
120const struct xfs_buf_ops xfs_attr_leaf_buf_ops = {
121 .verify_read = xfs_attr_leaf_read_verify,
122 .verify_write = xfs_attr_leaf_write_verify,
123};
123 124
124int 125int
125xfs_attr_leaf_read( 126xfs_attr_leaf_read(
@@ -130,7 +131,7 @@ xfs_attr_leaf_read(
130 struct xfs_buf **bpp) 131 struct xfs_buf **bpp)
131{ 132{
132 return xfs_da_read_buf(tp, dp, bno, mappedbno, bpp, 133 return xfs_da_read_buf(tp, dp, bno, mappedbno, bpp,
133 XFS_ATTR_FORK, xfs_attr_leaf_read_verify); 134 XFS_ATTR_FORK, &xfs_attr_leaf_buf_ops);
134} 135}
135 136
136/*======================================================================== 137/*========================================================================
@@ -924,7 +925,7 @@ xfs_attr_leaf_to_node(xfs_da_args_t *args)
924 XFS_ATTR_FORK); 925 XFS_ATTR_FORK);
925 if (error) 926 if (error)
926 goto out; 927 goto out;
927 bp2->b_pre_io = bp1->b_pre_io; 928 bp2->b_ops = bp1->b_ops;
928 memcpy(bp2->b_addr, bp1->b_addr, XFS_LBSIZE(dp->i_mount)); 929 memcpy(bp2->b_addr, bp1->b_addr, XFS_LBSIZE(dp->i_mount));
929 bp1 = NULL; 930 bp1 = NULL;
930 xfs_trans_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1); 931 xfs_trans_log_buf(args->trans, bp2, 0, XFS_LBSIZE(dp->i_mount) - 1);
@@ -978,7 +979,7 @@ xfs_attr_leaf_create(
978 XFS_ATTR_FORK); 979 XFS_ATTR_FORK);
979 if (error) 980 if (error)
980 return(error); 981 return(error);
981 bp->b_pre_io = xfs_attr_leaf_write_verify; 982 bp->b_ops = &xfs_attr_leaf_buf_ops;
982 leaf = bp->b_addr; 983 leaf = bp->b_addr;
983 memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount)); 984 memset((char *)leaf, 0, XFS_LBSIZE(dp->i_mount));
984 hdr = &leaf->hdr; 985 hdr = &leaf->hdr;
diff --git a/fs/xfs/xfs_attr_leaf.h b/fs/xfs/xfs_attr_leaf.h
index 3bbf6277e43c..77de139a58f0 100644
--- a/fs/xfs/xfs_attr_leaf.h
+++ b/fs/xfs/xfs_attr_leaf.h
@@ -264,6 +264,7 @@ int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize,
264int xfs_attr_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp, 264int xfs_attr_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp,
265 xfs_dablk_t bno, xfs_daddr_t mappedbno, 265 xfs_dablk_t bno, xfs_daddr_t mappedbno,
266 struct xfs_buf **bpp); 266 struct xfs_buf **bpp);
267void xfs_attr_leaf_read_verify(struct xfs_buf *bp); 267
268extern const struct xfs_buf_ops xfs_attr_leaf_buf_ops;
268 269
269#endif /* __XFS_ATTR_LEAF_H__ */ 270#endif /* __XFS_ATTR_LEAF_H__ */
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 6a0f3f9f39d3..0e92d12765d2 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -2663,7 +2663,7 @@ xfs_bmap_btree_to_extents(
2663 return error; 2663 return error;
2664#endif 2664#endif
2665 error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, XFS_BMAP_BTREE_REF, 2665 error = xfs_btree_read_bufl(mp, tp, cbno, 0, &cbp, XFS_BMAP_BTREE_REF,
2666 xfs_bmbt_read_verify); 2666 &xfs_bmbt_buf_ops);
2667 if (error) 2667 if (error)
2668 return error; 2668 return error;
2669 cblock = XFS_BUF_TO_BLOCK(cbp); 2669 cblock = XFS_BUF_TO_BLOCK(cbp);
@@ -3124,7 +3124,7 @@ xfs_bmap_extents_to_btree(
3124 /* 3124 /*
3125 * Fill in the child block. 3125 * Fill in the child block.
3126 */ 3126 */
3127 abp->b_pre_io = xfs_bmbt_write_verify; 3127 abp->b_ops = &xfs_bmbt_buf_ops;
3128 ablock = XFS_BUF_TO_BLOCK(abp); 3128 ablock = XFS_BUF_TO_BLOCK(abp);
3129 ablock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC); 3129 ablock->bb_magic = cpu_to_be32(XFS_BMAP_MAGIC);
3130 ablock->bb_level = 0; 3130 ablock->bb_level = 0;
@@ -3271,7 +3271,7 @@ xfs_bmap_local_to_extents(
3271 ASSERT(args.len == 1); 3271 ASSERT(args.len == 1);
3272 *firstblock = args.fsbno; 3272 *firstblock = args.fsbno;
3273 bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0); 3273 bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0);
3274 bp->b_pre_io = xfs_bmbt_write_verify; 3274 bp->b_ops = &xfs_bmbt_buf_ops;
3275 memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes); 3275 memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes);
3276 xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1); 3276 xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1);
3277 xfs_bmap_forkoff_reset(args.mp, ip, whichfork); 3277 xfs_bmap_forkoff_reset(args.mp, ip, whichfork);
@@ -4082,7 +4082,7 @@ xfs_bmap_read_extents(
4082 */ 4082 */
4083 while (level-- > 0) { 4083 while (level-- > 0) {
4084 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, 4084 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
4085 XFS_BMAP_BTREE_REF, xfs_bmbt_read_verify); 4085 XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops);
4086 if (error) 4086 if (error)
4087 return error; 4087 return error;
4088 block = XFS_BUF_TO_BLOCK(bp); 4088 block = XFS_BUF_TO_BLOCK(bp);
@@ -4129,7 +4129,7 @@ xfs_bmap_read_extents(
4129 nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib); 4129 nextbno = be64_to_cpu(block->bb_u.l.bb_rightsib);
4130 if (nextbno != NULLFSBLOCK) 4130 if (nextbno != NULLFSBLOCK)
4131 xfs_btree_reada_bufl(mp, nextbno, 1, 4131 xfs_btree_reada_bufl(mp, nextbno, 1,
4132 xfs_bmbt_read_verify); 4132 &xfs_bmbt_buf_ops);
4133 /* 4133 /*
4134 * Copy records into the extent records. 4134 * Copy records into the extent records.
4135 */ 4135 */
@@ -4162,7 +4162,7 @@ xfs_bmap_read_extents(
4162 if (bno == NULLFSBLOCK) 4162 if (bno == NULLFSBLOCK)
4163 break; 4163 break;
4164 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, 4164 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
4165 XFS_BMAP_BTREE_REF, xfs_bmbt_read_verify); 4165 XFS_BMAP_BTREE_REF, &xfs_bmbt_buf_ops);
4166 if (error) 4166 if (error)
4167 return error; 4167 return error;
4168 block = XFS_BUF_TO_BLOCK(bp); 4168 block = XFS_BUF_TO_BLOCK(bp);
@@ -5880,7 +5880,7 @@ xfs_bmap_check_leaf_extents(
5880 bp_release = 1; 5880 bp_release = 1;
5881 error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp, 5881 error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp,
5882 XFS_BMAP_BTREE_REF, 5882 XFS_BMAP_BTREE_REF,
5883 xfs_bmbt_read_verify); 5883 &xfs_bmbt_buf_ops);
5884 if (error) 5884 if (error)
5885 goto error_norelse; 5885 goto error_norelse;
5886 } 5886 }
@@ -5966,7 +5966,7 @@ xfs_bmap_check_leaf_extents(
5966 bp_release = 1; 5966 bp_release = 1;
5967 error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp, 5967 error = xfs_btree_read_bufl(mp, NULL, bno, 0, &bp,
5968 XFS_BMAP_BTREE_REF, 5968 XFS_BMAP_BTREE_REF,
5969 xfs_bmbt_read_verify); 5969 &xfs_bmbt_buf_ops);
5970 if (error) 5970 if (error)
5971 goto error_norelse; 5971 goto error_norelse;
5972 } 5972 }
@@ -6061,7 +6061,7 @@ xfs_bmap_count_tree(
6061 int numrecs; 6061 int numrecs;
6062 6062
6063 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF, 6063 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, XFS_BMAP_BTREE_REF,
6064 xfs_bmbt_read_verify); 6064 &xfs_bmbt_buf_ops);
6065 if (error) 6065 if (error)
6066 return error; 6066 return error;
6067 *count += 1; 6067 *count += 1;
@@ -6073,7 +6073,7 @@ xfs_bmap_count_tree(
6073 while (nextbno != NULLFSBLOCK) { 6073 while (nextbno != NULLFSBLOCK) {
6074 error = xfs_btree_read_bufl(mp, tp, nextbno, 0, &nbp, 6074 error = xfs_btree_read_bufl(mp, tp, nextbno, 0, &nbp,
6075 XFS_BMAP_BTREE_REF, 6075 XFS_BMAP_BTREE_REF,
6076 xfs_bmbt_read_verify); 6076 &xfs_bmbt_buf_ops);
6077 if (error) 6077 if (error)
6078 return error; 6078 return error;
6079 *count += 1; 6079 *count += 1;
@@ -6105,7 +6105,7 @@ xfs_bmap_count_tree(
6105 bno = nextbno; 6105 bno = nextbno;
6106 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp, 6106 error = xfs_btree_read_bufl(mp, tp, bno, 0, &bp,
6107 XFS_BMAP_BTREE_REF, 6107 XFS_BMAP_BTREE_REF,
6108 xfs_bmbt_read_verify); 6108 &xfs_bmbt_buf_ops);
6109 if (error) 6109 if (error)
6110 return error; 6110 return error;
6111 *count += 1; 6111 *count += 1;
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 79758e1e4f74..061b45cbe614 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -749,23 +749,26 @@ xfs_bmbt_verify(
749 } 749 }
750} 750}
751 751
752void 752static void
753xfs_bmbt_write_verify( 753xfs_bmbt_read_verify(
754 struct xfs_buf *bp) 754 struct xfs_buf *bp)
755{ 755{
756 xfs_bmbt_verify(bp); 756 xfs_bmbt_verify(bp);
757} 757}
758 758
759void 759static void
760xfs_bmbt_read_verify( 760xfs_bmbt_write_verify(
761 struct xfs_buf *bp) 761 struct xfs_buf *bp)
762{ 762{
763 xfs_bmbt_verify(bp); 763 xfs_bmbt_verify(bp);
764 bp->b_pre_io = xfs_bmbt_write_verify;
765 bp->b_iodone = NULL;
766 xfs_buf_ioend(bp, 0);
767} 764}
768 765
766const struct xfs_buf_ops xfs_bmbt_buf_ops = {
767 .verify_read = xfs_bmbt_read_verify,
768 .verify_write = xfs_bmbt_write_verify,
769};
770
771
769#ifdef DEBUG 772#ifdef DEBUG
770STATIC int 773STATIC int
771xfs_bmbt_keys_inorder( 774xfs_bmbt_keys_inorder(
@@ -805,8 +808,7 @@ static const struct xfs_btree_ops xfs_bmbt_ops = {
805 .init_rec_from_cur = xfs_bmbt_init_rec_from_cur, 808 .init_rec_from_cur = xfs_bmbt_init_rec_from_cur,
806 .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur, 809 .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur,
807 .key_diff = xfs_bmbt_key_diff, 810 .key_diff = xfs_bmbt_key_diff,
808 .read_verify = xfs_bmbt_read_verify, 811 .buf_ops = &xfs_bmbt_buf_ops,
809 .write_verify = xfs_bmbt_write_verify,
810#ifdef DEBUG 812#ifdef DEBUG
811 .keys_inorder = xfs_bmbt_keys_inorder, 813 .keys_inorder = xfs_bmbt_keys_inorder,
812 .recs_inorder = xfs_bmbt_recs_inorder, 814 .recs_inorder = xfs_bmbt_recs_inorder,
diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h
index 938c85986549..88469ca08696 100644
--- a/fs/xfs/xfs_bmap_btree.h
+++ b/fs/xfs/xfs_bmap_btree.h
@@ -232,11 +232,10 @@ extern void xfs_bmbt_to_bmdr(struct xfs_mount *, struct xfs_btree_block *, int,
232extern int xfs_bmbt_get_maxrecs(struct xfs_btree_cur *, int level); 232extern int xfs_bmbt_get_maxrecs(struct xfs_btree_cur *, int level);
233extern int xfs_bmdr_maxrecs(struct xfs_mount *, int blocklen, int leaf); 233extern int xfs_bmdr_maxrecs(struct xfs_mount *, int blocklen, int leaf);
234extern int xfs_bmbt_maxrecs(struct xfs_mount *, int blocklen, int leaf); 234extern int xfs_bmbt_maxrecs(struct xfs_mount *, int blocklen, int leaf);
235extern void xfs_bmbt_read_verify(struct xfs_buf *bp);
236extern void xfs_bmbt_write_verify(struct xfs_buf *bp);
237 235
238extern struct xfs_btree_cur *xfs_bmbt_init_cursor(struct xfs_mount *, 236extern struct xfs_btree_cur *xfs_bmbt_init_cursor(struct xfs_mount *,
239 struct xfs_trans *, struct xfs_inode *, int); 237 struct xfs_trans *, struct xfs_inode *, int);
240 238
239extern const struct xfs_buf_ops xfs_bmbt_buf_ops;
241 240
242#endif /* __XFS_BMAP_BTREE_H__ */ 241#endif /* __XFS_BMAP_BTREE_H__ */
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index 1e2d89eed2a4..db010408d701 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -271,7 +271,7 @@ xfs_btree_dup_cursor(
271 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, 271 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
272 XFS_BUF_ADDR(bp), mp->m_bsize, 272 XFS_BUF_ADDR(bp), mp->m_bsize,
273 0, &bp, 273 0, &bp,
274 cur->bc_ops->read_verify); 274 cur->bc_ops->buf_ops);
275 if (error) { 275 if (error) {
276 xfs_btree_del_cursor(new, error); 276 xfs_btree_del_cursor(new, error);
277 *ncur = NULL; 277 *ncur = NULL;
@@ -621,7 +621,7 @@ xfs_btree_read_bufl(
621 uint lock, /* lock flags for read_buf */ 621 uint lock, /* lock flags for read_buf */
622 struct xfs_buf **bpp, /* buffer for fsbno */ 622 struct xfs_buf **bpp, /* buffer for fsbno */
623 int refval, /* ref count value for buffer */ 623 int refval, /* ref count value for buffer */
624 xfs_buf_iodone_t verify) 624 const struct xfs_buf_ops *ops)
625{ 625{
626 struct xfs_buf *bp; /* return value */ 626 struct xfs_buf *bp; /* return value */
627 xfs_daddr_t d; /* real disk block address */ 627 xfs_daddr_t d; /* real disk block address */
@@ -630,7 +630,7 @@ xfs_btree_read_bufl(
630 ASSERT(fsbno != NULLFSBLOCK); 630 ASSERT(fsbno != NULLFSBLOCK);
631 d = XFS_FSB_TO_DADDR(mp, fsbno); 631 d = XFS_FSB_TO_DADDR(mp, fsbno);
632 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d, 632 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
633 mp->m_bsize, lock, &bp, verify); 633 mp->m_bsize, lock, &bp, ops);
634 if (error) 634 if (error)
635 return error; 635 return error;
636 ASSERT(!xfs_buf_geterror(bp)); 636 ASSERT(!xfs_buf_geterror(bp));
@@ -650,13 +650,13 @@ xfs_btree_reada_bufl(
650 struct xfs_mount *mp, /* file system mount point */ 650 struct xfs_mount *mp, /* file system mount point */
651 xfs_fsblock_t fsbno, /* file system block number */ 651 xfs_fsblock_t fsbno, /* file system block number */
652 xfs_extlen_t count, /* count of filesystem blocks */ 652 xfs_extlen_t count, /* count of filesystem blocks */
653 xfs_buf_iodone_t verify) 653 const struct xfs_buf_ops *ops)
654{ 654{
655 xfs_daddr_t d; 655 xfs_daddr_t d;
656 656
657 ASSERT(fsbno != NULLFSBLOCK); 657 ASSERT(fsbno != NULLFSBLOCK);
658 d = XFS_FSB_TO_DADDR(mp, fsbno); 658 d = XFS_FSB_TO_DADDR(mp, fsbno);
659 xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, verify); 659 xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, ops);
660} 660}
661 661
662/* 662/*
@@ -670,14 +670,14 @@ xfs_btree_reada_bufs(
670 xfs_agnumber_t agno, /* allocation group number */ 670 xfs_agnumber_t agno, /* allocation group number */
671 xfs_agblock_t agbno, /* allocation group block number */ 671 xfs_agblock_t agbno, /* allocation group block number */
672 xfs_extlen_t count, /* count of filesystem blocks */ 672 xfs_extlen_t count, /* count of filesystem blocks */
673 xfs_buf_iodone_t verify) 673 const struct xfs_buf_ops *ops)
674{ 674{
675 xfs_daddr_t d; 675 xfs_daddr_t d;
676 676
677 ASSERT(agno != NULLAGNUMBER); 677 ASSERT(agno != NULLAGNUMBER);
678 ASSERT(agbno != NULLAGBLOCK); 678 ASSERT(agbno != NULLAGBLOCK);
679 d = XFS_AGB_TO_DADDR(mp, agno, agbno); 679 d = XFS_AGB_TO_DADDR(mp, agno, agbno);
680 xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, verify); 680 xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, ops);
681} 681}
682 682
683STATIC int 683STATIC int
@@ -692,13 +692,13 @@ xfs_btree_readahead_lblock(
692 692
693 if ((lr & XFS_BTCUR_LEFTRA) && left != NULLDFSBNO) { 693 if ((lr & XFS_BTCUR_LEFTRA) && left != NULLDFSBNO) {
694 xfs_btree_reada_bufl(cur->bc_mp, left, 1, 694 xfs_btree_reada_bufl(cur->bc_mp, left, 1,
695 cur->bc_ops->read_verify); 695 cur->bc_ops->buf_ops);
696 rval++; 696 rval++;
697 } 697 }
698 698
699 if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLDFSBNO) { 699 if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLDFSBNO) {
700 xfs_btree_reada_bufl(cur->bc_mp, right, 1, 700 xfs_btree_reada_bufl(cur->bc_mp, right, 1,
701 cur->bc_ops->read_verify); 701 cur->bc_ops->buf_ops);
702 rval++; 702 rval++;
703 } 703 }
704 704
@@ -718,13 +718,13 @@ xfs_btree_readahead_sblock(
718 718
719 if ((lr & XFS_BTCUR_LEFTRA) && left != NULLAGBLOCK) { 719 if ((lr & XFS_BTCUR_LEFTRA) && left != NULLAGBLOCK) {
720 xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, 720 xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
721 left, 1, cur->bc_ops->read_verify); 721 left, 1, cur->bc_ops->buf_ops);
722 rval++; 722 rval++;
723 } 723 }
724 724
725 if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLAGBLOCK) { 725 if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLAGBLOCK) {
726 xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, 726 xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno,
727 right, 1, cur->bc_ops->read_verify); 727 right, 1, cur->bc_ops->buf_ops);
728 rval++; 728 rval++;
729 } 729 }
730 730
@@ -996,7 +996,7 @@ xfs_btree_get_buf_block(
996 if (!*bpp) 996 if (!*bpp)
997 return ENOMEM; 997 return ENOMEM;
998 998
999 (*bpp)->b_pre_io = cur->bc_ops->write_verify; 999 (*bpp)->b_ops = cur->bc_ops->buf_ops;
1000 *block = XFS_BUF_TO_BLOCK(*bpp); 1000 *block = XFS_BUF_TO_BLOCK(*bpp);
1001 return 0; 1001 return 0;
1002} 1002}
@@ -1024,7 +1024,7 @@ xfs_btree_read_buf_block(
1024 d = xfs_btree_ptr_to_daddr(cur, ptr); 1024 d = xfs_btree_ptr_to_daddr(cur, ptr);
1025 error = xfs_trans_read_buf(mp, cur->bc_tp, mp->m_ddev_targp, d, 1025 error = xfs_trans_read_buf(mp, cur->bc_tp, mp->m_ddev_targp, d,
1026 mp->m_bsize, flags, bpp, 1026 mp->m_bsize, flags, bpp,
1027 cur->bc_ops->read_verify); 1027 cur->bc_ops->buf_ops);
1028 if (error) 1028 if (error)
1029 return error; 1029 return error;
1030 1030
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h
index 458ab3550898..f932897194eb 100644
--- a/fs/xfs/xfs_btree.h
+++ b/fs/xfs/xfs_btree.h
@@ -188,8 +188,7 @@ struct xfs_btree_ops {
188 __int64_t (*key_diff)(struct xfs_btree_cur *cur, 188 __int64_t (*key_diff)(struct xfs_btree_cur *cur,
189 union xfs_btree_key *key); 189 union xfs_btree_key *key);
190 190
191 void (*read_verify)(struct xfs_buf *bp); 191 const struct xfs_buf_ops *buf_ops;
192 void (*write_verify)(struct xfs_buf *bp);
193 192
194#ifdef DEBUG 193#ifdef DEBUG
195 /* check that k1 is lower than k2 */ 194 /* check that k1 is lower than k2 */
@@ -359,7 +358,7 @@ xfs_btree_read_bufl(
359 uint lock, /* lock flags for read_buf */ 358 uint lock, /* lock flags for read_buf */
360 struct xfs_buf **bpp, /* buffer for fsbno */ 359 struct xfs_buf **bpp, /* buffer for fsbno */
361 int refval, /* ref count value for buffer */ 360 int refval, /* ref count value for buffer */
362 xfs_buf_iodone_t verify); 361 const struct xfs_buf_ops *ops);
363 362
364/* 363/*
365 * Read-ahead the block, don't wait for it, don't return a buffer. 364 * Read-ahead the block, don't wait for it, don't return a buffer.
@@ -370,7 +369,7 @@ xfs_btree_reada_bufl(
370 struct xfs_mount *mp, /* file system mount point */ 369 struct xfs_mount *mp, /* file system mount point */
371 xfs_fsblock_t fsbno, /* file system block number */ 370 xfs_fsblock_t fsbno, /* file system block number */
372 xfs_extlen_t count, /* count of filesystem blocks */ 371 xfs_extlen_t count, /* count of filesystem blocks */
373 xfs_buf_iodone_t verify); 372 const struct xfs_buf_ops *ops);
374 373
375/* 374/*
376 * Read-ahead the block, don't wait for it, don't return a buffer. 375 * Read-ahead the block, don't wait for it, don't return a buffer.
@@ -382,7 +381,7 @@ xfs_btree_reada_bufs(
382 xfs_agnumber_t agno, /* allocation group number */ 381 xfs_agnumber_t agno, /* allocation group number */
383 xfs_agblock_t agbno, /* allocation group block number */ 382 xfs_agblock_t agbno, /* allocation group block number */
384 xfs_extlen_t count, /* count of filesystem blocks */ 383 xfs_extlen_t count, /* count of filesystem blocks */
385 xfs_buf_iodone_t verify); 384 const struct xfs_buf_ops *ops);
386 385
387/* 386/*
388 * Initialise a new btree block header 387 * Initialise a new btree block header
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index bd1a948ee39c..26673a0b20e7 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -571,7 +571,7 @@ found:
571 ASSERT((bp->b_flags & _XBF_DELWRI_Q) == 0); 571 ASSERT((bp->b_flags & _XBF_DELWRI_Q) == 0);
572 ASSERT(bp->b_iodone == NULL); 572 ASSERT(bp->b_iodone == NULL);
573 bp->b_flags &= _XBF_KMEM | _XBF_PAGES; 573 bp->b_flags &= _XBF_KMEM | _XBF_PAGES;
574 bp->b_pre_io = NULL; 574 bp->b_ops = NULL;
575 } 575 }
576 576
577 trace_xfs_buf_find(bp, flags, _RET_IP_); 577 trace_xfs_buf_find(bp, flags, _RET_IP_);
@@ -657,7 +657,7 @@ xfs_buf_read_map(
657 struct xfs_buf_map *map, 657 struct xfs_buf_map *map,
658 int nmaps, 658 int nmaps,
659 xfs_buf_flags_t flags, 659 xfs_buf_flags_t flags,
660 xfs_buf_iodone_t verify) 660 const struct xfs_buf_ops *ops)
661{ 661{
662 struct xfs_buf *bp; 662 struct xfs_buf *bp;
663 663
@@ -669,7 +669,7 @@ xfs_buf_read_map(
669 669
670 if (!XFS_BUF_ISDONE(bp)) { 670 if (!XFS_BUF_ISDONE(bp)) {
671 XFS_STATS_INC(xb_get_read); 671 XFS_STATS_INC(xb_get_read);
672 bp->b_iodone = verify; 672 bp->b_ops = ops;
673 _xfs_buf_read(bp, flags); 673 _xfs_buf_read(bp, flags);
674 } else if (flags & XBF_ASYNC) { 674 } else if (flags & XBF_ASYNC) {
675 /* 675 /*
@@ -696,13 +696,13 @@ xfs_buf_readahead_map(
696 struct xfs_buftarg *target, 696 struct xfs_buftarg *target,
697 struct xfs_buf_map *map, 697 struct xfs_buf_map *map,
698 int nmaps, 698 int nmaps,
699 xfs_buf_iodone_t verify) 699 const struct xfs_buf_ops *ops)
700{ 700{
701 if (bdi_read_congested(target->bt_bdi)) 701 if (bdi_read_congested(target->bt_bdi))
702 return; 702 return;
703 703
704 xfs_buf_read_map(target, map, nmaps, 704 xfs_buf_read_map(target, map, nmaps,
705 XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD, verify); 705 XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD, ops);
706} 706}
707 707
708/* 708/*
@@ -715,7 +715,7 @@ xfs_buf_read_uncached(
715 xfs_daddr_t daddr, 715 xfs_daddr_t daddr,
716 size_t numblks, 716 size_t numblks,
717 int flags, 717 int flags,
718 xfs_buf_iodone_t verify) 718 const struct xfs_buf_ops *ops)
719{ 719{
720 struct xfs_buf *bp; 720 struct xfs_buf *bp;
721 721
@@ -728,7 +728,7 @@ xfs_buf_read_uncached(
728 bp->b_bn = daddr; 728 bp->b_bn = daddr;
729 bp->b_maps[0].bm_bn = daddr; 729 bp->b_maps[0].bm_bn = daddr;
730 bp->b_flags |= XBF_READ; 730 bp->b_flags |= XBF_READ;
731 bp->b_iodone = verify; 731 bp->b_ops = ops;
732 732
733 xfsbdstrat(target->bt_mount, bp); 733 xfsbdstrat(target->bt_mount, bp);
734 xfs_buf_iowait(bp); 734 xfs_buf_iowait(bp);
@@ -1001,27 +1001,37 @@ STATIC void
1001xfs_buf_iodone_work( 1001xfs_buf_iodone_work(
1002 struct work_struct *work) 1002 struct work_struct *work)
1003{ 1003{
1004 xfs_buf_t *bp = 1004 struct xfs_buf *bp =
1005 container_of(work, xfs_buf_t, b_iodone_work); 1005 container_of(work, xfs_buf_t, b_iodone_work);
1006 bool read = !!(bp->b_flags & XBF_READ);
1007
1008 bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_READ_AHEAD);
1009 if (read && bp->b_ops)
1010 bp->b_ops->verify_read(bp);
1006 1011
1007 if (bp->b_iodone) 1012 if (bp->b_iodone)
1008 (*(bp->b_iodone))(bp); 1013 (*(bp->b_iodone))(bp);
1009 else if (bp->b_flags & XBF_ASYNC) 1014 else if (bp->b_flags & XBF_ASYNC)
1010 xfs_buf_relse(bp); 1015 xfs_buf_relse(bp);
1016 else {
1017 ASSERT(read && bp->b_ops);
1018 complete(&bp->b_iowait);
1019 }
1011} 1020}
1012 1021
1013void 1022void
1014xfs_buf_ioend( 1023xfs_buf_ioend(
1015 xfs_buf_t *bp, 1024 struct xfs_buf *bp,
1016 int schedule) 1025 int schedule)
1017{ 1026{
1027 bool read = !!(bp->b_flags & XBF_READ);
1028
1018 trace_xfs_buf_iodone(bp, _RET_IP_); 1029 trace_xfs_buf_iodone(bp, _RET_IP_);
1019 1030
1020 bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_READ_AHEAD);
1021 if (bp->b_error == 0) 1031 if (bp->b_error == 0)
1022 bp->b_flags |= XBF_DONE; 1032 bp->b_flags |= XBF_DONE;
1023 1033
1024 if ((bp->b_iodone) || (bp->b_flags & XBF_ASYNC)) { 1034 if (bp->b_iodone || (read && bp->b_ops) || (bp->b_flags & XBF_ASYNC)) {
1025 if (schedule) { 1035 if (schedule) {
1026 INIT_WORK(&bp->b_iodone_work, xfs_buf_iodone_work); 1036 INIT_WORK(&bp->b_iodone_work, xfs_buf_iodone_work);
1027 queue_work(xfslogd_workqueue, &bp->b_iodone_work); 1037 queue_work(xfslogd_workqueue, &bp->b_iodone_work);
@@ -1029,6 +1039,7 @@ xfs_buf_ioend(
1029 xfs_buf_iodone_work(&bp->b_iodone_work); 1039 xfs_buf_iodone_work(&bp->b_iodone_work);
1030 } 1040 }
1031 } else { 1041 } else {
1042 bp->b_flags &= ~(XBF_READ | XBF_WRITE | XBF_READ_AHEAD);
1032 complete(&bp->b_iowait); 1043 complete(&bp->b_iowait);
1033 } 1044 }
1034} 1045}
@@ -1316,6 +1327,20 @@ _xfs_buf_ioapply(
1316 rw |= REQ_FUA; 1327 rw |= REQ_FUA;
1317 if (bp->b_flags & XBF_FLUSH) 1328 if (bp->b_flags & XBF_FLUSH)
1318 rw |= REQ_FLUSH; 1329 rw |= REQ_FLUSH;
1330
1331 /*
1332 * Run the write verifier callback function if it exists. If
1333 * this function fails it will mark the buffer with an error and
1334 * the IO should not be dispatched.
1335 */
1336 if (bp->b_ops) {
1337 bp->b_ops->verify_write(bp);
1338 if (bp->b_error) {
1339 xfs_force_shutdown(bp->b_target->bt_mount,
1340 SHUTDOWN_CORRUPT_INCORE);
1341 return;
1342 }
1343 }
1319 } else if (bp->b_flags & XBF_READ_AHEAD) { 1344 } else if (bp->b_flags & XBF_READ_AHEAD) {
1320 rw = READA; 1345 rw = READA;
1321 } else { 1346 } else {
@@ -1326,20 +1351,6 @@ _xfs_buf_ioapply(
1326 rw |= REQ_META; 1351 rw |= REQ_META;
1327 1352
1328 /* 1353 /*
1329 * run the pre-io callback function if it exists. If this function
1330 * fails it will mark the buffer with an error and the IO should
1331 * not be dispatched.
1332 */
1333 if (bp->b_pre_io) {
1334 bp->b_pre_io(bp);
1335 if (bp->b_error) {
1336 xfs_force_shutdown(bp->b_target->bt_mount,
1337 SHUTDOWN_CORRUPT_INCORE);
1338 return;
1339 }
1340 }
1341
1342 /*
1343 * Walk all the vectors issuing IO on them. Set up the initial offset 1354 * Walk all the vectors issuing IO on them. Set up the initial offset
1344 * into the buffer and the desired IO size before we start - 1355 * into the buffer and the desired IO size before we start -
1345 * _xfs_buf_ioapply_vec() will modify them appropriately for each 1356 * _xfs_buf_ioapply_vec() will modify them appropriately for each
diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h
index 51bc16a1cd9c..23f5642480bb 100644
--- a/fs/xfs/xfs_buf.h
+++ b/fs/xfs/xfs_buf.h
@@ -111,6 +111,11 @@ struct xfs_buf_map {
111#define DEFINE_SINGLE_BUF_MAP(map, blkno, numblk) \ 111#define DEFINE_SINGLE_BUF_MAP(map, blkno, numblk) \
112 struct xfs_buf_map (map) = { .bm_bn = (blkno), .bm_len = (numblk) }; 112 struct xfs_buf_map (map) = { .bm_bn = (blkno), .bm_len = (numblk) };
113 113
114struct xfs_buf_ops {
115 void (*verify_read)(struct xfs_buf *);
116 void (*verify_write)(struct xfs_buf *);
117};
118
114typedef struct xfs_buf { 119typedef struct xfs_buf {
115 /* 120 /*
116 * first cacheline holds all the fields needed for an uncontended cache 121 * first cacheline holds all the fields needed for an uncontended cache
@@ -154,9 +159,7 @@ typedef struct xfs_buf {
154 unsigned int b_page_count; /* size of page array */ 159 unsigned int b_page_count; /* size of page array */
155 unsigned int b_offset; /* page offset in first page */ 160 unsigned int b_offset; /* page offset in first page */
156 unsigned short b_error; /* error code on I/O */ 161 unsigned short b_error; /* error code on I/O */
157 162 const struct xfs_buf_ops *b_ops;
158 void (*b_pre_io)(struct xfs_buf *);
159 /* pre-io callback function */
160 163
161#ifdef XFS_BUF_LOCK_TRACKING 164#ifdef XFS_BUF_LOCK_TRACKING
162 int b_last_holder; 165 int b_last_holder;
@@ -199,10 +202,11 @@ struct xfs_buf *xfs_buf_get_map(struct xfs_buftarg *target,
199 xfs_buf_flags_t flags); 202 xfs_buf_flags_t flags);
200struct xfs_buf *xfs_buf_read_map(struct xfs_buftarg *target, 203struct xfs_buf *xfs_buf_read_map(struct xfs_buftarg *target,
201 struct xfs_buf_map *map, int nmaps, 204 struct xfs_buf_map *map, int nmaps,
202 xfs_buf_flags_t flags, xfs_buf_iodone_t verify); 205 xfs_buf_flags_t flags,
206 const struct xfs_buf_ops *ops);
203void xfs_buf_readahead_map(struct xfs_buftarg *target, 207void xfs_buf_readahead_map(struct xfs_buftarg *target,
204 struct xfs_buf_map *map, int nmaps, 208 struct xfs_buf_map *map, int nmaps,
205 xfs_buf_iodone_t verify); 209 const struct xfs_buf_ops *ops);
206 210
207static inline struct xfs_buf * 211static inline struct xfs_buf *
208xfs_buf_get( 212xfs_buf_get(
@@ -221,10 +225,10 @@ xfs_buf_read(
221 xfs_daddr_t blkno, 225 xfs_daddr_t blkno,
222 size_t numblks, 226 size_t numblks,
223 xfs_buf_flags_t flags, 227 xfs_buf_flags_t flags,
224 xfs_buf_iodone_t verify) 228 const struct xfs_buf_ops *ops)
225{ 229{
226 DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); 230 DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
227 return xfs_buf_read_map(target, &map, 1, flags, verify); 231 return xfs_buf_read_map(target, &map, 1, flags, ops);
228} 232}
229 233
230static inline void 234static inline void
@@ -232,10 +236,10 @@ xfs_buf_readahead(
232 struct xfs_buftarg *target, 236 struct xfs_buftarg *target,
233 xfs_daddr_t blkno, 237 xfs_daddr_t blkno,
234 size_t numblks, 238 size_t numblks,
235 xfs_buf_iodone_t verify) 239 const struct xfs_buf_ops *ops)
236{ 240{
237 DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); 241 DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
238 return xfs_buf_readahead_map(target, &map, 1, verify); 242 return xfs_buf_readahead_map(target, &map, 1, ops);
239} 243}
240 244
241struct xfs_buf *xfs_buf_get_empty(struct xfs_buftarg *target, size_t numblks); 245struct xfs_buf *xfs_buf_get_empty(struct xfs_buftarg *target, size_t numblks);
@@ -246,7 +250,7 @@ struct xfs_buf *xfs_buf_get_uncached(struct xfs_buftarg *target, size_t numblks,
246 int flags); 250 int flags);
247struct xfs_buf *xfs_buf_read_uncached(struct xfs_buftarg *target, 251struct xfs_buf *xfs_buf_read_uncached(struct xfs_buftarg *target,
248 xfs_daddr_t daddr, size_t numblks, int flags, 252 xfs_daddr_t daddr, size_t numblks, int flags,
249 xfs_buf_iodone_t verify); 253 const struct xfs_buf_ops *ops);
250void xfs_buf_hold(struct xfs_buf *bp); 254void xfs_buf_hold(struct xfs_buf *bp);
251 255
252/* Releasing Buffers */ 256/* Releasing Buffers */
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 087950fc2eb7..4d7696a02418 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -117,6 +117,12 @@ xfs_da_node_write_verify(
117 xfs_da_node_verify(bp); 117 xfs_da_node_verify(bp);
118} 118}
119 119
120/*
121 * leaf/node format detection on trees is sketchy, so a node read can be done on
122 * leaf level blocks when detection identifies the tree as a node format tree
123 * incorrectly. In this case, we need to swap the verifier to match the correct
124 * format of the block being read.
125 */
120static void 126static void
121xfs_da_node_read_verify( 127xfs_da_node_read_verify(
122 struct xfs_buf *bp) 128 struct xfs_buf *bp)
@@ -129,10 +135,12 @@ xfs_da_node_read_verify(
129 xfs_da_node_verify(bp); 135 xfs_da_node_verify(bp);
130 break; 136 break;
131 case XFS_ATTR_LEAF_MAGIC: 137 case XFS_ATTR_LEAF_MAGIC:
132 xfs_attr_leaf_read_verify(bp); 138 bp->b_ops = &xfs_attr_leaf_buf_ops;
139 bp->b_ops->verify_read(bp);
133 return; 140 return;
134 case XFS_DIR2_LEAFN_MAGIC: 141 case XFS_DIR2_LEAFN_MAGIC:
135 xfs_dir2_leafn_read_verify(bp); 142 bp->b_ops = &xfs_dir2_leafn_buf_ops;
143 bp->b_ops->verify_read(bp);
136 return; 144 return;
137 default: 145 default:
138 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, 146 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
@@ -140,12 +148,14 @@ xfs_da_node_read_verify(
140 xfs_buf_ioerror(bp, EFSCORRUPTED); 148 xfs_buf_ioerror(bp, EFSCORRUPTED);
141 break; 149 break;
142 } 150 }
143
144 bp->b_pre_io = xfs_da_node_write_verify;
145 bp->b_iodone = NULL;
146 xfs_buf_ioend(bp, 0);
147} 151}
148 152
153const struct xfs_buf_ops xfs_da_node_buf_ops = {
154 .verify_read = xfs_da_node_read_verify,
155 .verify_write = xfs_da_node_write_verify,
156};
157
158
149int 159int
150xfs_da_node_read( 160xfs_da_node_read(
151 struct xfs_trans *tp, 161 struct xfs_trans *tp,
@@ -156,7 +166,7 @@ xfs_da_node_read(
156 int which_fork) 166 int which_fork)
157{ 167{
158 return xfs_da_read_buf(tp, dp, bno, mappedbno, bpp, 168 return xfs_da_read_buf(tp, dp, bno, mappedbno, bpp,
159 which_fork, xfs_da_node_read_verify); 169 which_fork, &xfs_da_node_buf_ops);
160} 170}
161 171
162/*======================================================================== 172/*========================================================================
@@ -193,7 +203,7 @@ xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level,
193 xfs_trans_log_buf(tp, bp, 203 xfs_trans_log_buf(tp, bp,
194 XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr))); 204 XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
195 205
196 bp->b_pre_io = xfs_da_node_write_verify; 206 bp->b_ops = &xfs_da_node_buf_ops;
197 *bpp = bp; 207 *bpp = bp;
198 return(0); 208 return(0);
199} 209}
@@ -394,7 +404,7 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
394 memcpy(node, oldroot, size); 404 memcpy(node, oldroot, size);
395 xfs_trans_log_buf(tp, bp, 0, size - 1); 405 xfs_trans_log_buf(tp, bp, 0, size - 1);
396 406
397 bp->b_pre_io = blk1->bp->b_pre_io; 407 bp->b_ops = blk1->bp->b_ops;
398 blk1->bp = bp; 408 blk1->bp = bp;
399 blk1->blkno = blkno; 409 blk1->blkno = blkno;
400 410
@@ -828,11 +838,11 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)
828 /* 838 /*
829 * This could be copying a leaf back into the root block in the case of 839 * This could be copying a leaf back into the root block in the case of
830 * there only being a single leaf block left in the tree. Hence we have 840 * there only being a single leaf block left in the tree. Hence we have
831 * to update the pre_io pointer as well to match the buffer type change 841 * to update the b_ops pointer as well to match the buffer type change
832 * that could occur. 842 * that could occur.
833 */ 843 */
834 memcpy(root_blk->bp->b_addr, bp->b_addr, state->blocksize); 844 memcpy(root_blk->bp->b_addr, bp->b_addr, state->blocksize);
835 root_blk->bp->b_pre_io = bp->b_pre_io; 845 root_blk->bp->b_ops = bp->b_ops;
836 xfs_trans_log_buf(args->trans, root_blk->bp, 0, state->blocksize - 1); 846 xfs_trans_log_buf(args->trans, root_blk->bp, 0, state->blocksize - 1);
837 error = xfs_da_shrink_inode(args, child, bp); 847 error = xfs_da_shrink_inode(args, child, bp);
838 return(error); 848 return(error);
@@ -2223,7 +2233,7 @@ xfs_da_read_buf(
2223 xfs_daddr_t mappedbno, 2233 xfs_daddr_t mappedbno,
2224 struct xfs_buf **bpp, 2234 struct xfs_buf **bpp,
2225 int whichfork, 2235 int whichfork,
2226 xfs_buf_iodone_t verifier) 2236 const struct xfs_buf_ops *ops)
2227{ 2237{
2228 struct xfs_buf *bp; 2238 struct xfs_buf *bp;
2229 struct xfs_buf_map map; 2239 struct xfs_buf_map map;
@@ -2245,7 +2255,7 @@ xfs_da_read_buf(
2245 2255
2246 error = xfs_trans_read_buf_map(dp->i_mount, trans, 2256 error = xfs_trans_read_buf_map(dp->i_mount, trans,
2247 dp->i_mount->m_ddev_targp, 2257 dp->i_mount->m_ddev_targp,
2248 mapp, nmap, 0, &bp, verifier); 2258 mapp, nmap, 0, &bp, ops);
2249 if (error) 2259 if (error)
2250 goto out_free; 2260 goto out_free;
2251 2261
@@ -2303,7 +2313,7 @@ xfs_da_reada_buf(
2303 xfs_dablk_t bno, 2313 xfs_dablk_t bno,
2304 xfs_daddr_t mappedbno, 2314 xfs_daddr_t mappedbno,
2305 int whichfork, 2315 int whichfork,
2306 xfs_buf_iodone_t verifier) 2316 const struct xfs_buf_ops *ops)
2307{ 2317{
2308 struct xfs_buf_map map; 2318 struct xfs_buf_map map;
2309 struct xfs_buf_map *mapp; 2319 struct xfs_buf_map *mapp;
@@ -2322,7 +2332,7 @@ xfs_da_reada_buf(
2322 } 2332 }
2323 2333
2324 mappedbno = mapp[0].bm_bn; 2334 mappedbno = mapp[0].bm_bn;
2325 xfs_buf_readahead_map(dp->i_mount->m_ddev_targp, mapp, nmap, NULL); 2335 xfs_buf_readahead_map(dp->i_mount->m_ddev_targp, mapp, nmap, ops);
2326 2336
2327out_free: 2337out_free:
2328 if (mapp != &map) 2338 if (mapp != &map)
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h
index 521b008445ab..ee5170c46ae1 100644
--- a/fs/xfs/xfs_da_btree.h
+++ b/fs/xfs/xfs_da_btree.h
@@ -229,10 +229,10 @@ int xfs_da_get_buf(struct xfs_trans *trans, struct xfs_inode *dp,
229int xfs_da_read_buf(struct xfs_trans *trans, struct xfs_inode *dp, 229int xfs_da_read_buf(struct xfs_trans *trans, struct xfs_inode *dp,
230 xfs_dablk_t bno, xfs_daddr_t mappedbno, 230 xfs_dablk_t bno, xfs_daddr_t mappedbno,
231 struct xfs_buf **bpp, int whichfork, 231 struct xfs_buf **bpp, int whichfork,
232 xfs_buf_iodone_t verifier); 232 const struct xfs_buf_ops *ops);
233xfs_daddr_t xfs_da_reada_buf(struct xfs_trans *trans, struct xfs_inode *dp, 233xfs_daddr_t xfs_da_reada_buf(struct xfs_trans *trans, struct xfs_inode *dp,
234 xfs_dablk_t bno, xfs_daddr_t mapped_bno, 234 xfs_dablk_t bno, xfs_daddr_t mapped_bno,
235 int whichfork, xfs_buf_iodone_t verifier); 235 int whichfork, const struct xfs_buf_ops *ops);
236int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno, 236int xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
237 struct xfs_buf *dead_buf); 237 struct xfs_buf *dead_buf);
238 238
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index e2fdc6f03d8a..7536faaa61e7 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -74,22 +74,24 @@ xfs_dir2_block_verify(
74} 74}
75 75
76static void 76static void
77xfs_dir2_block_write_verify( 77xfs_dir2_block_read_verify(
78 struct xfs_buf *bp) 78 struct xfs_buf *bp)
79{ 79{
80 xfs_dir2_block_verify(bp); 80 xfs_dir2_block_verify(bp);
81} 81}
82 82
83void 83static void
84xfs_dir2_block_read_verify( 84xfs_dir2_block_write_verify(
85 struct xfs_buf *bp) 85 struct xfs_buf *bp)
86{ 86{
87 xfs_dir2_block_verify(bp); 87 xfs_dir2_block_verify(bp);
88 bp->b_pre_io = xfs_dir2_block_write_verify;
89 bp->b_iodone = NULL;
90 xfs_buf_ioend(bp, 0);
91} 88}
92 89
90const struct xfs_buf_ops xfs_dir2_block_buf_ops = {
91 .verify_read = xfs_dir2_block_read_verify,
92 .verify_write = xfs_dir2_block_write_verify,
93};
94
93static int 95static int
94xfs_dir2_block_read( 96xfs_dir2_block_read(
95 struct xfs_trans *tp, 97 struct xfs_trans *tp,
@@ -99,7 +101,7 @@ xfs_dir2_block_read(
99 struct xfs_mount *mp = dp->i_mount; 101 struct xfs_mount *mp = dp->i_mount;
100 102
101 return xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, bpp, 103 return xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, bpp,
102 XFS_DATA_FORK, xfs_dir2_block_read_verify); 104 XFS_DATA_FORK, &xfs_dir2_block_buf_ops);
103} 105}
104 106
105static void 107static void
@@ -1010,7 +1012,7 @@ xfs_dir2_leaf_to_block(
1010 /* 1012 /*
1011 * Start converting it to block form. 1013 * Start converting it to block form.
1012 */ 1014 */
1013 dbp->b_pre_io = xfs_dir2_block_write_verify; 1015 dbp->b_ops = &xfs_dir2_block_buf_ops;
1014 hdr->magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); 1016 hdr->magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC);
1015 needlog = 1; 1017 needlog = 1;
1016 needscan = 0; 1018 needscan = 0;
@@ -1140,7 +1142,7 @@ xfs_dir2_sf_to_block(
1140 kmem_free(sfp); 1142 kmem_free(sfp);
1141 return error; 1143 return error;
1142 } 1144 }
1143 bp->b_pre_io = xfs_dir2_block_write_verify; 1145 bp->b_ops = &xfs_dir2_block_buf_ops;
1144 hdr = bp->b_addr; 1146 hdr = bp->b_addr;
1145 hdr->magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); 1147 hdr->magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC);
1146 /* 1148 /*
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index dcb8a873ab92..ffcf1774152e 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -202,23 +202,57 @@ xfs_dir2_data_verify(
202 } 202 }
203} 203}
204 204
205void 205/*
206xfs_dir2_data_write_verify( 206 * Readahead of the first block of the directory when it is opened is completely
207 * oblivious to the format of the directory. Hence we can either get a block
208 * format buffer or a data format buffer on readahead.
209 */
210static void
211xfs_dir2_data_reada_verify(
212 struct xfs_buf *bp)
213{
214 struct xfs_mount *mp = bp->b_target->bt_mount;
215 struct xfs_dir2_data_hdr *hdr = bp->b_addr;
216
217 switch (hdr->magic) {
218 case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
219 bp->b_ops = &xfs_dir2_block_buf_ops;
220 bp->b_ops->verify_read(bp);
221 return;
222 case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
223 xfs_dir2_data_verify(bp);
224 return;
225 default:
226 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr);
227 xfs_buf_ioerror(bp, EFSCORRUPTED);
228 break;
229 }
230}
231
232static void
233xfs_dir2_data_read_verify(
207 struct xfs_buf *bp) 234 struct xfs_buf *bp)
208{ 235{
209 xfs_dir2_data_verify(bp); 236 xfs_dir2_data_verify(bp);
210} 237}
211 238
212static void 239static void
213xfs_dir2_data_read_verify( 240xfs_dir2_data_write_verify(
214 struct xfs_buf *bp) 241 struct xfs_buf *bp)
215{ 242{
216 xfs_dir2_data_verify(bp); 243 xfs_dir2_data_verify(bp);
217 bp->b_pre_io = xfs_dir2_data_write_verify;
218 bp->b_iodone = NULL;
219 xfs_buf_ioend(bp, 0);
220} 244}
221 245
246const struct xfs_buf_ops xfs_dir2_data_buf_ops = {
247 .verify_read = xfs_dir2_data_read_verify,
248 .verify_write = xfs_dir2_data_write_verify,
249};
250
251static const struct xfs_buf_ops xfs_dir2_data_reada_buf_ops = {
252 .verify_read = xfs_dir2_data_reada_verify,
253 .verify_write = xfs_dir2_data_write_verify,
254};
255
222 256
223int 257int
224xfs_dir2_data_read( 258xfs_dir2_data_read(
@@ -229,7 +263,7 @@ xfs_dir2_data_read(
229 struct xfs_buf **bpp) 263 struct xfs_buf **bpp)
230{ 264{
231 return xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp, 265 return xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp,
232 XFS_DATA_FORK, xfs_dir2_data_read_verify); 266 XFS_DATA_FORK, &xfs_dir2_data_buf_ops);
233} 267}
234 268
235int 269int
@@ -240,7 +274,7 @@ xfs_dir2_data_readahead(
240 xfs_daddr_t mapped_bno) 274 xfs_daddr_t mapped_bno)
241{ 275{
242 return xfs_da_reada_buf(tp, dp, bno, mapped_bno, 276 return xfs_da_reada_buf(tp, dp, bno, mapped_bno,
243 XFS_DATA_FORK, xfs_dir2_data_read_verify); 277 XFS_DATA_FORK, &xfs_dir2_data_reada_buf_ops);
244} 278}
245 279
246/* 280/*
@@ -484,7 +518,7 @@ xfs_dir2_data_init(
484 XFS_DATA_FORK); 518 XFS_DATA_FORK);
485 if (error) 519 if (error)
486 return error; 520 return error;
487 bp->b_pre_io = xfs_dir2_data_write_verify; 521 bp->b_ops = &xfs_dir2_data_buf_ops;
488 522
489 /* 523 /*
490 * Initialize the header. 524 * Initialize the header.
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 3002ab7d54c3..60cd2fa4e047 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -65,39 +65,43 @@ xfs_dir2_leaf_verify(
65} 65}
66 66
67static void 67static void
68xfs_dir2_leaf1_write_verify( 68xfs_dir2_leaf1_read_verify(
69 struct xfs_buf *bp) 69 struct xfs_buf *bp)
70{ 70{
71 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)); 71 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAF1_MAGIC));
72} 72}
73 73
74static void 74static void
75xfs_dir2_leaf1_read_verify( 75xfs_dir2_leaf1_write_verify(
76 struct xfs_buf *bp) 76 struct xfs_buf *bp)
77{ 77{
78 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAF1_MAGIC)); 78 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAF1_MAGIC));
79 bp->b_pre_io = xfs_dir2_leaf1_write_verify;
80 bp->b_iodone = NULL;
81 xfs_buf_ioend(bp, 0);
82} 79}
83 80
84void 81void
85xfs_dir2_leafn_write_verify( 82xfs_dir2_leafn_read_verify(
86 struct xfs_buf *bp) 83 struct xfs_buf *bp)
87{ 84{
88 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 85 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
89} 86}
90 87
91void 88void
92xfs_dir2_leafn_read_verify( 89xfs_dir2_leafn_write_verify(
93 struct xfs_buf *bp) 90 struct xfs_buf *bp)
94{ 91{
95 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)); 92 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
96 bp->b_pre_io = xfs_dir2_leafn_write_verify;
97 bp->b_iodone = NULL;
98 xfs_buf_ioend(bp, 0);
99} 93}
100 94
95static const struct xfs_buf_ops xfs_dir2_leaf1_buf_ops = {
96 .verify_read = xfs_dir2_leaf1_read_verify,
97 .verify_write = xfs_dir2_leaf1_write_verify,
98};
99
100const struct xfs_buf_ops xfs_dir2_leafn_buf_ops = {
101 .verify_read = xfs_dir2_leafn_read_verify,
102 .verify_write = xfs_dir2_leafn_write_verify,
103};
104
101static int 105static int
102xfs_dir2_leaf_read( 106xfs_dir2_leaf_read(
103 struct xfs_trans *tp, 107 struct xfs_trans *tp,
@@ -107,7 +111,7 @@ xfs_dir2_leaf_read(
107 struct xfs_buf **bpp) 111 struct xfs_buf **bpp)
108{ 112{
109 return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, 113 return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
110 XFS_DATA_FORK, xfs_dir2_leaf1_read_verify); 114 XFS_DATA_FORK, &xfs_dir2_leaf1_buf_ops);
111} 115}
112 116
113int 117int
@@ -119,7 +123,7 @@ xfs_dir2_leafn_read(
119 struct xfs_buf **bpp) 123 struct xfs_buf **bpp)
120{ 124{
121 return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, 125 return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
122 XFS_DATA_FORK, xfs_dir2_leafn_read_verify); 126 XFS_DATA_FORK, &xfs_dir2_leafn_buf_ops);
123} 127}
124 128
125/* 129/*
@@ -198,7 +202,7 @@ xfs_dir2_block_to_leaf(
198 /* 202 /*
199 * Fix up the block header, make it a data block. 203 * Fix up the block header, make it a data block.
200 */ 204 */
201 dbp->b_pre_io = xfs_dir2_data_write_verify; 205 dbp->b_ops = &xfs_dir2_data_buf_ops;
202 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); 206 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
203 if (needscan) 207 if (needscan)
204 xfs_dir2_data_freescan(mp, hdr, &needlog); 208 xfs_dir2_data_freescan(mp, hdr, &needlog);
@@ -1264,12 +1268,12 @@ xfs_dir2_leaf_init(
1264 * the block. 1268 * the block.
1265 */ 1269 */
1266 if (magic == XFS_DIR2_LEAF1_MAGIC) { 1270 if (magic == XFS_DIR2_LEAF1_MAGIC) {
1267 bp->b_pre_io = xfs_dir2_leaf1_write_verify; 1271 bp->b_ops = &xfs_dir2_leaf1_buf_ops;
1268 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 1272 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
1269 ltp->bestcount = 0; 1273 ltp->bestcount = 0;
1270 xfs_dir2_leaf_log_tail(tp, bp); 1274 xfs_dir2_leaf_log_tail(tp, bp);
1271 } else 1275 } else
1272 bp->b_pre_io = xfs_dir2_leafn_write_verify; 1276 bp->b_ops = &xfs_dir2_leafn_buf_ops;
1273 *bpp = bp; 1277 *bpp = bp;
1274 return 0; 1278 return 0;
1275} 1279}
@@ -1954,7 +1958,7 @@ xfs_dir2_node_to_leaf(
1954 else 1958 else
1955 xfs_dir2_leaf_log_header(tp, lbp); 1959 xfs_dir2_leaf_log_header(tp, lbp);
1956 1960
1957 lbp->b_pre_io = xfs_dir2_leaf1_write_verify; 1961 lbp->b_ops = &xfs_dir2_leaf1_buf_ops;
1958 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAF1_MAGIC); 1962 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAF1_MAGIC);
1959 1963
1960 /* 1964 /*
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index da90a91f4420..5980f9b7fa9b 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -72,22 +72,24 @@ xfs_dir2_free_verify(
72} 72}
73 73
74static void 74static void
75xfs_dir2_free_write_verify( 75xfs_dir2_free_read_verify(
76 struct xfs_buf *bp) 76 struct xfs_buf *bp)
77{ 77{
78 xfs_dir2_free_verify(bp); 78 xfs_dir2_free_verify(bp);
79} 79}
80 80
81void 81static void
82xfs_dir2_free_read_verify( 82xfs_dir2_free_write_verify(
83 struct xfs_buf *bp) 83 struct xfs_buf *bp)
84{ 84{
85 xfs_dir2_free_verify(bp); 85 xfs_dir2_free_verify(bp);
86 bp->b_pre_io = xfs_dir2_free_write_verify;
87 bp->b_iodone = NULL;
88 xfs_buf_ioend(bp, 0);
89} 86}
90 87
88static const struct xfs_buf_ops xfs_dir2_free_buf_ops = {
89 .verify_read = xfs_dir2_free_read_verify,
90 .verify_write = xfs_dir2_free_write_verify,
91};
92
91 93
92static int 94static int
93__xfs_dir2_free_read( 95__xfs_dir2_free_read(
@@ -98,7 +100,7 @@ __xfs_dir2_free_read(
98 struct xfs_buf **bpp) 100 struct xfs_buf **bpp)
99{ 101{
100 return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, 102 return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
101 XFS_DATA_FORK, xfs_dir2_free_read_verify); 103 XFS_DATA_FORK, &xfs_dir2_free_buf_ops);
102} 104}
103 105
104int 106int
@@ -201,7 +203,7 @@ xfs_dir2_leaf_to_node(
201 XFS_DATA_FORK); 203 XFS_DATA_FORK);
202 if (error) 204 if (error)
203 return error; 205 return error;
204 fbp->b_pre_io = xfs_dir2_free_write_verify; 206 fbp->b_ops = &xfs_dir2_free_buf_ops;
205 207
206 free = fbp->b_addr; 208 free = fbp->b_addr;
207 leaf = lbp->b_addr; 209 leaf = lbp->b_addr;
@@ -225,7 +227,7 @@ xfs_dir2_leaf_to_node(
225 } 227 }
226 free->hdr.nused = cpu_to_be32(n); 228 free->hdr.nused = cpu_to_be32(n);
227 229
228 lbp->b_pre_io = xfs_dir2_leafn_write_verify; 230 lbp->b_ops = &xfs_dir2_leafn_buf_ops;
229 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAFN_MAGIC); 231 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAFN_MAGIC);
230 232
231 /* 233 /*
@@ -636,7 +638,7 @@ xfs_dir2_leafn_lookup_for_entry(
636 state->extrablk.index = (int)((char *)dep - 638 state->extrablk.index = (int)((char *)dep -
637 (char *)curbp->b_addr); 639 (char *)curbp->b_addr);
638 state->extrablk.magic = XFS_DIR2_DATA_MAGIC; 640 state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
639 curbp->b_pre_io = xfs_dir2_data_write_verify; 641 curbp->b_ops = &xfs_dir2_data_buf_ops;
640 if (cmp == XFS_CMP_EXACT) 642 if (cmp == XFS_CMP_EXACT)
641 return XFS_ERROR(EEXIST); 643 return XFS_ERROR(EEXIST);
642 } 644 }
@@ -651,7 +653,7 @@ xfs_dir2_leafn_lookup_for_entry(
651 state->extrablk.index = -1; 653 state->extrablk.index = -1;
652 state->extrablk.blkno = curdb; 654 state->extrablk.blkno = curdb;
653 state->extrablk.magic = XFS_DIR2_DATA_MAGIC; 655 state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
654 curbp->b_pre_io = xfs_dir2_data_write_verify; 656 curbp->b_ops = &xfs_dir2_data_buf_ops;
655 } else { 657 } else {
656 /* If the curbp is not the CI match block, drop it */ 658 /* If the curbp is not the CI match block, drop it */
657 if (state->extrablk.bp != curbp) 659 if (state->extrablk.bp != curbp)
@@ -1649,7 +1651,7 @@ xfs_dir2_node_addname_int(
1649 -1, &fbp, XFS_DATA_FORK); 1651 -1, &fbp, XFS_DATA_FORK);
1650 if (error) 1652 if (error)
1651 return error; 1653 return error;
1652 fbp->b_pre_io = xfs_dir2_free_write_verify; 1654 fbp->b_ops = &xfs_dir2_free_buf_ops;
1653 1655
1654 /* 1656 /*
1655 * Initialize the new block to be empty, and remember 1657 * Initialize the new block to be empty, and remember
diff --git a/fs/xfs/xfs_dir2_priv.h b/fs/xfs/xfs_dir2_priv.h
index 01b82dcddc3e..7da79f6515fd 100644
--- a/fs/xfs/xfs_dir2_priv.h
+++ b/fs/xfs/xfs_dir2_priv.h
@@ -30,6 +30,8 @@ extern int xfs_dir_cilookup_result(struct xfs_da_args *args,
30 const unsigned char *name, int len); 30 const unsigned char *name, int len);
31 31
32/* xfs_dir2_block.c */ 32/* xfs_dir2_block.c */
33extern const struct xfs_buf_ops xfs_dir2_block_buf_ops;
34
33extern int xfs_dir2_block_addname(struct xfs_da_args *args); 35extern int xfs_dir2_block_addname(struct xfs_da_args *args);
34extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent, 36extern int xfs_dir2_block_getdents(struct xfs_inode *dp, void *dirent,
35 xfs_off_t *offset, filldir_t filldir); 37 xfs_off_t *offset, filldir_t filldir);
@@ -45,7 +47,9 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
45#else 47#else
46#define xfs_dir2_data_check(dp,bp) 48#define xfs_dir2_data_check(dp,bp)
47#endif 49#endif
48extern void xfs_dir2_data_write_verify(struct xfs_buf *bp); 50
51extern const struct xfs_buf_ops xfs_dir2_data_buf_ops;
52
49extern int __xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_buf *bp); 53extern int __xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_buf *bp);
50extern int xfs_dir2_data_read(struct xfs_trans *tp, struct xfs_inode *dp, 54extern int xfs_dir2_data_read(struct xfs_trans *tp, struct xfs_inode *dp,
51 xfs_dablk_t bno, xfs_daddr_t mapped_bno, struct xfs_buf **bpp); 55 xfs_dablk_t bno, xfs_daddr_t mapped_bno, struct xfs_buf **bpp);
@@ -73,8 +77,8 @@ extern void xfs_dir2_data_use_free(struct xfs_trans *tp, struct xfs_buf *bp,
73 xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp); 77 xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);
74 78
75/* xfs_dir2_leaf.c */ 79/* xfs_dir2_leaf.c */
76extern void xfs_dir2_leafn_read_verify(struct xfs_buf *bp); 80extern const struct xfs_buf_ops xfs_dir2_leafn_buf_ops;
77extern void xfs_dir2_leafn_write_verify(struct xfs_buf *bp); 81
78extern int xfs_dir2_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp, 82extern int xfs_dir2_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp,
79 xfs_dablk_t fbno, xfs_daddr_t mappedbno, struct xfs_buf **bpp); 83 xfs_dablk_t fbno, xfs_daddr_t mappedbno, struct xfs_buf **bpp);
80extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args, 84extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 1b06aa051074..9e1bf5294c91 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -284,22 +284,24 @@ xfs_dquot_buf_verify(
284} 284}
285 285
286static void 286static void
287xfs_dquot_buf_write_verify( 287xfs_dquot_buf_read_verify(
288 struct xfs_buf *bp) 288 struct xfs_buf *bp)
289{ 289{
290 xfs_dquot_buf_verify(bp); 290 xfs_dquot_buf_verify(bp);
291} 291}
292 292
293void 293void
294xfs_dquot_buf_read_verify( 294xfs_dquot_buf_write_verify(
295 struct xfs_buf *bp) 295 struct xfs_buf *bp)
296{ 296{
297 xfs_dquot_buf_verify(bp); 297 xfs_dquot_buf_verify(bp);
298 bp->b_pre_io = xfs_dquot_buf_write_verify;
299 bp->b_iodone = NULL;
300 xfs_buf_ioend(bp, 0);
301} 298}
302 299
300const struct xfs_buf_ops xfs_dquot_buf_ops = {
301 .verify_read = xfs_dquot_buf_read_verify,
302 .verify_write = xfs_dquot_buf_write_verify,
303};
304
303/* 305/*
304 * Allocate a block and fill it with dquots. 306 * Allocate a block and fill it with dquots.
305 * This is called when the bmapi finds a hole. 307 * This is called when the bmapi finds a hole.
@@ -365,7 +367,7 @@ xfs_qm_dqalloc(
365 error = xfs_buf_geterror(bp); 367 error = xfs_buf_geterror(bp);
366 if (error) 368 if (error)
367 goto error1; 369 goto error1;
368 bp->b_pre_io = xfs_dquot_buf_write_verify; 370 bp->b_ops = &xfs_dquot_buf_ops;
369 371
370 /* 372 /*
371 * Make a chunk of dquots out of this buffer and log 373 * Make a chunk of dquots out of this buffer and log
@@ -435,7 +437,7 @@ xfs_qm_dqrepair(
435 ASSERT(*bpp == NULL); 437 ASSERT(*bpp == NULL);
436 return XFS_ERROR(error); 438 return XFS_ERROR(error);
437 } 439 }
438 (*bpp)->b_pre_io = xfs_dquot_buf_write_verify; 440 (*bpp)->b_ops = &xfs_dquot_buf_ops;
439 441
440 ASSERT(xfs_buf_islocked(*bpp)); 442 ASSERT(xfs_buf_islocked(*bpp));
441 d = (struct xfs_dqblk *)(*bpp)->b_addr; 443 d = (struct xfs_dqblk *)(*bpp)->b_addr;
@@ -534,7 +536,7 @@ xfs_qm_dqtobp(
534 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, 536 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
535 dqp->q_blkno, 537 dqp->q_blkno,
536 mp->m_quotainfo->qi_dqchunklen, 538 mp->m_quotainfo->qi_dqchunklen,
537 0, &bp, xfs_dquot_buf_read_verify); 539 0, &bp, &xfs_dquot_buf_ops);
538 540
539 if (error == EFSCORRUPTED && (flags & XFS_QMOPT_DQREPAIR)) { 541 if (error == EFSCORRUPTED && (flags & XFS_QMOPT_DQREPAIR)) {
540 xfs_dqid_t firstid = (xfs_dqid_t)map.br_startoff * 542 xfs_dqid_t firstid = (xfs_dqid_t)map.br_startoff *
diff --git a/fs/xfs/xfs_dquot.h b/fs/xfs/xfs_dquot.h
index 5438d883b628..c694a8469c4a 100644
--- a/fs/xfs/xfs_dquot.h
+++ b/fs/xfs/xfs_dquot.h
@@ -140,7 +140,6 @@ static inline xfs_dquot_t *xfs_inode_dquot(struct xfs_inode *ip, int type)
140 140
141extern int xfs_qm_dqread(struct xfs_mount *, xfs_dqid_t, uint, 141extern int xfs_qm_dqread(struct xfs_mount *, xfs_dqid_t, uint,
142 uint, struct xfs_dquot **); 142 uint, struct xfs_dquot **);
143extern void xfs_dquot_buf_read_verify(struct xfs_buf *bp);
144extern void xfs_qm_dqdestroy(xfs_dquot_t *); 143extern void xfs_qm_dqdestroy(xfs_dquot_t *);
145extern int xfs_qm_dqflush(struct xfs_dquot *, struct xfs_buf **); 144extern int xfs_qm_dqflush(struct xfs_dquot *, struct xfs_buf **);
146extern void xfs_qm_dqunpin_wait(xfs_dquot_t *); 145extern void xfs_qm_dqunpin_wait(xfs_dquot_t *);
@@ -162,4 +161,6 @@ static inline struct xfs_dquot *xfs_qm_dqhold(struct xfs_dquot *dqp)
162 return dqp; 161 return dqp;
163} 162}
164 163
164extern const struct xfs_buf_ops xfs_dquot_buf_ops;
165
165#endif /* __XFS_DQUOT_H__ */ 166#endif /* __XFS_DQUOT_H__ */
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 5d6d6b9d369d..94eaeedc5498 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -119,7 +119,8 @@ xfs_growfs_get_hdr_buf(
119 struct xfs_mount *mp, 119 struct xfs_mount *mp,
120 xfs_daddr_t blkno, 120 xfs_daddr_t blkno,
121 size_t numblks, 121 size_t numblks,
122 int flags) 122 int flags,
123 const struct xfs_buf_ops *ops)
123{ 124{
124 struct xfs_buf *bp; 125 struct xfs_buf *bp;
125 126
@@ -130,6 +131,7 @@ xfs_growfs_get_hdr_buf(
130 xfs_buf_zero(bp, 0, BBTOB(bp->b_length)); 131 xfs_buf_zero(bp, 0, BBTOB(bp->b_length));
131 bp->b_bn = blkno; 132 bp->b_bn = blkno;
132 bp->b_maps[0].bm_bn = blkno; 133 bp->b_maps[0].bm_bn = blkno;
134 bp->b_ops = ops;
133 135
134 return bp; 136 return bp;
135} 137}
@@ -217,12 +219,12 @@ xfs_growfs_data_private(
217 */ 219 */
218 bp = xfs_growfs_get_hdr_buf(mp, 220 bp = xfs_growfs_get_hdr_buf(mp,
219 XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), 221 XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
220 XFS_FSS_TO_BB(mp, 1), 0); 222 XFS_FSS_TO_BB(mp, 1), 0,
223 &xfs_agf_buf_ops);
221 if (!bp) { 224 if (!bp) {
222 error = ENOMEM; 225 error = ENOMEM;
223 goto error0; 226 goto error0;
224 } 227 }
225 bp->b_pre_io = xfs_agf_write_verify;
226 228
227 agf = XFS_BUF_TO_AGF(bp); 229 agf = XFS_BUF_TO_AGF(bp);
228 agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC); 230 agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
@@ -255,12 +257,12 @@ xfs_growfs_data_private(
255 */ 257 */
256 bp = xfs_growfs_get_hdr_buf(mp, 258 bp = xfs_growfs_get_hdr_buf(mp,
257 XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), 259 XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
258 XFS_FSS_TO_BB(mp, 1), 0); 260 XFS_FSS_TO_BB(mp, 1), 0,
261 &xfs_agfl_buf_ops);
259 if (!bp) { 262 if (!bp) {
260 error = ENOMEM; 263 error = ENOMEM;
261 goto error0; 264 goto error0;
262 } 265 }
263 bp->b_pre_io = xfs_agfl_write_verify;
264 266
265 agfl = XFS_BUF_TO_AGFL(bp); 267 agfl = XFS_BUF_TO_AGFL(bp);
266 for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++) 268 for (bucket = 0; bucket < XFS_AGFL_SIZE(mp); bucket++)
@@ -276,12 +278,12 @@ xfs_growfs_data_private(
276 */ 278 */
277 bp = xfs_growfs_get_hdr_buf(mp, 279 bp = xfs_growfs_get_hdr_buf(mp,
278 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), 280 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
279 XFS_FSS_TO_BB(mp, 1), 0); 281 XFS_FSS_TO_BB(mp, 1), 0,
282 &xfs_agi_buf_ops);
280 if (!bp) { 283 if (!bp) {
281 error = ENOMEM; 284 error = ENOMEM;
282 goto error0; 285 goto error0;
283 } 286 }
284 bp->b_pre_io = xfs_agi_write_verify;
285 287
286 agi = XFS_BUF_TO_AGI(bp); 288 agi = XFS_BUF_TO_AGI(bp);
287 agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC); 289 agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
@@ -306,7 +308,8 @@ xfs_growfs_data_private(
306 */ 308 */
307 bp = xfs_growfs_get_hdr_buf(mp, 309 bp = xfs_growfs_get_hdr_buf(mp,
308 XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)), 310 XFS_AGB_TO_DADDR(mp, agno, XFS_BNO_BLOCK(mp)),
309 BTOBB(mp->m_sb.sb_blocksize), 0); 311 BTOBB(mp->m_sb.sb_blocksize), 0,
312 &xfs_allocbt_buf_ops);
310 313
311 if (!bp) { 314 if (!bp) {
312 error = ENOMEM; 315 error = ENOMEM;
@@ -329,7 +332,8 @@ xfs_growfs_data_private(
329 */ 332 */
330 bp = xfs_growfs_get_hdr_buf(mp, 333 bp = xfs_growfs_get_hdr_buf(mp,
331 XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)), 334 XFS_AGB_TO_DADDR(mp, agno, XFS_CNT_BLOCK(mp)),
332 BTOBB(mp->m_sb.sb_blocksize), 0); 335 BTOBB(mp->m_sb.sb_blocksize), 0,
336 &xfs_allocbt_buf_ops);
333 if (!bp) { 337 if (!bp) {
334 error = ENOMEM; 338 error = ENOMEM;
335 goto error0; 339 goto error0;
@@ -352,7 +356,8 @@ xfs_growfs_data_private(
352 */ 356 */
353 bp = xfs_growfs_get_hdr_buf(mp, 357 bp = xfs_growfs_get_hdr_buf(mp,
354 XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)), 358 XFS_AGB_TO_DADDR(mp, agno, XFS_IBT_BLOCK(mp)),
355 BTOBB(mp->m_sb.sb_blocksize), 0); 359 BTOBB(mp->m_sb.sb_blocksize), 0,
360 &xfs_inobt_buf_ops);
356 if (!bp) { 361 if (!bp) {
357 error = ENOMEM; 362 error = ENOMEM;
358 goto error0; 363 goto error0;
@@ -448,14 +453,14 @@ xfs_growfs_data_private(
448 error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, 453 error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
449 XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), 454 XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
450 XFS_FSS_TO_BB(mp, 1), 0, &bp, 455 XFS_FSS_TO_BB(mp, 1), 0, &bp,
451 xfs_sb_read_verify); 456 &xfs_sb_buf_ops);
452 } else { 457 } else {
453 bp = xfs_trans_get_buf(NULL, mp->m_ddev_targp, 458 bp = xfs_trans_get_buf(NULL, mp->m_ddev_targp,
454 XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)), 459 XFS_AGB_TO_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
455 XFS_FSS_TO_BB(mp, 1), 0); 460 XFS_FSS_TO_BB(mp, 1), 0);
456 if (bp) { 461 if (bp) {
462 bp->b_ops = &xfs_sb_buf_ops;
457 xfs_buf_zero(bp, 0, BBTOB(bp->b_length)); 463 xfs_buf_zero(bp, 0, BBTOB(bp->b_length));
458 bp->b_pre_io = xfs_sb_write_verify;
459 } else 464 } else
460 error = ENOMEM; 465 error = ENOMEM;
461 } 466 }
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index faf68600d3a6..2d6495eaaa34 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -210,7 +210,7 @@ xfs_ialloc_inode_init(
210 * to log a whole cluster of inodes instead of all the 210 * to log a whole cluster of inodes instead of all the
211 * individual transactions causing a lot of log traffic. 211 * individual transactions causing a lot of log traffic.
212 */ 212 */
213 fbuf->b_pre_io = xfs_inode_buf_write_verify; 213 fbuf->b_ops = &xfs_inode_buf_ops;
214 xfs_buf_zero(fbuf, 0, ninodes << mp->m_sb.sb_inodelog); 214 xfs_buf_zero(fbuf, 0, ninodes << mp->m_sb.sb_inodelog);
215 for (i = 0; i < ninodes; i++) { 215 for (i = 0; i < ninodes; i++) {
216 int ioffset = i << mp->m_sb.sb_inodelog; 216 int ioffset = i << mp->m_sb.sb_inodelog;
@@ -1505,23 +1505,25 @@ xfs_agi_verify(
1505 xfs_check_agi_unlinked(agi); 1505 xfs_check_agi_unlinked(agi);
1506} 1506}
1507 1507
1508void 1508static void
1509xfs_agi_write_verify( 1509xfs_agi_read_verify(
1510 struct xfs_buf *bp) 1510 struct xfs_buf *bp)
1511{ 1511{
1512 xfs_agi_verify(bp); 1512 xfs_agi_verify(bp);
1513} 1513}
1514 1514
1515static void 1515static void
1516xfs_agi_read_verify( 1516xfs_agi_write_verify(
1517 struct xfs_buf *bp) 1517 struct xfs_buf *bp)
1518{ 1518{
1519 xfs_agi_verify(bp); 1519 xfs_agi_verify(bp);
1520 bp->b_pre_io = xfs_agi_write_verify;
1521 bp->b_iodone = NULL;
1522 xfs_buf_ioend(bp, 0);
1523} 1520}
1524 1521
1522const struct xfs_buf_ops xfs_agi_buf_ops = {
1523 .verify_read = xfs_agi_read_verify,
1524 .verify_write = xfs_agi_write_verify,
1525};
1526
1525/* 1527/*
1526 * Read in the allocation group header (inode allocation section) 1528 * Read in the allocation group header (inode allocation section)
1527 */ 1529 */
@@ -1538,7 +1540,7 @@ xfs_read_agi(
1538 1540
1539 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, 1541 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
1540 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), 1542 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
1541 XFS_FSS_TO_BB(mp, 1), 0, bpp, xfs_agi_read_verify); 1543 XFS_FSS_TO_BB(mp, 1), 0, bpp, &xfs_agi_buf_ops);
1542 if (error) 1544 if (error)
1543 return error; 1545 return error;
1544 1546
diff --git a/fs/xfs/xfs_ialloc.h b/fs/xfs/xfs_ialloc.h
index 7a169e34e30e..c8da3df271e6 100644
--- a/fs/xfs/xfs_ialloc.h
+++ b/fs/xfs/xfs_ialloc.h
@@ -150,6 +150,6 @@ int xfs_inobt_lookup(struct xfs_btree_cur *cur, xfs_agino_t ino,
150int xfs_inobt_get_rec(struct xfs_btree_cur *cur, 150int xfs_inobt_get_rec(struct xfs_btree_cur *cur,
151 xfs_inobt_rec_incore_t *rec, int *stat); 151 xfs_inobt_rec_incore_t *rec, int *stat);
152 152
153void xfs_agi_write_verify(struct xfs_buf *bp); 153extern const struct xfs_buf_ops xfs_agi_buf_ops;
154 154
155#endif /* __XFS_IALLOC_H__ */ 155#endif /* __XFS_IALLOC_H__ */
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c
index 7761e1ebeff7..bec344b36507 100644
--- a/fs/xfs/xfs_ialloc_btree.c
+++ b/fs/xfs/xfs_ialloc_btree.c
@@ -217,22 +217,24 @@ xfs_inobt_verify(
217} 217}
218 218
219static void 219static void
220xfs_inobt_write_verify( 220xfs_inobt_read_verify(
221 struct xfs_buf *bp) 221 struct xfs_buf *bp)
222{ 222{
223 xfs_inobt_verify(bp); 223 xfs_inobt_verify(bp);
224} 224}
225 225
226void 226static void
227xfs_inobt_read_verify( 227xfs_inobt_write_verify(
228 struct xfs_buf *bp) 228 struct xfs_buf *bp)
229{ 229{
230 xfs_inobt_verify(bp); 230 xfs_inobt_verify(bp);
231 bp->b_pre_io = xfs_inobt_write_verify;
232 bp->b_iodone = NULL;
233 xfs_buf_ioend(bp, 0);
234} 231}
235 232
233const struct xfs_buf_ops xfs_inobt_buf_ops = {
234 .verify_read = xfs_inobt_read_verify,
235 .verify_write = xfs_inobt_write_verify,
236};
237
236#ifdef DEBUG 238#ifdef DEBUG
237STATIC int 239STATIC int
238xfs_inobt_keys_inorder( 240xfs_inobt_keys_inorder(
@@ -270,8 +272,7 @@ static const struct xfs_btree_ops xfs_inobt_ops = {
270 .init_rec_from_cur = xfs_inobt_init_rec_from_cur, 272 .init_rec_from_cur = xfs_inobt_init_rec_from_cur,
271 .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur, 273 .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur,
272 .key_diff = xfs_inobt_key_diff, 274 .key_diff = xfs_inobt_key_diff,
273 .read_verify = xfs_inobt_read_verify, 275 .buf_ops = &xfs_inobt_buf_ops,
274 .write_verify = xfs_inobt_write_verify,
275#ifdef DEBUG 276#ifdef DEBUG
276 .keys_inorder = xfs_inobt_keys_inorder, 277 .keys_inorder = xfs_inobt_keys_inorder,
277 .recs_inorder = xfs_inobt_recs_inorder, 278 .recs_inorder = xfs_inobt_recs_inorder,
diff --git a/fs/xfs/xfs_ialloc_btree.h b/fs/xfs/xfs_ialloc_btree.h
index f782ad0c4769..25c0239a8eab 100644
--- a/fs/xfs/xfs_ialloc_btree.h
+++ b/fs/xfs/xfs_ialloc_btree.h
@@ -109,4 +109,6 @@ extern struct xfs_btree_cur *xfs_inobt_init_cursor(struct xfs_mount *,
109 struct xfs_trans *, struct xfs_buf *, xfs_agnumber_t); 109 struct xfs_trans *, struct xfs_buf *, xfs_agnumber_t);
110extern int xfs_inobt_maxrecs(struct xfs_mount *, int, int); 110extern int xfs_inobt_maxrecs(struct xfs_mount *, int, int);
111 111
112extern const struct xfs_buf_ops xfs_inobt_buf_ops;
113
112#endif /* __XFS_IALLOC_BTREE_H__ */ 114#endif /* __XFS_IALLOC_BTREE_H__ */
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index dfcbe73f1db4..66282dcb821b 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -420,23 +420,27 @@ xfs_inode_buf_verify(
420 xfs_inobp_check(mp, bp); 420 xfs_inobp_check(mp, bp);
421} 421}
422 422
423void 423
424xfs_inode_buf_write_verify( 424static void
425xfs_inode_buf_read_verify(
425 struct xfs_buf *bp) 426 struct xfs_buf *bp)
426{ 427{
427 xfs_inode_buf_verify(bp); 428 xfs_inode_buf_verify(bp);
428} 429}
429 430
430void 431static void
431xfs_inode_buf_read_verify( 432xfs_inode_buf_write_verify(
432 struct xfs_buf *bp) 433 struct xfs_buf *bp)
433{ 434{
434 xfs_inode_buf_verify(bp); 435 xfs_inode_buf_verify(bp);
435 bp->b_pre_io = xfs_inode_buf_write_verify;
436 bp->b_iodone = NULL;
437 xfs_buf_ioend(bp, 0);
438} 436}
439 437
438const struct xfs_buf_ops xfs_inode_buf_ops = {
439 .verify_read = xfs_inode_buf_read_verify,
440 .verify_write = xfs_inode_buf_write_verify,
441};
442
443
440/* 444/*
441 * This routine is called to map an inode to the buffer containing the on-disk 445 * This routine is called to map an inode to the buffer containing the on-disk
442 * version of the inode. It returns a pointer to the buffer containing the 446 * version of the inode. It returns a pointer to the buffer containing the
@@ -462,7 +466,7 @@ xfs_imap_to_bp(
462 buf_flags |= XBF_UNMAPPED; 466 buf_flags |= XBF_UNMAPPED;
463 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno, 467 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno,
464 (int)imap->im_len, buf_flags, &bp, 468 (int)imap->im_len, buf_flags, &bp,
465 xfs_inode_buf_read_verify); 469 &xfs_inode_buf_ops);
466 if (error) { 470 if (error) {
467 if (error == EAGAIN) { 471 if (error == EAGAIN) {
468 ASSERT(buf_flags & XBF_TRYLOCK); 472 ASSERT(buf_flags & XBF_TRYLOCK);
@@ -1792,7 +1796,7 @@ xfs_ifree_cluster(
1792 * want it to fail. We can acheive this by adding a write 1796 * want it to fail. We can acheive this by adding a write
1793 * verifier to the buffer. 1797 * verifier to the buffer.
1794 */ 1798 */
1795 bp->b_pre_io = xfs_inode_buf_write_verify; 1799 bp->b_ops = &xfs_inode_buf_ops;
1796 1800
1797 /* 1801 /*
1798 * Walk the inodes already attached to the buffer and mark them 1802 * Walk the inodes already attached to the buffer and mark them
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 482214d120a7..22baf6ea4fac 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -554,8 +554,6 @@ int xfs_imap_to_bp(struct xfs_mount *, struct xfs_trans *,
554 struct xfs_buf **, uint, uint); 554 struct xfs_buf **, uint, uint);
555int xfs_iread(struct xfs_mount *, struct xfs_trans *, 555int xfs_iread(struct xfs_mount *, struct xfs_trans *,
556 struct xfs_inode *, uint); 556 struct xfs_inode *, uint);
557void xfs_inode_buf_read_verify(struct xfs_buf *);
558void xfs_inode_buf_write_verify(struct xfs_buf *);
559void xfs_dinode_to_disk(struct xfs_dinode *, 557void xfs_dinode_to_disk(struct xfs_dinode *,
560 struct xfs_icdinode *); 558 struct xfs_icdinode *);
561void xfs_idestroy_fork(struct xfs_inode *, int); 559void xfs_idestroy_fork(struct xfs_inode *, int);
@@ -600,5 +598,6 @@ void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);
600extern struct kmem_zone *xfs_ifork_zone; 598extern struct kmem_zone *xfs_ifork_zone;
601extern struct kmem_zone *xfs_inode_zone; 599extern struct kmem_zone *xfs_inode_zone;
602extern struct kmem_zone *xfs_ili_zone; 600extern struct kmem_zone *xfs_ili_zone;
601extern const struct xfs_buf_ops xfs_inode_buf_ops;
603 602
604#endif /* __XFS_INODE_H__ */ 603#endif /* __XFS_INODE_H__ */
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 7f86fdaab7ae..2ea7d402188d 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -397,7 +397,7 @@ xfs_bulkstat(
397 & ~r.ir_free) 397 & ~r.ir_free)
398 xfs_btree_reada_bufs(mp, agno, 398 xfs_btree_reada_bufs(mp, agno,
399 agbno, nbcluster, 399 agbno, nbcluster,
400 xfs_inode_buf_read_verify); 400 &xfs_inode_buf_ops);
401 } 401 }
402 irbp->ir_startino = r.ir_startino; 402 irbp->ir_startino = r.ir_startino;
403 irbp->ir_freecount = r.ir_freecount; 403 irbp->ir_freecount = r.ir_freecount;
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 924a4bc3d49a..931e8e23f192 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -3699,7 +3699,7 @@ xlog_do_recover(
3699 ASSERT(!(XFS_BUF_ISWRITE(bp))); 3699 ASSERT(!(XFS_BUF_ISWRITE(bp)));
3700 XFS_BUF_READ(bp); 3700 XFS_BUF_READ(bp);
3701 XFS_BUF_UNASYNC(bp); 3701 XFS_BUF_UNASYNC(bp);
3702 bp->b_iodone = xfs_sb_read_verify; 3702 bp->b_ops = &xfs_sb_buf_ops;
3703 xfsbdstrat(log->l_mp, bp); 3703 xfsbdstrat(log->l_mp, bp);
3704 error = xfs_buf_iowait(bp); 3704 error = xfs_buf_iowait(bp);
3705 if (error) { 3705 if (error) {
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 152a7fc843f9..da508463ff10 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -631,21 +631,11 @@ xfs_sb_verify(
631 xfs_buf_ioerror(bp, error); 631 xfs_buf_ioerror(bp, error);
632} 632}
633 633
634void 634static void
635xfs_sb_write_verify(
636 struct xfs_buf *bp)
637{
638 xfs_sb_verify(bp);
639}
640
641void
642xfs_sb_read_verify( 635xfs_sb_read_verify(
643 struct xfs_buf *bp) 636 struct xfs_buf *bp)
644{ 637{
645 xfs_sb_verify(bp); 638 xfs_sb_verify(bp);
646 bp->b_pre_io = xfs_sb_write_verify;
647 bp->b_iodone = NULL;
648 xfs_buf_ioend(bp, 0);
649} 639}
650 640
651/* 641/*
@@ -654,7 +644,7 @@ xfs_sb_read_verify(
654 * If we find an XFS superblock, the run a normal, noisy mount because we are 644 * If we find an XFS superblock, the run a normal, noisy mount because we are
655 * really going to mount it and want to know about errors. 645 * really going to mount it and want to know about errors.
656 */ 646 */
657void 647static void
658xfs_sb_quiet_read_verify( 648xfs_sb_quiet_read_verify(
659 struct xfs_buf *bp) 649 struct xfs_buf *bp)
660{ 650{
@@ -671,6 +661,23 @@ xfs_sb_quiet_read_verify(
671 xfs_buf_ioerror(bp, EFSCORRUPTED); 661 xfs_buf_ioerror(bp, EFSCORRUPTED);
672} 662}
673 663
664static void
665xfs_sb_write_verify(
666 struct xfs_buf *bp)
667{
668 xfs_sb_verify(bp);
669}
670
671const struct xfs_buf_ops xfs_sb_buf_ops = {
672 .verify_read = xfs_sb_read_verify,
673 .verify_write = xfs_sb_write_verify,
674};
675
676static const struct xfs_buf_ops xfs_sb_quiet_buf_ops = {
677 .verify_read = xfs_sb_quiet_read_verify,
678 .verify_write = xfs_sb_write_verify,
679};
680
674/* 681/*
675 * xfs_readsb 682 * xfs_readsb
676 * 683 *
@@ -697,8 +704,8 @@ xfs_readsb(xfs_mount_t *mp, int flags)
697reread: 704reread:
698 bp = xfs_buf_read_uncached(mp->m_ddev_targp, XFS_SB_DADDR, 705 bp = xfs_buf_read_uncached(mp->m_ddev_targp, XFS_SB_DADDR,
699 BTOBB(sector_size), 0, 706 BTOBB(sector_size), 0,
700 loud ? xfs_sb_read_verify 707 loud ? &xfs_sb_buf_ops
701 : xfs_sb_quiet_read_verify); 708 : &xfs_sb_quiet_buf_ops);
702 if (!bp) { 709 if (!bp) {
703 if (loud) 710 if (loud)
704 xfs_warn(mp, "SB buffer read failed"); 711 xfs_warn(mp, "SB buffer read failed");
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 29c1b3ac920e..bab8314507e4 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -385,12 +385,12 @@ extern void xfs_set_low_space_thresholds(struct xfs_mount *);
385 385
386#endif /* __KERNEL__ */ 386#endif /* __KERNEL__ */
387 387
388extern void xfs_sb_read_verify(struct xfs_buf *);
389extern void xfs_sb_write_verify(struct xfs_buf *bp);
390extern void xfs_mod_sb(struct xfs_trans *, __int64_t); 388extern void xfs_mod_sb(struct xfs_trans *, __int64_t);
391extern int xfs_initialize_perag(struct xfs_mount *, xfs_agnumber_t, 389extern int xfs_initialize_perag(struct xfs_mount *, xfs_agnumber_t,
392 xfs_agnumber_t *); 390 xfs_agnumber_t *);
393extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *); 391extern void xfs_sb_from_disk(struct xfs_sb *, struct xfs_dsb *);
394extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t); 392extern void xfs_sb_to_disk(struct xfs_dsb *, struct xfs_sb *, __int64_t);
395 393
394extern const struct xfs_buf_ops xfs_sb_buf_ops;
395
396#endif /* __XFS_MOUNT_H__ */ 396#endif /* __XFS_MOUNT_H__ */
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
index bd40ae9624e5..e6a0af0ba007 100644
--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -893,7 +893,7 @@ xfs_qm_dqiter_bufs(
893 error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, 893 error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp,
894 XFS_FSB_TO_DADDR(mp, bno), 894 XFS_FSB_TO_DADDR(mp, bno),
895 mp->m_quotainfo->qi_dqchunklen, 0, &bp, 895 mp->m_quotainfo->qi_dqchunklen, 0, &bp,
896 xfs_dquot_buf_read_verify); 896 &xfs_dquot_buf_ops);
897 if (error) 897 if (error)
898 break; 898 break;
899 899
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index f02d40296506..c6c0601abd7a 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -474,7 +474,7 @@ int xfs_trans_read_buf_map(struct xfs_mount *mp,
474 struct xfs_buf_map *map, int nmaps, 474 struct xfs_buf_map *map, int nmaps,
475 xfs_buf_flags_t flags, 475 xfs_buf_flags_t flags,
476 struct xfs_buf **bpp, 476 struct xfs_buf **bpp,
477 xfs_buf_iodone_t verify); 477 const struct xfs_buf_ops *ops);
478 478
479static inline int 479static inline int
480xfs_trans_read_buf( 480xfs_trans_read_buf(
@@ -485,11 +485,11 @@ xfs_trans_read_buf(
485 int numblks, 485 int numblks,
486 xfs_buf_flags_t flags, 486 xfs_buf_flags_t flags,
487 struct xfs_buf **bpp, 487 struct xfs_buf **bpp,
488 xfs_buf_iodone_t verify) 488 const struct xfs_buf_ops *ops)
489{ 489{
490 DEFINE_SINGLE_BUF_MAP(map, blkno, numblks); 490 DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
491 return xfs_trans_read_buf_map(mp, tp, target, &map, 1, 491 return xfs_trans_read_buf_map(mp, tp, target, &map, 1,
492 flags, bpp, verify); 492 flags, bpp, ops);
493} 493}
494 494
495struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int); 495struct xfs_buf *xfs_trans_getsb(xfs_trans_t *, struct xfs_mount *, int);
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index 977628207b45..4fc17d479d42 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -258,7 +258,7 @@ xfs_trans_read_buf_map(
258 int nmaps, 258 int nmaps,
259 xfs_buf_flags_t flags, 259 xfs_buf_flags_t flags,
260 struct xfs_buf **bpp, 260 struct xfs_buf **bpp,
261 xfs_buf_iodone_t verify) 261 const struct xfs_buf_ops *ops)
262{ 262{
263 xfs_buf_t *bp; 263 xfs_buf_t *bp;
264 xfs_buf_log_item_t *bip; 264 xfs_buf_log_item_t *bip;
@@ -266,7 +266,7 @@ xfs_trans_read_buf_map(
266 266
267 *bpp = NULL; 267 *bpp = NULL;
268 if (!tp) { 268 if (!tp) {
269 bp = xfs_buf_read_map(target, map, nmaps, flags, verify); 269 bp = xfs_buf_read_map(target, map, nmaps, flags, ops);
270 if (!bp) 270 if (!bp)
271 return (flags & XBF_TRYLOCK) ? 271 return (flags & XBF_TRYLOCK) ?
272 EAGAIN : XFS_ERROR(ENOMEM); 272 EAGAIN : XFS_ERROR(ENOMEM);
@@ -315,7 +315,7 @@ xfs_trans_read_buf_map(
315 ASSERT(!XFS_BUF_ISASYNC(bp)); 315 ASSERT(!XFS_BUF_ISASYNC(bp));
316 ASSERT(bp->b_iodone == NULL); 316 ASSERT(bp->b_iodone == NULL);
317 XFS_BUF_READ(bp); 317 XFS_BUF_READ(bp);
318 bp->b_iodone = verify; 318 bp->b_ops = ops;
319 xfsbdstrat(tp->t_mountp, bp); 319 xfsbdstrat(tp->t_mountp, bp);
320 error = xfs_buf_iowait(bp); 320 error = xfs_buf_iowait(bp);
321 if (error) { 321 if (error) {
@@ -352,7 +352,7 @@ xfs_trans_read_buf_map(
352 return 0; 352 return 0;
353 } 353 }
354 354
355 bp = xfs_buf_read_map(target, map, nmaps, flags, verify); 355 bp = xfs_buf_read_map(target, map, nmaps, flags, ops);
356 if (bp == NULL) { 356 if (bp == NULL) {
357 *bpp = NULL; 357 *bpp = NULL;
358 return (flags & XBF_TRYLOCK) ? 358 return (flags & XBF_TRYLOCK) ?