Commit d9392a4bb75503fc2adbb5237c3df940c6467eb2

Authored by Dave Chinner
Committed by Ben Myers
1 parent ad14c33ac8

xfs: add xfs_da_node verification

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Phil White <pwhite@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>

Showing 7 changed files with 107 additions and 50 deletions Side-by-side Diff

... ... @@ -1696,10 +1696,10 @@
1696 1696 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1697 1697 for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1698 1698 if (blk->disk_blkno) {
1699   - error = xfs_da_read_buf(state->args->trans,
  1699 + error = xfs_da_node_read(state->args->trans,
1700 1700 state->args->dp,
1701 1701 blk->blkno, blk->disk_blkno,
1702   - &blk->bp, XFS_ATTR_FORK, NULL);
  1702 + &blk->bp, XFS_ATTR_FORK);
1703 1703 if (error)
1704 1704 return(error);
1705 1705 } else {
1706 1706  
... ... @@ -1715,10 +1715,10 @@
1715 1715 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1716 1716 for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1717 1717 if (blk->disk_blkno) {
1718   - error = xfs_da_read_buf(state->args->trans,
  1718 + error = xfs_da_node_read(state->args->trans,
1719 1719 state->args->dp,
1720 1720 blk->blkno, blk->disk_blkno,
1721   - &blk->bp, XFS_ATTR_FORK, NULL);
  1721 + &blk->bp, XFS_ATTR_FORK);
1722 1722 if (error)
1723 1723 return(error);
1724 1724 } else {
... ... @@ -1807,8 +1807,8 @@
1807 1807 */
1808 1808 bp = NULL;
1809 1809 if (cursor->blkno > 0) {
1810   - error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1,
1811   - &bp, XFS_ATTR_FORK, NULL);
  1810 + error = xfs_da_node_read(NULL, context->dp, cursor->blkno, -1,
  1811 + &bp, XFS_ATTR_FORK);
1812 1812 if ((error != 0) && (error != EFSCORRUPTED))
1813 1813 return(error);
1814 1814 if (bp) {
1815 1815  
1816 1816  
... ... @@ -1849,17 +1849,11 @@
1849 1849 if (bp == NULL) {
1850 1850 cursor->blkno = 0;
1851 1851 for (;;) {
1852   - error = xfs_da_read_buf(NULL, context->dp,
  1852 + error = xfs_da_node_read(NULL, context->dp,
1853 1853 cursor->blkno, -1, &bp,
1854   - XFS_ATTR_FORK, NULL);
  1854 + XFS_ATTR_FORK);
1855 1855 if (error)
1856 1856 return(error);
1857   - if (unlikely(bp == NULL)) {
1858   - XFS_ERROR_REPORT("xfs_attr_node_list(2)",
1859   - XFS_ERRLEVEL_LOW,
1860   - context->dp->i_mount);
1861   - return(XFS_ERROR(EFSCORRUPTED));
1862   - }
1863 1857 node = bp->b_addr;
1864 1858 if (node->hdr.info.magic ==
1865 1859 cpu_to_be16(XFS_ATTR_LEAF_MAGIC))
fs/xfs/xfs_attr_leaf.c
... ... @@ -88,7 +88,7 @@
88 88 xfs_mount_t *mp);
89 89 STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
90 90  
91   -static void
  91 +void
92 92 xfs_attr_leaf_verify(
93 93 struct xfs_buf *bp)
94 94 {
... ... @@ -2765,7 +2765,7 @@
2765 2765 * the extents in reverse order the extent containing
2766 2766 * block 0 must still be there.
2767 2767 */
2768   - error = xfs_da_read_buf(*trans, dp, 0, -1, &bp, XFS_ATTR_FORK, NULL);
  2768 + error = xfs_da_node_read(*trans, dp, 0, -1, &bp, XFS_ATTR_FORK);
2769 2769 if (error)
2770 2770 return(error);
2771 2771 blkno = XFS_BUF_ADDR(bp);
... ... @@ -2850,8 +2850,8 @@
2850 2850 * traversal of the tree so we may deal with many blocks
2851 2851 * before we come back to this one.
2852 2852 */
2853   - error = xfs_da_read_buf(*trans, dp, child_fsb, -2, &child_bp,
2854   - XFS_ATTR_FORK, NULL);
  2853 + error = xfs_da_node_read(*trans, dp, child_fsb, -2, &child_bp,
  2854 + XFS_ATTR_FORK);
2855 2855 if (error)
2856 2856 return(error);
2857 2857 if (child_bp) {
... ... @@ -2891,8 +2891,8 @@
2891 2891 * child block number.
2892 2892 */
2893 2893 if ((i+1) < count) {
2894   - error = xfs_da_read_buf(*trans, dp, 0, parent_blkno,
2895   - &bp, XFS_ATTR_FORK, NULL);
  2894 + error = xfs_da_node_read(*trans, dp, 0, parent_blkno,
  2895 + &bp, XFS_ATTR_FORK);
2896 2896 if (error)
2897 2897 return(error);
2898 2898 child_fsb = be32_to_cpu(node->btree[i+1].before);
fs/xfs/xfs_attr_leaf.h
... ... @@ -227,9 +227,6 @@
227 227 int xfs_attr_leaf_clearflag(struct xfs_da_args *args);
228 228 int xfs_attr_leaf_setflag(struct xfs_da_args *args);
229 229 int xfs_attr_leaf_flipflags(xfs_da_args_t *args);
230   -int xfs_attr_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp,
231   - xfs_dablk_t bno, xfs_daddr_t mappedbno,
232   - struct xfs_buf **bpp);
233 230  
234 231 /*
235 232 * Routines used for growing the Btree.
... ... @@ -264,5 +261,10 @@
264 261 struct xfs_buf *leaf2_bp);
265 262 int xfs_attr_leaf_newentsize(int namelen, int valuelen, int blocksize,
266 263 int *local);
  264 +int xfs_attr_leaf_read(struct xfs_trans *tp, struct xfs_inode *dp,
  265 + xfs_dablk_t bno, xfs_daddr_t mappedbno,
  266 + struct xfs_buf **bpp);
  267 +void xfs_attr_leaf_verify(struct xfs_buf *bp);
  268 +
267 269 #endif /* __XFS_ATTR_LEAF_H__ */
fs/xfs/xfs_da_btree.c
... ... @@ -91,6 +91,68 @@
91 91 xfs_da_state_blk_t *save_blk);
92 92 STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state);
93 93  
  94 +static void
  95 +__xfs_da_node_verify(
  96 + struct xfs_buf *bp)
  97 +{
  98 + struct xfs_mount *mp = bp->b_target->bt_mount;
  99 + struct xfs_da_node_hdr *hdr = bp->b_addr;
  100 + int block_ok = 0;
  101 +
  102 + block_ok = hdr->info.magic == cpu_to_be16(XFS_DA_NODE_MAGIC);
  103 + block_ok = block_ok &&
  104 + be16_to_cpu(hdr->level) > 0 &&
  105 + be16_to_cpu(hdr->count) > 0 ;
  106 + if (!block_ok) {
  107 + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr);
  108 + xfs_buf_ioerror(bp, EFSCORRUPTED);
  109 + }
  110 +
  111 + bp->b_iodone = NULL;
  112 + xfs_buf_ioend(bp, 0);
  113 +}
  114 +
  115 +static void
  116 +xfs_da_node_verify(
  117 + struct xfs_buf *bp)
  118 +{
  119 + struct xfs_mount *mp = bp->b_target->bt_mount;
  120 + struct xfs_da_blkinfo *info = bp->b_addr;
  121 +
  122 + switch (be16_to_cpu(info->magic)) {
  123 + case XFS_DA_NODE_MAGIC:
  124 + __xfs_da_node_verify(bp);
  125 + return;
  126 + case XFS_ATTR_LEAF_MAGIC:
  127 + xfs_attr_leaf_verify(bp);
  128 + return;
  129 + case XFS_DIR2_LEAFN_MAGIC:
  130 + xfs_dir2_leafn_verify(bp);
  131 + return;
  132 + default:
  133 + break;
  134 + }
  135 +
  136 + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, info);
  137 + xfs_buf_ioerror(bp, EFSCORRUPTED);
  138 +
  139 + bp->b_iodone = NULL;
  140 + xfs_buf_ioend(bp, 0);
  141 +}
  142 +
  143 +int
  144 +xfs_da_node_read(
  145 + struct xfs_trans *tp,
  146 + struct xfs_inode *dp,
  147 + xfs_dablk_t bno,
  148 + xfs_daddr_t mappedbno,
  149 + struct xfs_buf **bpp,
  150 + int which_fork)
  151 +{
  152 + return xfs_da_read_buf(tp, dp, bno, mappedbno, bpp,
  153 + which_fork, xfs_da_node_verify);
  154 +}
  155 +
94 156 /*========================================================================
95 157 * Routines used for growing the Btree.
96 158 *========================================================================*/
... ... @@ -746,8 +808,8 @@
746 808 */
747 809 child = be32_to_cpu(oldroot->btree[0].before);
748 810 ASSERT(child != 0);
749   - error = xfs_da_read_buf(args->trans, args->dp, child, -1, &bp,
750   - args->whichfork, NULL);
  811 + error = xfs_da_node_read(args->trans, args->dp, child, -1, &bp,
  812 + args->whichfork);
751 813 if (error)
752 814 return(error);
753 815 ASSERT(bp != NULL);
... ... @@ -837,9 +899,8 @@
837 899 blkno = be32_to_cpu(info->back);
838 900 if (blkno == 0)
839 901 continue;
840   - error = xfs_da_read_buf(state->args->trans, state->args->dp,
841   - blkno, -1, &bp, state->args->whichfork,
842   - NULL);
  902 + error = xfs_da_node_read(state->args->trans, state->args->dp,
  903 + blkno, -1, &bp, state->args->whichfork);
843 904 if (error)
844 905 return(error);
845 906 ASSERT(bp != NULL);
... ... @@ -1084,8 +1145,8 @@
1084 1145 * Read the next node down in the tree.
1085 1146 */
1086 1147 blk->blkno = blkno;
1087   - error = xfs_da_read_buf(args->trans, args->dp, blkno,
1088   - -1, &blk->bp, args->whichfork, NULL);
  1148 + error = xfs_da_node_read(args->trans, args->dp, blkno,
  1149 + -1, &blk->bp, args->whichfork);
1089 1150 if (error) {
1090 1151 blk->blkno = 0;
1091 1152 state->path.active--;
1092 1153  
... ... @@ -1246,9 +1307,9 @@
1246 1307 new_info->forw = cpu_to_be32(old_blk->blkno);
1247 1308 new_info->back = old_info->back;
1248 1309 if (old_info->back) {
1249   - error = xfs_da_read_buf(args->trans, args->dp,
  1310 + error = xfs_da_node_read(args->trans, args->dp,
1250 1311 be32_to_cpu(old_info->back),
1251   - -1, &bp, args->whichfork, NULL);
  1312 + -1, &bp, args->whichfork);
1252 1313 if (error)
1253 1314 return(error);
1254 1315 ASSERT(bp != NULL);
1255 1316  
... ... @@ -1267,9 +1328,9 @@
1267 1328 new_info->forw = old_info->forw;
1268 1329 new_info->back = cpu_to_be32(old_blk->blkno);
1269 1330 if (old_info->forw) {
1270   - error = xfs_da_read_buf(args->trans, args->dp,
  1331 + error = xfs_da_node_read(args->trans, args->dp,
1271 1332 be32_to_cpu(old_info->forw),
1272   - -1, &bp, args->whichfork, NULL);
  1333 + -1, &bp, args->whichfork);
1273 1334 if (error)
1274 1335 return(error);
1275 1336 ASSERT(bp != NULL);
1276 1337  
... ... @@ -1367,9 +1428,9 @@
1367 1428 trace_xfs_da_unlink_back(args);
1368 1429 save_info->back = drop_info->back;
1369 1430 if (drop_info->back) {
1370   - error = xfs_da_read_buf(args->trans, args->dp,
  1431 + error = xfs_da_node_read(args->trans, args->dp,
1371 1432 be32_to_cpu(drop_info->back),
1372   - -1, &bp, args->whichfork, NULL);
  1433 + -1, &bp, args->whichfork);
1373 1434 if (error)
1374 1435 return(error);
1375 1436 ASSERT(bp != NULL);
1376 1437  
... ... @@ -1384,9 +1445,9 @@
1384 1445 trace_xfs_da_unlink_forward(args);
1385 1446 save_info->forw = drop_info->forw;
1386 1447 if (drop_info->forw) {
1387   - error = xfs_da_read_buf(args->trans, args->dp,
  1448 + error = xfs_da_node_read(args->trans, args->dp,
1388 1449 be32_to_cpu(drop_info->forw),
1389   - -1, &bp, args->whichfork, NULL);
  1450 + -1, &bp, args->whichfork);
1390 1451 if (error)
1391 1452 return(error);
1392 1453 ASSERT(bp != NULL);
... ... @@ -1470,8 +1531,8 @@
1470 1531 * Read the next child block.
1471 1532 */
1472 1533 blk->blkno = blkno;
1473   - error = xfs_da_read_buf(args->trans, args->dp, blkno, -1,
1474   - &blk->bp, args->whichfork, NULL);
  1534 + error = xfs_da_node_read(args->trans, args->dp, blkno, -1,
  1535 + &blk->bp, args->whichfork);
1475 1536 if (error)
1476 1537 return(error);
1477 1538 ASSERT(blk->bp != NULL);
... ... @@ -1734,7 +1795,7 @@
1734 1795 * Read the last block in the btree space.
1735 1796 */
1736 1797 last_blkno = (xfs_dablk_t)lastoff - mp->m_dirblkfsbs;
1737   - error = xfs_da_read_buf(tp, ip, last_blkno, -1, &last_buf, w, NULL);
  1798 + error = xfs_da_node_read(tp, ip, last_blkno, -1, &last_buf, w);
1738 1799 if (error)
1739 1800 return error;
1740 1801 /*
... ... @@ -1761,8 +1822,7 @@
1761 1822 * If the moved block has a left sibling, fix up the pointers.
1762 1823 */
1763 1824 if ((sib_blkno = be32_to_cpu(dead_info->back))) {
1764   - error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w,
1765   - NULL);
  1825 + error = xfs_da_node_read(tp, ip, sib_blkno, -1, &sib_buf, w);
1766 1826 if (error)
1767 1827 goto done;
1768 1828 sib_info = sib_buf->b_addr;
... ... @@ -1784,8 +1844,7 @@
1784 1844 * If the moved block has a right sibling, fix up the pointers.
1785 1845 */
1786 1846 if ((sib_blkno = be32_to_cpu(dead_info->forw))) {
1787   - error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w,
1788   - NULL);
  1847 + error = xfs_da_node_read(tp, ip, sib_blkno, -1, &sib_buf, w);
1789 1848 if (error)
1790 1849 goto done;
1791 1850 sib_info = sib_buf->b_addr;
... ... @@ -1809,8 +1868,7 @@
1809 1868 * Walk down the tree looking for the parent of the moved block.
1810 1869 */
1811 1870 for (;;) {
1812   - error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w,
1813   - NULL);
  1871 + error = xfs_da_node_read(tp, ip, par_blkno, -1, &par_buf, w);
1814 1872 if (error)
1815 1873 goto done;
1816 1874 par_node = par_buf->b_addr;
... ... @@ -1861,8 +1919,7 @@
1861 1919 error = XFS_ERROR(EFSCORRUPTED);
1862 1920 goto done;
1863 1921 }
1864   - error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w,
1865   - NULL);
  1922 + error = xfs_da_node_read(tp, ip, par_blkno, -1, &par_buf, w);
1866 1923 if (error)
1867 1924 goto done;
1868 1925 par_node = par_buf->b_addr;
fs/xfs/xfs_da_btree.h
... ... @@ -213,6 +213,9 @@
213 213 */
214 214 int xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk,
215 215 xfs_da_state_blk_t *new_blk);
  216 +int xfs_da_node_read(struct xfs_trans *tp, struct xfs_inode *dp,
  217 + xfs_dablk_t bno, xfs_daddr_t mappedbno,
  218 + struct xfs_buf **bpp, int which_fork);
216 219  
217 220 /*
218 221 * Utility routines.
fs/xfs/xfs_dir2_leaf.c
... ... @@ -74,7 +74,7 @@
74 74 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAF1_MAGIC));
75 75 }
76 76  
77   -static void
  77 +void
78 78 xfs_dir2_leafn_verify(
79 79 struct xfs_buf *bp)
80 80 {
fs/xfs/xfs_dir2_priv.h
... ... @@ -70,6 +70,7 @@
70 70 xfs_dir2_data_aoff_t len, int *needlogp, int *needscanp);
71 71  
72 72 /* xfs_dir2_leaf.c */
  73 +extern void xfs_dir2_leafn_verify(struct xfs_buf *bp);
73 74 extern int xfs_dir2_leafn_read(struct xfs_trans *tp, struct xfs_inode *dp,
74 75 xfs_dablk_t fbno, xfs_daddr_t mappedbno, struct xfs_buf **bpp);
75 76 extern int xfs_dir2_block_to_leaf(struct xfs_da_args *args,