xfs: factor out dir2 data block reading
authorDave Chinner <dchinner@redhat.com>
Mon, 12 Nov 2012 11:54:14 +0000 (22:54 +1100)
committerBen Myers <bpm@sgi.com>
Fri, 16 Nov 2012 03:34:45 +0000 (21:34 -0600)
And add a verifier callback function while there.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Phil White <pwhite@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
fs/xfs/xfs_dir2_block.c
fs/xfs/xfs_dir2_data.c
fs/xfs/xfs_dir2_leaf.c
fs/xfs/xfs_dir2_node.c
fs/xfs/xfs_dir2_priv.h

index 57351b8688616fe0e31f5b4bda065497c65c739d..ca03b109772d9b121b4198306afba61c47af6936 100644 (file)
@@ -970,8 +970,7 @@ xfs_dir2_leaf_to_block(
         * Read the data block if we don't already have it, give up if it fails.
         */
        if (!dbp) {
-               error = xfs_da_read_buf(tp, dp, mp->m_dirdatablk, -1, &dbp,
-                                       XFS_DATA_FORK, NULL);
+               error = xfs_dir2_data_read(tp, dp, mp->m_dirdatablk, -1, &dbp);
                if (error)
                        return error;
        }
index cb117234e32ef03c2a45f22e3eb6cb2a6e441214..0ef04f1bf51123722b09d3ca1502715c1d44a1a4 100644 (file)
@@ -185,6 +185,38 @@ __xfs_dir2_data_check(
        return 0;
 }
 
+static void
+xfs_dir2_data_verify(
+       struct xfs_buf          *bp)
+{
+       struct xfs_mount        *mp = bp->b_target->bt_mount;
+       struct xfs_dir2_data_hdr *hdr = bp->b_addr;
+       int                     block_ok = 0;
+
+       block_ok = hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC);
+       block_ok = block_ok && __xfs_dir2_data_check(NULL, bp) == 0;
+
+       if (!block_ok) {
+               XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr);
+               xfs_buf_ioerror(bp, EFSCORRUPTED);
+       }
+
+       bp->b_iodone = NULL;
+       xfs_buf_ioend(bp, 0);
+}
+
+int
+xfs_dir2_data_read(
+       struct xfs_trans        *tp,
+       struct xfs_inode        *dp,
+       xfs_dablk_t             bno,
+       xfs_daddr_t             mapped_bno,
+       struct xfs_buf          **bpp)
+{
+       return xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp,
+                                       XFS_DATA_FORK, xfs_dir2_data_verify);
+}
+
 /*
  * Given a data block and an unused entry from that block,
  * return the bestfree entry if any that corresponds to it.
index 6c1359dc98988d0015a483ee3b25b9de94cc3369..0fdf765c917fe11b936552d4ba84e5eea54d27c9 100644 (file)
@@ -493,14 +493,14 @@ xfs_dir2_leaf_addname(
                hdr = dbp->b_addr;
                bestsp[use_block] = hdr->bestfree[0].length;
                grown = 1;
-       }
-       /*
-        * Already had space in some data block.
-        * Just read that one in.
-        */
-       else {
-               error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, use_block),
-                                       -1, &dbp, XFS_DATA_FORK, NULL);
+       } else {
+               /*
+                * Already had space in some data block.
+                * Just read that one in.
+                */
+               error = xfs_dir2_data_read(tp, dp,
+                                          xfs_dir2_db_to_da(mp, use_block),
+                                          -1, &dbp);
                if (error) {
                        xfs_trans_brelse(tp, lbp);
                        return error;
@@ -508,7 +508,6 @@ xfs_dir2_leaf_addname(
                hdr = dbp->b_addr;
                grown = 0;
        }
-       xfs_dir2_data_check(dp, dbp);
        /*
         * Point to the biggest freespace in our data block.
         */
@@ -891,10 +890,9 @@ xfs_dir2_leaf_readbuf(
         * Read the directory block starting at the first mapping.
         */
        mip->curdb = xfs_dir2_da_to_db(mp, map->br_startoff);
-       error = xfs_da_read_buf(NULL, dp, map->br_startoff,
+       error = xfs_dir2_data_read(NULL, dp, map->br_startoff,
                        map->br_blockcount >= mp->m_dirblkfsbs ?
-                           XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1,
-                       &bp, XFS_DATA_FORK, NULL);
+                           XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, &bp);
 
        /*
         * Should just skip over the data block instead of giving up.
@@ -1408,14 +1406,13 @@ xfs_dir2_leaf_lookup_int(
                if (newdb != curdb) {
                        if (dbp)
                                xfs_trans_brelse(tp, dbp);
-                       error = xfs_da_read_buf(tp, dp,
-                                               xfs_dir2_db_to_da(mp, newdb),
-                                               -1, &dbp, XFS_DATA_FORK, NULL);
+                       error = xfs_dir2_data_read(tp, dp,
+                                                  xfs_dir2_db_to_da(mp, newdb),
+                                                  -1, &dbp);
                        if (error) {
                                xfs_trans_brelse(tp, lbp);
                                return error;
                        }
-                       xfs_dir2_data_check(dp, dbp);
                        curdb = newdb;
                }
                /*
@@ -1450,9 +1447,9 @@ xfs_dir2_leaf_lookup_int(
                ASSERT(cidb != -1);
                if (cidb != curdb) {
                        xfs_trans_brelse(tp, dbp);
-                       error = xfs_da_read_buf(tp, dp,
-                                               xfs_dir2_db_to_da(mp, cidb),
-                                               -1, &dbp, XFS_DATA_FORK, NULL);
+                       error = xfs_dir2_data_read(tp, dp,
+                                                  xfs_dir2_db_to_da(mp, cidb),
+                                                  -1, &dbp);
                        if (error) {
                                xfs_trans_brelse(tp, lbp);
                                return error;
@@ -1737,8 +1734,7 @@ xfs_dir2_leaf_trim_data(
        /*
         * Read the offending data block.  We need its buffer.
         */
-       error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp,
-                               XFS_DATA_FORK, NULL);
+       error = xfs_dir2_data_read(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp);
        if (error)
                return error;
 
index d7f899dfbff5a62a91098f2752870beb3e4786fa..67b811c17eaabf996522561b40af6647757646cf 100644 (file)
@@ -583,9 +583,9 @@ xfs_dir2_leafn_lookup_for_entry(
                                ASSERT(state->extravalid);
                                curbp = state->extrablk.bp;
                        } else {
-                               error = xfs_da_read_buf(tp, dp,
+                               error = xfs_dir2_data_read(tp, dp,
                                                xfs_dir2_db_to_da(mp, newdb),
-                                               -1, &curbp, XFS_DATA_FORK, NULL);
+                                               -1, &curbp);
                                if (error)
                                        return error;
                        }
@@ -1692,8 +1692,8 @@ xfs_dir2_node_addname_int(
                /*
                 * Read the data block in.
                 */
-               error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, dbno),
-                                       -1, &dbp, XFS_DATA_FORK, NULL);
+               error = xfs_dir2_data_read(tp, dp, xfs_dir2_db_to_da(mp, dbno),
+                                          -1, &dbp);
                if (error)
                        return error;
                hdr = dbp->b_addr;
index 263a6328791033773d7807dbd18adc1dba5b726a..71ec8283910790c1908c946da629758b5684e865 100644 (file)
@@ -46,6 +46,8 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
 #define        xfs_dir2_data_check(dp,bp)
 #endif
 extern int __xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_buf *bp);
+extern int xfs_dir2_data_read(struct xfs_trans *tp, struct xfs_inode *dp,
+               xfs_dablk_t bno, xfs_daddr_t mapped_bno, struct xfs_buf **bpp);
 
 extern struct xfs_dir2_data_free *
 xfs_dir2_data_freeinsert(struct xfs_dir2_data_hdr *hdr,