diff options
author | Dave Chinner <dchinner@redhat.com> | 2012-11-12 06:54:17 -0500 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2012-11-15 22:34:55 -0500 |
commit | d9392a4bb75503fc2adbb5237c3df940c6467eb2 (patch) | |
tree | dd00bc09208541fcb35bc9e387be5bf294327c5e /fs/xfs/xfs_da_btree.c | |
parent | ad14c33ac862601c4c22755ed3b59f1906b134e5 (diff) |
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>
Diffstat (limited to 'fs/xfs/xfs_da_btree.c')
-rw-r--r-- | fs/xfs/xfs_da_btree.c | 109 |
1 files changed, 83 insertions, 26 deletions
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c index f9e9149de009..1b84fc50a053 100644 --- a/fs/xfs/xfs_da_btree.c +++ b/fs/xfs/xfs_da_btree.c | |||
@@ -91,6 +91,68 @@ STATIC int xfs_da_blk_unlink(xfs_da_state_t *state, | |||
91 | xfs_da_state_blk_t *save_blk); | 91 | xfs_da_state_blk_t *save_blk); |
92 | STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state); | 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 | * Routines used for growing the Btree. | 157 | * Routines used for growing the Btree. |
96 | *========================================================================*/ | 158 | *========================================================================*/ |
@@ -746,8 +808,8 @@ xfs_da_root_join(xfs_da_state_t *state, xfs_da_state_blk_t *root_blk) | |||
746 | */ | 808 | */ |
747 | child = be32_to_cpu(oldroot->btree[0].before); | 809 | child = be32_to_cpu(oldroot->btree[0].before); |
748 | ASSERT(child != 0); | 810 | ASSERT(child != 0); |
749 | error = xfs_da_read_buf(args->trans, args->dp, child, -1, &bp, | 811 | error = xfs_da_node_read(args->trans, args->dp, child, -1, &bp, |
750 | args->whichfork, NULL); | 812 | args->whichfork); |
751 | if (error) | 813 | if (error) |
752 | return(error); | 814 | return(error); |
753 | ASSERT(bp != NULL); | 815 | ASSERT(bp != NULL); |
@@ -837,9 +899,8 @@ xfs_da_node_toosmall(xfs_da_state_t *state, int *action) | |||
837 | blkno = be32_to_cpu(info->back); | 899 | blkno = be32_to_cpu(info->back); |
838 | if (blkno == 0) | 900 | if (blkno == 0) |
839 | continue; | 901 | continue; |
840 | error = xfs_da_read_buf(state->args->trans, state->args->dp, | 902 | error = xfs_da_node_read(state->args->trans, state->args->dp, |
841 | blkno, -1, &bp, state->args->whichfork, | 903 | blkno, -1, &bp, state->args->whichfork); |
842 | NULL); | ||
843 | if (error) | 904 | if (error) |
844 | return(error); | 905 | return(error); |
845 | ASSERT(bp != NULL); | 906 | ASSERT(bp != NULL); |
@@ -1084,8 +1145,8 @@ xfs_da_node_lookup_int(xfs_da_state_t *state, int *result) | |||
1084 | * Read the next node down in the tree. | 1145 | * Read the next node down in the tree. |
1085 | */ | 1146 | */ |
1086 | blk->blkno = blkno; | 1147 | blk->blkno = blkno; |
1087 | error = xfs_da_read_buf(args->trans, args->dp, blkno, | 1148 | error = xfs_da_node_read(args->trans, args->dp, blkno, |
1088 | -1, &blk->bp, args->whichfork, NULL); | 1149 | -1, &blk->bp, args->whichfork); |
1089 | if (error) { | 1150 | if (error) { |
1090 | blk->blkno = 0; | 1151 | blk->blkno = 0; |
1091 | state->path.active--; | 1152 | state->path.active--; |
@@ -1246,9 +1307,9 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, | |||
1246 | new_info->forw = cpu_to_be32(old_blk->blkno); | 1307 | new_info->forw = cpu_to_be32(old_blk->blkno); |
1247 | new_info->back = old_info->back; | 1308 | new_info->back = old_info->back; |
1248 | if (old_info->back) { | 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 | be32_to_cpu(old_info->back), | 1311 | be32_to_cpu(old_info->back), |
1251 | -1, &bp, args->whichfork, NULL); | 1312 | -1, &bp, args->whichfork); |
1252 | if (error) | 1313 | if (error) |
1253 | return(error); | 1314 | return(error); |
1254 | ASSERT(bp != NULL); | 1315 | ASSERT(bp != NULL); |
@@ -1267,9 +1328,9 @@ xfs_da_blk_link(xfs_da_state_t *state, xfs_da_state_blk_t *old_blk, | |||
1267 | new_info->forw = old_info->forw; | 1328 | new_info->forw = old_info->forw; |
1268 | new_info->back = cpu_to_be32(old_blk->blkno); | 1329 | new_info->back = cpu_to_be32(old_blk->blkno); |
1269 | if (old_info->forw) { | 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 | be32_to_cpu(old_info->forw), | 1332 | be32_to_cpu(old_info->forw), |
1272 | -1, &bp, args->whichfork, NULL); | 1333 | -1, &bp, args->whichfork); |
1273 | if (error) | 1334 | if (error) |
1274 | return(error); | 1335 | return(error); |
1275 | ASSERT(bp != NULL); | 1336 | ASSERT(bp != NULL); |
@@ -1367,9 +1428,9 @@ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | |||
1367 | trace_xfs_da_unlink_back(args); | 1428 | trace_xfs_da_unlink_back(args); |
1368 | save_info->back = drop_info->back; | 1429 | save_info->back = drop_info->back; |
1369 | if (drop_info->back) { | 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 | be32_to_cpu(drop_info->back), | 1432 | be32_to_cpu(drop_info->back), |
1372 | -1, &bp, args->whichfork, NULL); | 1433 | -1, &bp, args->whichfork); |
1373 | if (error) | 1434 | if (error) |
1374 | return(error); | 1435 | return(error); |
1375 | ASSERT(bp != NULL); | 1436 | ASSERT(bp != NULL); |
@@ -1384,9 +1445,9 @@ xfs_da_blk_unlink(xfs_da_state_t *state, xfs_da_state_blk_t *drop_blk, | |||
1384 | trace_xfs_da_unlink_forward(args); | 1445 | trace_xfs_da_unlink_forward(args); |
1385 | save_info->forw = drop_info->forw; | 1446 | save_info->forw = drop_info->forw; |
1386 | if (drop_info->forw) { | 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 | be32_to_cpu(drop_info->forw), | 1449 | be32_to_cpu(drop_info->forw), |
1389 | -1, &bp, args->whichfork, NULL); | 1450 | -1, &bp, args->whichfork); |
1390 | if (error) | 1451 | if (error) |
1391 | return(error); | 1452 | return(error); |
1392 | ASSERT(bp != NULL); | 1453 | ASSERT(bp != NULL); |
@@ -1470,8 +1531,8 @@ xfs_da_path_shift(xfs_da_state_t *state, xfs_da_state_path_t *path, | |||
1470 | * Read the next child block. | 1531 | * Read the next child block. |
1471 | */ | 1532 | */ |
1472 | blk->blkno = blkno; | 1533 | blk->blkno = blkno; |
1473 | error = xfs_da_read_buf(args->trans, args->dp, blkno, -1, | 1534 | error = xfs_da_node_read(args->trans, args->dp, blkno, -1, |
1474 | &blk->bp, args->whichfork, NULL); | 1535 | &blk->bp, args->whichfork); |
1475 | if (error) | 1536 | if (error) |
1476 | return(error); | 1537 | return(error); |
1477 | ASSERT(blk->bp != NULL); | 1538 | ASSERT(blk->bp != NULL); |
@@ -1734,7 +1795,7 @@ xfs_da_swap_lastblock( | |||
1734 | * Read the last block in the btree space. | 1795 | * Read the last block in the btree space. |
1735 | */ | 1796 | */ |
1736 | last_blkno = (xfs_dablk_t)lastoff - mp->m_dirblkfsbs; | 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 | if (error) | 1799 | if (error) |
1739 | return error; | 1800 | return error; |
1740 | /* | 1801 | /* |
@@ -1761,8 +1822,7 @@ xfs_da_swap_lastblock( | |||
1761 | * If the moved block has a left sibling, fix up the pointers. | 1822 | * If the moved block has a left sibling, fix up the pointers. |
1762 | */ | 1823 | */ |
1763 | if ((sib_blkno = be32_to_cpu(dead_info->back))) { | 1824 | if ((sib_blkno = be32_to_cpu(dead_info->back))) { |
1764 | error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w, | 1825 | error = xfs_da_node_read(tp, ip, sib_blkno, -1, &sib_buf, w); |
1765 | NULL); | ||
1766 | if (error) | 1826 | if (error) |
1767 | goto done; | 1827 | goto done; |
1768 | sib_info = sib_buf->b_addr; | 1828 | sib_info = sib_buf->b_addr; |
@@ -1784,8 +1844,7 @@ xfs_da_swap_lastblock( | |||
1784 | * If the moved block has a right sibling, fix up the pointers. | 1844 | * If the moved block has a right sibling, fix up the pointers. |
1785 | */ | 1845 | */ |
1786 | if ((sib_blkno = be32_to_cpu(dead_info->forw))) { | 1846 | if ((sib_blkno = be32_to_cpu(dead_info->forw))) { |
1787 | error = xfs_da_read_buf(tp, ip, sib_blkno, -1, &sib_buf, w, | 1847 | error = xfs_da_node_read(tp, ip, sib_blkno, -1, &sib_buf, w); |
1788 | NULL); | ||
1789 | if (error) | 1848 | if (error) |
1790 | goto done; | 1849 | goto done; |
1791 | sib_info = sib_buf->b_addr; | 1850 | sib_info = sib_buf->b_addr; |
@@ -1809,8 +1868,7 @@ xfs_da_swap_lastblock( | |||
1809 | * Walk down the tree looking for the parent of the moved block. | 1868 | * Walk down the tree looking for the parent of the moved block. |
1810 | */ | 1869 | */ |
1811 | for (;;) { | 1870 | for (;;) { |
1812 | error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w, | 1871 | error = xfs_da_node_read(tp, ip, par_blkno, -1, &par_buf, w); |
1813 | NULL); | ||
1814 | if (error) | 1872 | if (error) |
1815 | goto done; | 1873 | goto done; |
1816 | par_node = par_buf->b_addr; | 1874 | par_node = par_buf->b_addr; |
@@ -1861,8 +1919,7 @@ xfs_da_swap_lastblock( | |||
1861 | error = XFS_ERROR(EFSCORRUPTED); | 1919 | error = XFS_ERROR(EFSCORRUPTED); |
1862 | goto done; | 1920 | goto done; |
1863 | } | 1921 | } |
1864 | error = xfs_da_read_buf(tp, ip, par_blkno, -1, &par_buf, w, | 1922 | error = xfs_da_node_read(tp, ip, par_blkno, -1, &par_buf, w); |
1865 | NULL); | ||
1866 | if (error) | 1923 | if (error) |
1867 | goto done; | 1924 | goto done; |
1868 | par_node = par_buf->b_addr; | 1925 | par_node = par_buf->b_addr; |