aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_da_btree.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2012-11-12 06:54:17 -0500
committerBen Myers <bpm@sgi.com>2012-11-15 22:34:55 -0500
commitd9392a4bb75503fc2adbb5237c3df940c6467eb2 (patch)
treedd00bc09208541fcb35bc9e387be5bf294327c5e /fs/xfs/xfs_da_btree.c
parentad14c33ac862601c4c22755ed3b59f1906b134e5 (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.c109
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);
92STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state); 92STATIC void xfs_da_state_kill_altpath(xfs_da_state_t *state);
93 93
94static 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
115static void
116xfs_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
143int
144xfs_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;