diff options
author | Dave Chinner <dchinner@redhat.com> | 2013-04-03 01:11:22 -0400 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2013-04-27 13:00:00 -0400 |
commit | 33363feed1614def83d0a6870051f0a7828cd61b (patch) | |
tree | 87fc721e32537e981264a1662de2c44d1d195607 /fs/xfs/xfs_dir2_leaf.c | |
parent | cbc8adf89724b961c08b823d8bfb6dadbfa8733d (diff) |
xfs: add CRC checking to dir2 data blocks
This addition follows the same pattern as the dir2 block CRCs.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Ben Myers <bpm@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_dir2_leaf.c')
-rw-r--r-- | fs/xfs/xfs_dir2_leaf.c | 71 |
1 files changed, 41 insertions, 30 deletions
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 979735b0c76d..c7dca950f768 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c | |||
@@ -149,7 +149,7 @@ xfs_dir2_block_to_leaf( | |||
149 | int needlog; /* need to log block header */ | 149 | int needlog; /* need to log block header */ |
150 | int needscan; /* need to rescan bestfree */ | 150 | int needscan; /* need to rescan bestfree */ |
151 | xfs_trans_t *tp; /* transaction pointer */ | 151 | xfs_trans_t *tp; /* transaction pointer */ |
152 | struct xfs_dir2_data_free *bf; | 152 | struct xfs_dir2_data_free *bf; |
153 | 153 | ||
154 | trace_xfs_dir2_block_to_leaf(args); | 154 | trace_xfs_dir2_block_to_leaf(args); |
155 | 155 | ||
@@ -175,7 +175,7 @@ xfs_dir2_block_to_leaf( | |||
175 | ASSERT(lbp != NULL); | 175 | ASSERT(lbp != NULL); |
176 | leaf = lbp->b_addr; | 176 | leaf = lbp->b_addr; |
177 | hdr = dbp->b_addr; | 177 | hdr = dbp->b_addr; |
178 | xfs_dir2_data_check(dp, dbp); | 178 | xfs_dir3_data_check(dp, dbp); |
179 | btp = xfs_dir2_block_tail_p(mp, hdr); | 179 | btp = xfs_dir2_block_tail_p(mp, hdr); |
180 | blp = xfs_dir2_block_leaf_p(btp); | 180 | blp = xfs_dir2_block_leaf_p(btp); |
181 | bf = xfs_dir3_data_bestfree_p(hdr); | 181 | bf = xfs_dir3_data_bestfree_p(hdr); |
@@ -204,8 +204,12 @@ xfs_dir2_block_to_leaf( | |||
204 | /* | 204 | /* |
205 | * Fix up the block header, make it a data block. | 205 | * Fix up the block header, make it a data block. |
206 | */ | 206 | */ |
207 | dbp->b_ops = &xfs_dir2_data_buf_ops; | 207 | dbp->b_ops = &xfs_dir3_data_buf_ops; |
208 | hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); | 208 | if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) |
209 | hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); | ||
210 | else | ||
211 | hdr->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC); | ||
212 | |||
209 | if (needscan) | 213 | if (needscan) |
210 | xfs_dir2_data_freescan(mp, hdr, &needlog); | 214 | xfs_dir2_data_freescan(mp, hdr, &needlog); |
211 | /* | 215 | /* |
@@ -221,7 +225,7 @@ xfs_dir2_block_to_leaf( | |||
221 | if (needlog) | 225 | if (needlog) |
222 | xfs_dir2_data_log_header(tp, dbp); | 226 | xfs_dir2_data_log_header(tp, dbp); |
223 | xfs_dir2_leaf_check(dp, lbp); | 227 | xfs_dir2_leaf_check(dp, lbp); |
224 | xfs_dir2_data_check(dp, dbp); | 228 | xfs_dir3_data_check(dp, dbp); |
225 | xfs_dir2_leaf_log_bests(tp, lbp, 0, 0); | 229 | xfs_dir2_leaf_log_bests(tp, lbp, 0, 0); |
226 | return 0; | 230 | return 0; |
227 | } | 231 | } |
@@ -385,6 +389,7 @@ xfs_dir2_leaf_addname( | |||
385 | __be16 *tagp; /* end of data entry */ | 389 | __be16 *tagp; /* end of data entry */ |
386 | xfs_trans_t *tp; /* transaction pointer */ | 390 | xfs_trans_t *tp; /* transaction pointer */ |
387 | xfs_dir2_db_t use_block; /* data block number */ | 391 | xfs_dir2_db_t use_block; /* data block number */ |
392 | struct xfs_dir2_data_free *bf; /* bestfree table */ | ||
388 | 393 | ||
389 | trace_xfs_dir2_leaf_addname(args); | 394 | trace_xfs_dir2_leaf_addname(args); |
390 | 395 | ||
@@ -568,14 +573,15 @@ xfs_dir2_leaf_addname( | |||
568 | else | 573 | else |
569 | xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); | 574 | xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); |
570 | hdr = dbp->b_addr; | 575 | hdr = dbp->b_addr; |
571 | bestsp[use_block] = hdr->bestfree[0].length; | 576 | bf = xfs_dir3_data_bestfree_p(hdr); |
577 | bestsp[use_block] = bf[0].length; | ||
572 | grown = 1; | 578 | grown = 1; |
573 | } else { | 579 | } else { |
574 | /* | 580 | /* |
575 | * Already had space in some data block. | 581 | * Already had space in some data block. |
576 | * Just read that one in. | 582 | * Just read that one in. |
577 | */ | 583 | */ |
578 | error = xfs_dir2_data_read(tp, dp, | 584 | error = xfs_dir3_data_read(tp, dp, |
579 | xfs_dir2_db_to_da(mp, use_block), | 585 | xfs_dir2_db_to_da(mp, use_block), |
580 | -1, &dbp); | 586 | -1, &dbp); |
581 | if (error) { | 587 | if (error) { |
@@ -583,13 +589,14 @@ xfs_dir2_leaf_addname( | |||
583 | return error; | 589 | return error; |
584 | } | 590 | } |
585 | hdr = dbp->b_addr; | 591 | hdr = dbp->b_addr; |
592 | bf = xfs_dir3_data_bestfree_p(hdr); | ||
586 | grown = 0; | 593 | grown = 0; |
587 | } | 594 | } |
588 | /* | 595 | /* |
589 | * Point to the biggest freespace in our data block. | 596 | * Point to the biggest freespace in our data block. |
590 | */ | 597 | */ |
591 | dup = (xfs_dir2_data_unused_t *) | 598 | dup = (xfs_dir2_data_unused_t *) |
592 | ((char *)hdr + be16_to_cpu(hdr->bestfree[0].offset)); | 599 | ((char *)hdr + be16_to_cpu(bf[0].offset)); |
593 | ASSERT(be16_to_cpu(dup->length) >= length); | 600 | ASSERT(be16_to_cpu(dup->length) >= length); |
594 | needscan = needlog = 0; | 601 | needscan = needlog = 0; |
595 | /* | 602 | /* |
@@ -622,8 +629,8 @@ xfs_dir2_leaf_addname( | |||
622 | * If the bests table needs to be changed, do it. | 629 | * If the bests table needs to be changed, do it. |
623 | * Log the change unless we've already done that. | 630 | * Log the change unless we've already done that. |
624 | */ | 631 | */ |
625 | if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(hdr->bestfree[0].length)) { | 632 | if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(bf[0].length)) { |
626 | bestsp[use_block] = hdr->bestfree[0].length; | 633 | bestsp[use_block] = bf[0].length; |
627 | if (!grown) | 634 | if (!grown) |
628 | xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); | 635 | xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); |
629 | } | 636 | } |
@@ -643,7 +650,7 @@ xfs_dir2_leaf_addname( | |||
643 | xfs_dir2_leaf_log_header(tp, lbp); | 650 | xfs_dir2_leaf_log_header(tp, lbp); |
644 | xfs_dir2_leaf_log_ents(tp, lbp, lfloglow, lfloghigh); | 651 | xfs_dir2_leaf_log_ents(tp, lbp, lfloglow, lfloghigh); |
645 | xfs_dir2_leaf_check(dp, lbp); | 652 | xfs_dir2_leaf_check(dp, lbp); |
646 | xfs_dir2_data_check(dp, dbp); | 653 | xfs_dir3_data_check(dp, dbp); |
647 | return 0; | 654 | return 0; |
648 | } | 655 | } |
649 | 656 | ||
@@ -967,7 +974,7 @@ xfs_dir2_leaf_readbuf( | |||
967 | * Read the directory block starting at the first mapping. | 974 | * Read the directory block starting at the first mapping. |
968 | */ | 975 | */ |
969 | mip->curdb = xfs_dir2_da_to_db(mp, map->br_startoff); | 976 | mip->curdb = xfs_dir2_da_to_db(mp, map->br_startoff); |
970 | error = xfs_dir2_data_read(NULL, dp, map->br_startoff, | 977 | error = xfs_dir3_data_read(NULL, dp, map->br_startoff, |
971 | map->br_blockcount >= mp->m_dirblkfsbs ? | 978 | map->br_blockcount >= mp->m_dirblkfsbs ? |
972 | XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, &bp); | 979 | XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, &bp); |
973 | 980 | ||
@@ -996,7 +1003,7 @@ xfs_dir2_leaf_readbuf( | |||
996 | */ | 1003 | */ |
997 | if (i > mip->ra_current && | 1004 | if (i > mip->ra_current && |
998 | map[mip->ra_index].br_blockcount >= mp->m_dirblkfsbs) { | 1005 | map[mip->ra_index].br_blockcount >= mp->m_dirblkfsbs) { |
999 | xfs_dir2_data_readahead(NULL, dp, | 1006 | xfs_dir3_data_readahead(NULL, dp, |
1000 | map[mip->ra_index].br_startoff + mip->ra_offset, | 1007 | map[mip->ra_index].br_startoff + mip->ra_offset, |
1001 | XFS_FSB_TO_DADDR(mp, | 1008 | XFS_FSB_TO_DADDR(mp, |
1002 | map[mip->ra_index].br_startblock + | 1009 | map[mip->ra_index].br_startblock + |
@@ -1009,7 +1016,7 @@ xfs_dir2_leaf_readbuf( | |||
1009 | * use our mapping, but this is a very rare case. | 1016 | * use our mapping, but this is a very rare case. |
1010 | */ | 1017 | */ |
1011 | else if (i > mip->ra_current) { | 1018 | else if (i > mip->ra_current) { |
1012 | xfs_dir2_data_readahead(NULL, dp, | 1019 | xfs_dir3_data_readahead(NULL, dp, |
1013 | map[mip->ra_index].br_startoff + | 1020 | map[mip->ra_index].br_startoff + |
1014 | mip->ra_offset, -1); | 1021 | mip->ra_offset, -1); |
1015 | mip->ra_current = i; | 1022 | mip->ra_current = i; |
@@ -1135,17 +1142,17 @@ xfs_dir2_leaf_getdents( | |||
1135 | ASSERT(xfs_dir2_byte_to_db(mp, curoff) == | 1142 | ASSERT(xfs_dir2_byte_to_db(mp, curoff) == |
1136 | map_info->curdb); | 1143 | map_info->curdb); |
1137 | hdr = bp->b_addr; | 1144 | hdr = bp->b_addr; |
1138 | xfs_dir2_data_check(dp, bp); | 1145 | xfs_dir3_data_check(dp, bp); |
1139 | /* | 1146 | /* |
1140 | * Find our position in the block. | 1147 | * Find our position in the block. |
1141 | */ | 1148 | */ |
1142 | ptr = (char *)(hdr + 1); | 1149 | ptr = (char *)xfs_dir3_data_entry_p(hdr); |
1143 | byteoff = xfs_dir2_byte_to_off(mp, curoff); | 1150 | byteoff = xfs_dir2_byte_to_off(mp, curoff); |
1144 | /* | 1151 | /* |
1145 | * Skip past the header. | 1152 | * Skip past the header. |
1146 | */ | 1153 | */ |
1147 | if (byteoff == 0) | 1154 | if (byteoff == 0) |
1148 | curoff += (uint)sizeof(*hdr); | 1155 | curoff += xfs_dir3_data_entry_offset(hdr); |
1149 | /* | 1156 | /* |
1150 | * Skip past entries until we reach our offset. | 1157 | * Skip past entries until we reach our offset. |
1151 | */ | 1158 | */ |
@@ -1481,7 +1488,7 @@ xfs_dir2_leaf_lookup_int( | |||
1481 | if (newdb != curdb) { | 1488 | if (newdb != curdb) { |
1482 | if (dbp) | 1489 | if (dbp) |
1483 | xfs_trans_brelse(tp, dbp); | 1490 | xfs_trans_brelse(tp, dbp); |
1484 | error = xfs_dir2_data_read(tp, dp, | 1491 | error = xfs_dir3_data_read(tp, dp, |
1485 | xfs_dir2_db_to_da(mp, newdb), | 1492 | xfs_dir2_db_to_da(mp, newdb), |
1486 | -1, &dbp); | 1493 | -1, &dbp); |
1487 | if (error) { | 1494 | if (error) { |
@@ -1522,7 +1529,7 @@ xfs_dir2_leaf_lookup_int( | |||
1522 | ASSERT(cidb != -1); | 1529 | ASSERT(cidb != -1); |
1523 | if (cidb != curdb) { | 1530 | if (cidb != curdb) { |
1524 | xfs_trans_brelse(tp, dbp); | 1531 | xfs_trans_brelse(tp, dbp); |
1525 | error = xfs_dir2_data_read(tp, dp, | 1532 | error = xfs_dir3_data_read(tp, dp, |
1526 | xfs_dir2_db_to_da(mp, cidb), | 1533 | xfs_dir2_db_to_da(mp, cidb), |
1527 | -1, &dbp); | 1534 | -1, &dbp); |
1528 | if (error) { | 1535 | if (error) { |
@@ -1568,6 +1575,7 @@ xfs_dir2_leaf_removename( | |||
1568 | int needscan; /* need to rescan data frees */ | 1575 | int needscan; /* need to rescan data frees */ |
1569 | xfs_dir2_data_off_t oldbest; /* old value of best free */ | 1576 | xfs_dir2_data_off_t oldbest; /* old value of best free */ |
1570 | xfs_trans_t *tp; /* transaction pointer */ | 1577 | xfs_trans_t *tp; /* transaction pointer */ |
1578 | struct xfs_dir2_data_free *bf; /* bestfree table */ | ||
1571 | 1579 | ||
1572 | trace_xfs_dir2_leaf_removename(args); | 1580 | trace_xfs_dir2_leaf_removename(args); |
1573 | 1581 | ||
@@ -1582,7 +1590,8 @@ xfs_dir2_leaf_removename( | |||
1582 | mp = dp->i_mount; | 1590 | mp = dp->i_mount; |
1583 | leaf = lbp->b_addr; | 1591 | leaf = lbp->b_addr; |
1584 | hdr = dbp->b_addr; | 1592 | hdr = dbp->b_addr; |
1585 | xfs_dir2_data_check(dp, dbp); | 1593 | bf = xfs_dir3_data_bestfree_p(hdr); |
1594 | xfs_dir3_data_check(dp, dbp); | ||
1586 | /* | 1595 | /* |
1587 | * Point to the leaf entry, use that to point to the data entry. | 1596 | * Point to the leaf entry, use that to point to the data entry. |
1588 | */ | 1597 | */ |
@@ -1591,7 +1600,7 @@ xfs_dir2_leaf_removename( | |||
1591 | dep = (xfs_dir2_data_entry_t *) | 1600 | dep = (xfs_dir2_data_entry_t *) |
1592 | ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); | 1601 | ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); |
1593 | needscan = needlog = 0; | 1602 | needscan = needlog = 0; |
1594 | oldbest = be16_to_cpu(hdr->bestfree[0].length); | 1603 | oldbest = be16_to_cpu(bf[0].length); |
1595 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); | 1604 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
1596 | bestsp = xfs_dir2_leaf_bests_p(ltp); | 1605 | bestsp = xfs_dir2_leaf_bests_p(ltp); |
1597 | ASSERT(be16_to_cpu(bestsp[db]) == oldbest); | 1606 | ASSERT(be16_to_cpu(bestsp[db]) == oldbest); |
@@ -1620,16 +1629,16 @@ xfs_dir2_leaf_removename( | |||
1620 | * If the longest freespace in the data block has changed, | 1629 | * If the longest freespace in the data block has changed, |
1621 | * put the new value in the bests table and log that. | 1630 | * put the new value in the bests table and log that. |
1622 | */ | 1631 | */ |
1623 | if (be16_to_cpu(hdr->bestfree[0].length) != oldbest) { | 1632 | if (be16_to_cpu(bf[0].length) != oldbest) { |
1624 | bestsp[db] = hdr->bestfree[0].length; | 1633 | bestsp[db] = bf[0].length; |
1625 | xfs_dir2_leaf_log_bests(tp, lbp, db, db); | 1634 | xfs_dir2_leaf_log_bests(tp, lbp, db, db); |
1626 | } | 1635 | } |
1627 | xfs_dir2_data_check(dp, dbp); | 1636 | xfs_dir3_data_check(dp, dbp); |
1628 | /* | 1637 | /* |
1629 | * If the data block is now empty then get rid of the data block. | 1638 | * If the data block is now empty then get rid of the data block. |
1630 | */ | 1639 | */ |
1631 | if (be16_to_cpu(hdr->bestfree[0].length) == | 1640 | if (be16_to_cpu(bf[0].length) == |
1632 | mp->m_dirblksize - (uint)sizeof(*hdr)) { | 1641 | mp->m_dirblksize - xfs_dir3_data_entry_offset(hdr)) { |
1633 | ASSERT(db != mp->m_dirdatablk); | 1642 | ASSERT(db != mp->m_dirdatablk); |
1634 | if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { | 1643 | if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { |
1635 | /* | 1644 | /* |
@@ -1809,7 +1818,7 @@ xfs_dir2_leaf_trim_data( | |||
1809 | /* | 1818 | /* |
1810 | * Read the offending data block. We need its buffer. | 1819 | * Read the offending data block. We need its buffer. |
1811 | */ | 1820 | */ |
1812 | error = xfs_dir2_data_read(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp); | 1821 | error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp); |
1813 | if (error) | 1822 | if (error) |
1814 | return error; | 1823 | return error; |
1815 | 1824 | ||
@@ -1819,10 +1828,12 @@ xfs_dir2_leaf_trim_data( | |||
1819 | #ifdef DEBUG | 1828 | #ifdef DEBUG |
1820 | { | 1829 | { |
1821 | struct xfs_dir2_data_hdr *hdr = dbp->b_addr; | 1830 | struct xfs_dir2_data_hdr *hdr = dbp->b_addr; |
1831 | struct xfs_dir2_data_free *bf = xfs_dir3_data_bestfree_p(hdr); | ||
1822 | 1832 | ||
1823 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC)); | 1833 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || |
1824 | ASSERT(be16_to_cpu(hdr->bestfree[0].length) == | 1834 | hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)); |
1825 | mp->m_dirblksize - (uint)sizeof(*hdr)); | 1835 | ASSERT(be16_to_cpu(bf[0].length) == |
1836 | mp->m_dirblksize - xfs_dir3_data_entry_offset(hdr)); | ||
1826 | ASSERT(db == be32_to_cpu(ltp->bestcount) - 1); | 1837 | ASSERT(db == be32_to_cpu(ltp->bestcount) - 1); |
1827 | } | 1838 | } |
1828 | #endif | 1839 | #endif |