Commit d9392a4bb75503fc2adbb5237c3df940c6467eb2
Committed by
Ben Myers
1 parent
ad14c33ac8
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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
fs/xfs/xfs_attr.c
... | ... | @@ -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
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, |