aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2_data.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_dir2_data.c')
-rw-r--r--fs/xfs/xfs_dir2_data.c52
1 files changed, 43 insertions, 9 deletions
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index dcb8a873ab9..ffcf1774152 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.