aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2_leaf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_dir2_leaf.c')
-rw-r--r--fs/xfs/xfs_dir2_leaf.c172
1 files changed, 121 insertions, 51 deletions
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 0b296253bd01..60cd2fa4e047 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -48,6 +48,83 @@ static void xfs_dir2_leaf_log_bests(struct xfs_trans *tp, struct xfs_buf *bp,
48 int first, int last); 48 int first, int last);
49static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_buf *bp); 49static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_buf *bp);
50 50
51static void
52xfs_dir2_leaf_verify(
53 struct xfs_buf *bp,
54 __be16 magic)
55{
56 struct xfs_mount *mp = bp->b_target->bt_mount;
57 struct xfs_dir2_leaf_hdr *hdr = bp->b_addr;
58 int block_ok = 0;
59
60 block_ok = hdr->info.magic == magic;
61 if (!block_ok) {
62 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr);
63 xfs_buf_ioerror(bp, EFSCORRUPTED);
64 }
65}
66
67static void
68xfs_dir2_leaf1_read_verify(
69 struct xfs_buf *bp)
70{
71 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAF1_MAGIC));
72}
73
74static void
75xfs_dir2_leaf1_write_verify(
76 struct xfs_buf *bp)
77{
78 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAF1_MAGIC));
79}
80
81void
82xfs_dir2_leafn_read_verify(
83 struct xfs_buf *bp)
84{
85 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
86}
87
88void
89xfs_dir2_leafn_write_verify(
90 struct xfs_buf *bp)
91{
92 xfs_dir2_leaf_verify(bp, cpu_to_be16(XFS_DIR2_LEAFN_MAGIC));
93}
94
95static const struct xfs_buf_ops xfs_dir2_leaf1_buf_ops = {
96 .verify_read = xfs_dir2_leaf1_read_verify,
97 .verify_write = xfs_dir2_leaf1_write_verify,
98};
99
100const struct xfs_buf_ops xfs_dir2_leafn_buf_ops = {
101 .verify_read = xfs_dir2_leafn_read_verify,
102 .verify_write = xfs_dir2_leafn_write_verify,
103};
104
105static int
106xfs_dir2_leaf_read(
107 struct xfs_trans *tp,
108 struct xfs_inode *dp,
109 xfs_dablk_t fbno,
110 xfs_daddr_t mappedbno,
111 struct xfs_buf **bpp)
112{
113 return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
114 XFS_DATA_FORK, &xfs_dir2_leaf1_buf_ops);
115}
116
117int
118xfs_dir2_leafn_read(
119 struct xfs_trans *tp,
120 struct xfs_inode *dp,
121 xfs_dablk_t fbno,
122 xfs_daddr_t mappedbno,
123 struct xfs_buf **bpp)
124{
125 return xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
126 XFS_DATA_FORK, &xfs_dir2_leafn_buf_ops);
127}
51 128
52/* 129/*
53 * Convert a block form directory to a leaf form directory. 130 * Convert a block form directory to a leaf form directory.
@@ -125,6 +202,7 @@ xfs_dir2_block_to_leaf(
125 /* 202 /*
126 * Fix up the block header, make it a data block. 203 * Fix up the block header, make it a data block.
127 */ 204 */
205 dbp->b_ops = &xfs_dir2_data_buf_ops;
128 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); 206 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
129 if (needscan) 207 if (needscan)
130 xfs_dir2_data_freescan(mp, hdr, &needlog); 208 xfs_dir2_data_freescan(mp, hdr, &needlog);
@@ -311,15 +389,11 @@ xfs_dir2_leaf_addname(
311 dp = args->dp; 389 dp = args->dp;
312 tp = args->trans; 390 tp = args->trans;
313 mp = dp->i_mount; 391 mp = dp->i_mount;
314 /* 392
315 * Read the leaf block. 393 error = xfs_dir2_leaf_read(tp, dp, mp->m_dirleafblk, -1, &lbp);
316 */ 394 if (error)
317 error = xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp,
318 XFS_DATA_FORK);
319 if (error) {
320 return error; 395 return error;
321 } 396
322 ASSERT(lbp != NULL);
323 /* 397 /*
324 * Look up the entry by hash value and name. 398 * Look up the entry by hash value and name.
325 * We know it's not there, our caller has already done a lookup. 399 * We know it's not there, our caller has already done a lookup.
@@ -494,22 +568,21 @@ xfs_dir2_leaf_addname(
494 hdr = dbp->b_addr; 568 hdr = dbp->b_addr;
495 bestsp[use_block] = hdr->bestfree[0].length; 569 bestsp[use_block] = hdr->bestfree[0].length;
496 grown = 1; 570 grown = 1;
497 } 571 } else {
498 /* 572 /*
499 * Already had space in some data block. 573 * Already had space in some data block.
500 * Just read that one in. 574 * Just read that one in.
501 */ 575 */
502 else { 576 error = xfs_dir2_data_read(tp, dp,
503 if ((error = 577 xfs_dir2_db_to_da(mp, use_block),
504 xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, use_block), 578 -1, &dbp);
505 -1, &dbp, XFS_DATA_FORK))) { 579 if (error) {
506 xfs_trans_brelse(tp, lbp); 580 xfs_trans_brelse(tp, lbp);
507 return error; 581 return error;
508 } 582 }
509 hdr = dbp->b_addr; 583 hdr = dbp->b_addr;
510 grown = 0; 584 grown = 0;
511 } 585 }
512 xfs_dir2_data_check(dp, dbp);
513 /* 586 /*
514 * Point to the biggest freespace in our data block. 587 * Point to the biggest freespace in our data block.
515 */ 588 */
@@ -892,10 +965,9 @@ xfs_dir2_leaf_readbuf(
892 * Read the directory block starting at the first mapping. 965 * Read the directory block starting at the first mapping.
893 */ 966 */
894 mip->curdb = xfs_dir2_da_to_db(mp, map->br_startoff); 967 mip->curdb = xfs_dir2_da_to_db(mp, map->br_startoff);
895 error = xfs_da_read_buf(NULL, dp, map->br_startoff, 968 error = xfs_dir2_data_read(NULL, dp, map->br_startoff,
896 map->br_blockcount >= mp->m_dirblkfsbs ? 969 map->br_blockcount >= mp->m_dirblkfsbs ?
897 XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, 970 XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, &bp);
898 &bp, XFS_DATA_FORK);
899 971
900 /* 972 /*
901 * Should just skip over the data block instead of giving up. 973 * Should just skip over the data block instead of giving up.
@@ -922,11 +994,11 @@ xfs_dir2_leaf_readbuf(
922 */ 994 */
923 if (i > mip->ra_current && 995 if (i > mip->ra_current &&
924 map[mip->ra_index].br_blockcount >= mp->m_dirblkfsbs) { 996 map[mip->ra_index].br_blockcount >= mp->m_dirblkfsbs) {
925 xfs_buf_readahead(mp->m_ddev_targp, 997 xfs_dir2_data_readahead(NULL, dp,
998 map[mip->ra_index].br_startoff + mip->ra_offset,
926 XFS_FSB_TO_DADDR(mp, 999 XFS_FSB_TO_DADDR(mp,
927 map[mip->ra_index].br_startblock + 1000 map[mip->ra_index].br_startblock +
928 mip->ra_offset), 1001 mip->ra_offset));
929 (int)BTOBB(mp->m_dirblksize));
930 mip->ra_current = i; 1002 mip->ra_current = i;
931 } 1003 }
932 1004
@@ -935,10 +1007,9 @@ xfs_dir2_leaf_readbuf(
935 * use our mapping, but this is a very rare case. 1007 * use our mapping, but this is a very rare case.
936 */ 1008 */
937 else if (i > mip->ra_current) { 1009 else if (i > mip->ra_current) {
938 xfs_da_reada_buf(NULL, dp, 1010 xfs_dir2_data_readahead(NULL, dp,
939 map[mip->ra_index].br_startoff + 1011 map[mip->ra_index].br_startoff +
940 mip->ra_offset, 1012 mip->ra_offset, -1);
941 XFS_DATA_FORK);
942 mip->ra_current = i; 1013 mip->ra_current = i;
943 } 1014 }
944 1015
@@ -1177,15 +1248,14 @@ xfs_dir2_leaf_init(
1177 * Get the buffer for the block. 1248 * Get the buffer for the block.
1178 */ 1249 */
1179 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, bno), -1, &bp, 1250 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(mp, bno), -1, &bp,
1180 XFS_DATA_FORK); 1251 XFS_DATA_FORK);
1181 if (error) { 1252 if (error)
1182 return error; 1253 return error;
1183 } 1254
1184 ASSERT(bp != NULL);
1185 leaf = bp->b_addr;
1186 /* 1255 /*
1187 * Initialize the header. 1256 * Initialize the header.
1188 */ 1257 */
1258 leaf = bp->b_addr;
1189 leaf->hdr.info.magic = cpu_to_be16(magic); 1259 leaf->hdr.info.magic = cpu_to_be16(magic);
1190 leaf->hdr.info.forw = 0; 1260 leaf->hdr.info.forw = 0;
1191 leaf->hdr.info.back = 0; 1261 leaf->hdr.info.back = 0;
@@ -1198,10 +1268,12 @@ xfs_dir2_leaf_init(
1198 * the block. 1268 * the block.
1199 */ 1269 */
1200 if (magic == XFS_DIR2_LEAF1_MAGIC) { 1270 if (magic == XFS_DIR2_LEAF1_MAGIC) {
1271 bp->b_ops = &xfs_dir2_leaf1_buf_ops;
1201 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 1272 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
1202 ltp->bestcount = 0; 1273 ltp->bestcount = 0;
1203 xfs_dir2_leaf_log_tail(tp, bp); 1274 xfs_dir2_leaf_log_tail(tp, bp);
1204 } 1275 } else
1276 bp->b_ops = &xfs_dir2_leafn_buf_ops;
1205 *bpp = bp; 1277 *bpp = bp;
1206 return 0; 1278 return 0;
1207} 1279}
@@ -1372,13 +1444,11 @@ xfs_dir2_leaf_lookup_int(
1372 dp = args->dp; 1444 dp = args->dp;
1373 tp = args->trans; 1445 tp = args->trans;
1374 mp = dp->i_mount; 1446 mp = dp->i_mount;
1375 /* 1447
1376 * Read the leaf block into the buffer. 1448 error = xfs_dir2_leaf_read(tp, dp, mp->m_dirleafblk, -1, &lbp);
1377 */
1378 error = xfs_da_read_buf(tp, dp, mp->m_dirleafblk, -1, &lbp,
1379 XFS_DATA_FORK);
1380 if (error) 1449 if (error)
1381 return error; 1450 return error;
1451
1382 *lbpp = lbp; 1452 *lbpp = lbp;
1383 leaf = lbp->b_addr; 1453 leaf = lbp->b_addr;
1384 xfs_dir2_leaf_check(dp, lbp); 1454 xfs_dir2_leaf_check(dp, lbp);
@@ -1409,14 +1479,13 @@ xfs_dir2_leaf_lookup_int(
1409 if (newdb != curdb) { 1479 if (newdb != curdb) {
1410 if (dbp) 1480 if (dbp)
1411 xfs_trans_brelse(tp, dbp); 1481 xfs_trans_brelse(tp, dbp);
1412 error = xfs_da_read_buf(tp, dp, 1482 error = xfs_dir2_data_read(tp, dp,
1413 xfs_dir2_db_to_da(mp, newdb), 1483 xfs_dir2_db_to_da(mp, newdb),
1414 -1, &dbp, XFS_DATA_FORK); 1484 -1, &dbp);
1415 if (error) { 1485 if (error) {
1416 xfs_trans_brelse(tp, lbp); 1486 xfs_trans_brelse(tp, lbp);
1417 return error; 1487 return error;
1418 } 1488 }
1419 xfs_dir2_data_check(dp, dbp);
1420 curdb = newdb; 1489 curdb = newdb;
1421 } 1490 }
1422 /* 1491 /*
@@ -1451,9 +1520,9 @@ xfs_dir2_leaf_lookup_int(
1451 ASSERT(cidb != -1); 1520 ASSERT(cidb != -1);
1452 if (cidb != curdb) { 1521 if (cidb != curdb) {
1453 xfs_trans_brelse(tp, dbp); 1522 xfs_trans_brelse(tp, dbp);
1454 error = xfs_da_read_buf(tp, dp, 1523 error = xfs_dir2_data_read(tp, dp,
1455 xfs_dir2_db_to_da(mp, cidb), 1524 xfs_dir2_db_to_da(mp, cidb),
1456 -1, &dbp, XFS_DATA_FORK); 1525 -1, &dbp);
1457 if (error) { 1526 if (error) {
1458 xfs_trans_brelse(tp, lbp); 1527 xfs_trans_brelse(tp, lbp);
1459 return error; 1528 return error;
@@ -1738,10 +1807,9 @@ xfs_dir2_leaf_trim_data(
1738 /* 1807 /*
1739 * Read the offending data block. We need its buffer. 1808 * Read the offending data block. We need its buffer.
1740 */ 1809 */
1741 if ((error = xfs_da_read_buf(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp, 1810 error = xfs_dir2_data_read(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp);
1742 XFS_DATA_FORK))) { 1811 if (error)
1743 return error; 1812 return error;
1744 }
1745 1813
1746 leaf = lbp->b_addr; 1814 leaf = lbp->b_addr;
1747 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 1815 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
@@ -1864,10 +1932,9 @@ xfs_dir2_node_to_leaf(
1864 /* 1932 /*
1865 * Read the freespace block. 1933 * Read the freespace block.
1866 */ 1934 */
1867 if ((error = xfs_da_read_buf(tp, dp, mp->m_dirfreeblk, -1, &fbp, 1935 error = xfs_dir2_free_read(tp, dp, mp->m_dirfreeblk, &fbp);
1868 XFS_DATA_FORK))) { 1936 if (error)
1869 return error; 1937 return error;
1870 }
1871 free = fbp->b_addr; 1938 free = fbp->b_addr;
1872 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC)); 1939 ASSERT(free->hdr.magic == cpu_to_be32(XFS_DIR2_FREE_MAGIC));
1873 ASSERT(!free->hdr.firstdb); 1940 ASSERT(!free->hdr.firstdb);
@@ -1890,7 +1957,10 @@ xfs_dir2_node_to_leaf(
1890 xfs_dir2_leaf_compact(args, lbp); 1957 xfs_dir2_leaf_compact(args, lbp);
1891 else 1958 else
1892 xfs_dir2_leaf_log_header(tp, lbp); 1959 xfs_dir2_leaf_log_header(tp, lbp);
1960
1961 lbp->b_ops = &xfs_dir2_leaf1_buf_ops;
1893 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAF1_MAGIC); 1962 leaf->hdr.info.magic = cpu_to_be16(XFS_DIR2_LEAF1_MAGIC);
1963
1894 /* 1964 /*
1895 * Set up the leaf tail from the freespace block. 1965 * Set up the leaf tail from the freespace block.
1896 */ 1966 */