diff options
author | Jiri Kosina <jkosina@suse.cz> | 2013-01-29 04:48:30 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-01-29 04:48:30 -0500 |
commit | 617677295b53a40d0e54aac4cbbc216ffbc755dd (patch) | |
tree | 51b9e87213243ed5efff252c8e8d8fec4eebc588 /fs/xfs/xfs_dir2_leaf.c | |
parent | 5c8d1b68e01a144813e38795fe6dbe7ebb506131 (diff) | |
parent | 6abb7c25775b7fb2225ad0508236d63ca710e65f (diff) |
Merge branch 'master' into for-next
Conflicts:
drivers/devfreq/exynos4_bus.c
Sync with Linus' tree to be able to apply patches that are
against newer code (mvneta).
Diffstat (limited to 'fs/xfs/xfs_dir2_leaf.c')
-rw-r--r-- | fs/xfs/xfs_dir2_leaf.c | 172 |
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); |
49 | static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_buf *bp); | 49 | static void xfs_dir2_leaf_log_tail(struct xfs_trans *tp, struct xfs_buf *bp); |
50 | 50 | ||
51 | static void | ||
52 | xfs_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 | |||
67 | static void | ||
68 | xfs_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 | |||
74 | static void | ||
75 | xfs_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 | |||
81 | void | ||
82 | xfs_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 | |||
88 | void | ||
89 | xfs_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 | |||
95 | static 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 | |||
100 | const 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 | |||
105 | static int | ||
106 | xfs_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 | |||
117 | int | ||
118 | xfs_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 | */ |