diff options
Diffstat (limited to 'fs/xfs/xfs_dir2_data.c')
-rw-r--r-- | fs/xfs/xfs_dir2_data.c | 52 |
1 files changed, 43 insertions, 9 deletions
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( } } -void -xfs_dir2_data_write_verify( +/* + * Readahead of the first block of the directory when it is opened is completely + * oblivious to the format of the directory. Hence we can either get a block + * format buffer or a data format buffer on readahead. + */ +static void +xfs_dir2_data_reada_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_dir2_data_hdr *hdr = bp->b_addr; + + switch (hdr->magic) { + case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC): + bp->b_ops = &xfs_dir2_block_buf_ops; + bp->b_ops->verify_read(bp); + return; + case cpu_to_be32(XFS_DIR2_DATA_MAGIC): + xfs_dir2_data_verify(bp); + return; + default: + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr); + xfs_buf_ioerror(bp, EFSCORRUPTED); + break; + } +} + +static void +xfs_dir2_data_read_verify( struct xfs_buf *bp) { xfs_dir2_data_verify(bp); } static void -xfs_dir2_data_read_verify( +xfs_dir2_data_write_verify( struct xfs_buf *bp) { xfs_dir2_data_verify(bp); - bp->b_pre_io = xfs_dir2_data_write_verify; - bp->b_iodone = NULL; - xfs_buf_ioend(bp, 0); } +const struct xfs_buf_ops xfs_dir2_data_buf_ops = { + .verify_read = xfs_dir2_data_read_verify, + .verify_write = xfs_dir2_data_write_verify, +}; + +static const struct xfs_buf_ops xfs_dir2_data_reada_buf_ops = { + .verify_read = xfs_dir2_data_reada_verify, + .verify_write = xfs_dir2_data_write_verify, +}; + int xfs_dir2_data_read( @@ -229,7 +263,7 @@ xfs_dir2_data_read( struct xfs_buf **bpp) { return xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp, - XFS_DATA_FORK, xfs_dir2_data_read_verify); + XFS_DATA_FORK, &xfs_dir2_data_buf_ops); } int @@ -240,7 +274,7 @@ xfs_dir2_data_readahead( xfs_daddr_t mapped_bno) { return xfs_da_reada_buf(tp, dp, bno, mapped_bno, - XFS_DATA_FORK, xfs_dir2_data_read_verify); + XFS_DATA_FORK, &xfs_dir2_data_reada_buf_ops); } /* @@ -484,7 +518,7 @@ xfs_dir2_data_init( XFS_DATA_FORK); if (error) return error; - bp->b_pre_io = xfs_dir2_data_write_verify; + bp->b_ops = &xfs_dir2_data_buf_ops; /* * Initialize the header. |