summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_da_btree.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2012-11-14 17:54:40 +1100
committerBen Myers <bpm@sgi.com>2012-11-15 21:35:12 -0600
commit1813dd64057490e7a0678a885c4fe6d02f78bdc1 (patch)
treecaf95e2be7881b771da65561b2f1664d73588401 /fs/xfs/xfs_da_btree.c
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/xfs/xfs_da_btree.c')
-rw-r--r--fs/xfs/xfs_da_btree.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 087950fc2eb..4d7696a0241 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -117,6 +117,12 @@ xfs_da_node_write_verify(
xfs_da_node_verify(bp);
}
+/*
+ * leaf/node format detection on trees is sketchy, so a node read can be done on
+ * leaf level blocks when detection identifies the tree as a node format tree
+ * incorrectly. In this case, we need to swap the verifier to match the correct
+ * format of the block being read.
+ */
static void
xfs_da_node_read_verify(
struct xfs_buf *bp)
@@ -129,10 +135,12 @@ xfs_da_node_read_verify(
xfs_da_node_verify(bp);
break;
case XFS_ATTR_LEAF_MAGIC:
- xfs_attr_leaf_read_verify(bp);
+ bp->b_ops = &xfs_attr_leaf_buf_ops;
+ bp->b_ops->verify_read(bp);
return;
case XFS_DIR2_LEAFN_MAGIC:
- xfs_dir2_leafn_read_verify(bp);
+ bp->b_ops = &xfs_dir2_leafn_buf_ops;
+ bp->b_ops->verify_read(bp);
return;
default:
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
@@ -140,12 +148,14 @@ xfs_da_node_read_verify(
xfs_buf_ioerror(bp, EFSCORRUPTED);
break;
}
-
- bp->b_pre_io = xfs_da_node_write_verify;
- bp->b_iodone = NULL;
- xfs_buf_ioend(bp, 0);
}
+const struct xfs_buf_ops xfs_da_node_buf_ops = {
+ .verify_read = xfs_da_node_read_verify,
+ .verify_write = xfs_da_node_write_verify,
+};
+
+
int
xfs_da_node_read(
struct xfs_trans *tp,
@@ -156,7 +166,7 @@ xfs_da_node_read(
int which_fork)
{
return xfs_da_read_buf(tp, dp, bno, mappedbno, bpp,
- which_fork, xfs_da_node_read_verify);
+ which_fork, &xfs_da_node_buf_ops);
}
/*========================================================================
@@ -193,7 +203,7 @@ xfs_da_node_create(xfs_da_args_t *args, xfs_dablk_t blkno, int level,
xfs_trans_log_buf(tp, bp,
XFS_DA_LOGRANGE(node, &node->hdr, sizeof(node->hdr)));
- bp->b_pre_io = xfs_da_node_write_verify;
+ bp->b_ops = &xfs_da_node_buf_ops;
*bpp = bp;
return(0);
}
@@ -394,7 +404,7 @@ xfs_da_root_split(xfs_da_state_t *state, xfs_da_state_blk_t *blk1,
memcpy(node, oldroot, size);
xfs_trans_log_buf(tp, bp, 0, size - 1);
- bp->b_pre_io = blk1->bp->b_pre_io;
+ bp->b_ops = blk1->bp->b_ops;
blk1->bp = bp;
blk1->blkno = blkno;
@@ -828,11 +838,11 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk)
/*
* This could be copying a leaf back into the root block in the case of
* there only being a single leaf block left in the tree. Hence we have
- * to update the pre_io pointer as well to match the buffer type change
+ * to update the b_ops pointer as well to match the buffer type change
* that could occur.
*/
memcpy(root_blk->bp->b_addr, bp->b_addr, state->blocksize);
- root_blk->bp->b_pre_io = bp->b_pre_io;
+ root_blk->bp->b_ops = bp->b_ops;
xfs_trans_log_buf(args->trans, root_blk->bp, 0, state->blocksize - 1);
error = xfs_da_shrink_inode(args, child, bp);
return(error);
@@ -2223,7 +2233,7 @@ xfs_da_read_buf(
xfs_daddr_t mappedbno,
struct xfs_buf **bpp,
int whichfork,
- xfs_buf_iodone_t verifier)
+ const struct xfs_buf_ops *ops)
{
struct xfs_buf *bp;
struct xfs_buf_map map;
@@ -2245,7 +2255,7 @@ xfs_da_read_buf(
error = xfs_trans_read_buf_map(dp->i_mount, trans,
dp->i_mount->m_ddev_targp,
- mapp, nmap, 0, &bp, verifier);
+ mapp, nmap, 0, &bp, ops);
if (error)
goto out_free;
@@ -2303,7 +2313,7 @@ xfs_da_reada_buf(
xfs_dablk_t bno,
xfs_daddr_t mappedbno,
int whichfork,
- xfs_buf_iodone_t verifier)
+ const struct xfs_buf_ops *ops)
{
struct xfs_buf_map map;
struct xfs_buf_map *mapp;
@@ -2322,7 +2332,7 @@ xfs_da_reada_buf(
}
mappedbno = mapp[0].bm_bn;
- xfs_buf_readahead_map(dp->i_mount->m_ddev_targp, mapp, nmap, NULL);
+ xfs_buf_readahead_map(dp->i_mount->m_ddev_targp, mapp, nmap, ops);
out_free:
if (mapp != &map)