aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2_leaf.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-04-03 01:11:22 -0400
committerBen Myers <bpm@sgi.com>2013-04-27 13:00:00 -0400
commit33363feed1614def83d0a6870051f0a7828cd61b (patch)
tree87fc721e32537e981264a1662de2c44d1d195607 /fs/xfs/xfs_dir2_leaf.c
parentcbc8adf89724b961c08b823d8bfb6dadbfa8733d (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.c71
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