diff options
Diffstat (limited to 'fs/xfs/xfs_dir2_leaf.c')
-rw-r--r-- | fs/xfs/xfs_dir2_leaf.c | 100 |
1 files changed, 24 insertions, 76 deletions
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c index 16fdc0e627a7..2fb8db9fb574 100644 --- a/fs/xfs/xfs_dir2_leaf.c +++ b/fs/xfs/xfs_dir2_leaf.c | |||
@@ -64,7 +64,7 @@ xfs_dir3_leaf1_check( | |||
64 | struct xfs_dir2_leaf *leaf = bp->b_addr; | 64 | struct xfs_dir2_leaf *leaf = bp->b_addr; |
65 | struct xfs_dir3_icleaf_hdr leafhdr; | 65 | struct xfs_dir3_icleaf_hdr leafhdr; |
66 | 66 | ||
67 | xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); | 67 | dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); |
68 | 68 | ||
69 | if (leafhdr.magic == XFS_DIR3_LEAF1_MAGIC) { | 69 | if (leafhdr.magic == XFS_DIR3_LEAF1_MAGIC) { |
70 | struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr; | 70 | struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr; |
@@ -79,62 +79,6 @@ xfs_dir3_leaf1_check( | |||
79 | #define xfs_dir3_leaf_check(dp, bp) | 79 | #define xfs_dir3_leaf_check(dp, bp) |
80 | #endif | 80 | #endif |
81 | 81 | ||
82 | void | ||
83 | xfs_dir3_leaf_hdr_from_disk( | ||
84 | struct xfs_dir3_icleaf_hdr *to, | ||
85 | struct xfs_dir2_leaf *from) | ||
86 | { | ||
87 | if (from->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || | ||
88 | from->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC)) { | ||
89 | to->forw = be32_to_cpu(from->hdr.info.forw); | ||
90 | to->back = be32_to_cpu(from->hdr.info.back); | ||
91 | to->magic = be16_to_cpu(from->hdr.info.magic); | ||
92 | to->count = be16_to_cpu(from->hdr.count); | ||
93 | to->stale = be16_to_cpu(from->hdr.stale); | ||
94 | } else { | ||
95 | struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)from; | ||
96 | |||
97 | to->forw = be32_to_cpu(hdr3->info.hdr.forw); | ||
98 | to->back = be32_to_cpu(hdr3->info.hdr.back); | ||
99 | to->magic = be16_to_cpu(hdr3->info.hdr.magic); | ||
100 | to->count = be16_to_cpu(hdr3->count); | ||
101 | to->stale = be16_to_cpu(hdr3->stale); | ||
102 | } | ||
103 | |||
104 | ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC || | ||
105 | to->magic == XFS_DIR3_LEAF1_MAGIC || | ||
106 | to->magic == XFS_DIR2_LEAFN_MAGIC || | ||
107 | to->magic == XFS_DIR3_LEAFN_MAGIC); | ||
108 | } | ||
109 | |||
110 | void | ||
111 | xfs_dir3_leaf_hdr_to_disk( | ||
112 | struct xfs_dir2_leaf *to, | ||
113 | struct xfs_dir3_icleaf_hdr *from) | ||
114 | { | ||
115 | ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC || | ||
116 | from->magic == XFS_DIR3_LEAF1_MAGIC || | ||
117 | from->magic == XFS_DIR2_LEAFN_MAGIC || | ||
118 | from->magic == XFS_DIR3_LEAFN_MAGIC); | ||
119 | |||
120 | if (from->magic == XFS_DIR2_LEAF1_MAGIC || | ||
121 | from->magic == XFS_DIR2_LEAFN_MAGIC) { | ||
122 | to->hdr.info.forw = cpu_to_be32(from->forw); | ||
123 | to->hdr.info.back = cpu_to_be32(from->back); | ||
124 | to->hdr.info.magic = cpu_to_be16(from->magic); | ||
125 | to->hdr.count = cpu_to_be16(from->count); | ||
126 | to->hdr.stale = cpu_to_be16(from->stale); | ||
127 | } else { | ||
128 | struct xfs_dir3_leaf_hdr *hdr3 = (struct xfs_dir3_leaf_hdr *)to; | ||
129 | |||
130 | hdr3->info.hdr.forw = cpu_to_be32(from->forw); | ||
131 | hdr3->info.hdr.back = cpu_to_be32(from->back); | ||
132 | hdr3->info.hdr.magic = cpu_to_be16(from->magic); | ||
133 | hdr3->count = cpu_to_be16(from->count); | ||
134 | hdr3->stale = cpu_to_be16(from->stale); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | bool | 82 | bool |
139 | xfs_dir3_leaf_check_int( | 83 | xfs_dir3_leaf_check_int( |
140 | struct xfs_mount *mp, | 84 | struct xfs_mount *mp, |
@@ -147,6 +91,7 @@ xfs_dir3_leaf_check_int( | |||
147 | int stale; | 91 | int stale; |
148 | int i; | 92 | int i; |
149 | const struct xfs_dir_ops *ops; | 93 | const struct xfs_dir_ops *ops; |
94 | struct xfs_dir3_icleaf_hdr leafhdr; | ||
150 | 95 | ||
151 | /* | 96 | /* |
152 | * we can be passed a null dp here from a verifier, so we need to go the | 97 | * we can be passed a null dp here from a verifier, so we need to go the |
@@ -154,6 +99,11 @@ xfs_dir3_leaf_check_int( | |||
154 | */ | 99 | */ |
155 | ops = xfs_dir_get_ops(mp, dp); | 100 | ops = xfs_dir_get_ops(mp, dp); |
156 | 101 | ||
102 | if (!hdr) { | ||
103 | ops->leaf_hdr_from_disk(&leafhdr, leaf); | ||
104 | hdr = &leafhdr; | ||
105 | } | ||
106 | |||
157 | ents = ops->leaf_ents_p(leaf); | 107 | ents = ops->leaf_ents_p(leaf); |
158 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); | 108 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
159 | 109 | ||
@@ -198,7 +148,6 @@ xfs_dir3_leaf_verify( | |||
198 | { | 148 | { |
199 | struct xfs_mount *mp = bp->b_target->bt_mount; | 149 | struct xfs_mount *mp = bp->b_target->bt_mount; |
200 | struct xfs_dir2_leaf *leaf = bp->b_addr; | 150 | struct xfs_dir2_leaf *leaf = bp->b_addr; |
201 | struct xfs_dir3_icleaf_hdr leafhdr; | ||
202 | 151 | ||
203 | ASSERT(magic == XFS_DIR2_LEAF1_MAGIC || magic == XFS_DIR2_LEAFN_MAGIC); | 152 | ASSERT(magic == XFS_DIR2_LEAF1_MAGIC || magic == XFS_DIR2_LEAFN_MAGIC); |
204 | 153 | ||
@@ -220,8 +169,7 @@ xfs_dir3_leaf_verify( | |||
220 | return false; | 169 | return false; |
221 | } | 170 | } |
222 | 171 | ||
223 | xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); | 172 | return xfs_dir3_leaf_check_int(mp, NULL, NULL, leaf); |
224 | return xfs_dir3_leaf_check_int(mp, NULL, &leafhdr, leaf); | ||
225 | } | 173 | } |
226 | 174 | ||
227 | static void | 175 | static void |
@@ -474,10 +422,10 @@ xfs_dir2_block_to_leaf( | |||
474 | /* | 422 | /* |
475 | * Set the counts in the leaf header. | 423 | * Set the counts in the leaf header. |
476 | */ | 424 | */ |
477 | xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); | 425 | dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); |
478 | leafhdr.count = be32_to_cpu(btp->count); | 426 | leafhdr.count = be32_to_cpu(btp->count); |
479 | leafhdr.stale = be32_to_cpu(btp->stale); | 427 | leafhdr.stale = be32_to_cpu(btp->stale); |
480 | xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr); | 428 | dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); |
481 | xfs_dir3_leaf_log_header(tp, dp, lbp); | 429 | xfs_dir3_leaf_log_header(tp, dp, lbp); |
482 | 430 | ||
483 | /* | 431 | /* |
@@ -706,7 +654,7 @@ xfs_dir2_leaf_addname( | |||
706 | leaf = lbp->b_addr; | 654 | leaf = lbp->b_addr; |
707 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); | 655 | ltp = xfs_dir2_leaf_tail_p(mp, leaf); |
708 | ents = dp->d_ops->leaf_ents_p(leaf); | 656 | ents = dp->d_ops->leaf_ents_p(leaf); |
709 | xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); | 657 | dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); |
710 | bestsp = xfs_dir2_leaf_bests_p(ltp); | 658 | bestsp = xfs_dir2_leaf_bests_p(ltp); |
711 | length = dp->d_ops->data_entsize(args->namelen); | 659 | length = dp->d_ops->data_entsize(args->namelen); |
712 | 660 | ||
@@ -945,7 +893,7 @@ xfs_dir2_leaf_addname( | |||
945 | /* | 893 | /* |
946 | * Log the leaf fields and give up the buffers. | 894 | * Log the leaf fields and give up the buffers. |
947 | */ | 895 | */ |
948 | xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr); | 896 | dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); |
949 | xfs_dir3_leaf_log_header(tp, dp, lbp); | 897 | xfs_dir3_leaf_log_header(tp, dp, lbp); |
950 | xfs_dir3_leaf_log_ents(tp, dp, lbp, lfloglow, lfloghigh); | 898 | xfs_dir3_leaf_log_ents(tp, dp, lbp, lfloglow, lfloghigh); |
951 | xfs_dir3_leaf_check(dp, lbp); | 899 | xfs_dir3_leaf_check(dp, lbp); |
@@ -968,6 +916,7 @@ xfs_dir3_leaf_compact( | |||
968 | int loglow; /* first leaf entry to log */ | 916 | int loglow; /* first leaf entry to log */ |
969 | int to; /* target leaf index */ | 917 | int to; /* target leaf index */ |
970 | struct xfs_dir2_leaf_entry *ents; | 918 | struct xfs_dir2_leaf_entry *ents; |
919 | struct xfs_inode *dp = args->dp; | ||
971 | 920 | ||
972 | leaf = bp->b_addr; | 921 | leaf = bp->b_addr; |
973 | if (!leafhdr->stale) | 922 | if (!leafhdr->stale) |
@@ -976,7 +925,7 @@ xfs_dir3_leaf_compact( | |||
976 | /* | 925 | /* |
977 | * Compress out the stale entries in place. | 926 | * Compress out the stale entries in place. |
978 | */ | 927 | */ |
979 | ents = args->dp->d_ops->leaf_ents_p(leaf); | 928 | ents = dp->d_ops->leaf_ents_p(leaf); |
980 | for (from = to = 0, loglow = -1; from < leafhdr->count; from++) { | 929 | for (from = to = 0, loglow = -1; from < leafhdr->count; from++) { |
981 | if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) | 930 | if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) |
982 | continue; | 931 | continue; |
@@ -997,11 +946,10 @@ xfs_dir3_leaf_compact( | |||
997 | leafhdr->count -= leafhdr->stale; | 946 | leafhdr->count -= leafhdr->stale; |
998 | leafhdr->stale = 0; | 947 | leafhdr->stale = 0; |
999 | 948 | ||
1000 | xfs_dir3_leaf_hdr_to_disk(leaf, leafhdr); | 949 | dp->d_ops->leaf_hdr_to_disk(leaf, leafhdr); |
1001 | xfs_dir3_leaf_log_header(args->trans, args->dp, bp); | 950 | xfs_dir3_leaf_log_header(args->trans, dp, bp); |
1002 | if (loglow != -1) | 951 | if (loglow != -1) |
1003 | xfs_dir3_leaf_log_ents(args->trans, args->dp, bp, | 952 | xfs_dir3_leaf_log_ents(args->trans, dp, bp, loglow, to - 1); |
1004 | loglow, to - 1); | ||
1005 | } | 953 | } |
1006 | 954 | ||
1007 | /* | 955 | /* |
@@ -1290,7 +1238,7 @@ xfs_dir2_leaf_lookup_int( | |||
1290 | leaf = lbp->b_addr; | 1238 | leaf = lbp->b_addr; |
1291 | xfs_dir3_leaf_check(dp, lbp); | 1239 | xfs_dir3_leaf_check(dp, lbp); |
1292 | ents = dp->d_ops->leaf_ents_p(leaf); | 1240 | ents = dp->d_ops->leaf_ents_p(leaf); |
1293 | xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); | 1241 | dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); |
1294 | 1242 | ||
1295 | /* | 1243 | /* |
1296 | * Look for the first leaf entry with our hash value. | 1244 | * Look for the first leaf entry with our hash value. |
@@ -1425,7 +1373,7 @@ xfs_dir2_leaf_removename( | |||
1425 | hdr = dbp->b_addr; | 1373 | hdr = dbp->b_addr; |
1426 | xfs_dir3_data_check(dp, dbp); | 1374 | xfs_dir3_data_check(dp, dbp); |
1427 | bf = dp->d_ops->data_bestfree_p(hdr); | 1375 | bf = dp->d_ops->data_bestfree_p(hdr); |
1428 | xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); | 1376 | dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); |
1429 | ents = dp->d_ops->leaf_ents_p(leaf); | 1377 | ents = dp->d_ops->leaf_ents_p(leaf); |
1430 | /* | 1378 | /* |
1431 | * Point to the leaf entry, use that to point to the data entry. | 1379 | * Point to the leaf entry, use that to point to the data entry. |
@@ -1449,7 +1397,7 @@ xfs_dir2_leaf_removename( | |||
1449 | * We just mark the leaf entry stale by putting a null in it. | 1397 | * We just mark the leaf entry stale by putting a null in it. |
1450 | */ | 1398 | */ |
1451 | leafhdr.stale++; | 1399 | leafhdr.stale++; |
1452 | xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr); | 1400 | dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); |
1453 | xfs_dir3_leaf_log_header(tp, dp, lbp); | 1401 | xfs_dir3_leaf_log_header(tp, dp, lbp); |
1454 | 1402 | ||
1455 | lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); | 1403 | lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); |
@@ -1602,7 +1550,7 @@ xfs_dir2_leaf_search_hash( | |||
1602 | 1550 | ||
1603 | leaf = lbp->b_addr; | 1551 | leaf = lbp->b_addr; |
1604 | ents = args->dp->d_ops->leaf_ents_p(leaf); | 1552 | ents = args->dp->d_ops->leaf_ents_p(leaf); |
1605 | xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); | 1553 | args->dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); |
1606 | 1554 | ||
1607 | /* | 1555 | /* |
1608 | * Note, the table cannot be empty, so we have to go through the loop. | 1556 | * Note, the table cannot be empty, so we have to go through the loop. |
@@ -1791,7 +1739,7 @@ xfs_dir2_node_to_leaf( | |||
1791 | return 0; | 1739 | return 0; |
1792 | lbp = state->path.blk[0].bp; | 1740 | lbp = state->path.blk[0].bp; |
1793 | leaf = lbp->b_addr; | 1741 | leaf = lbp->b_addr; |
1794 | xfs_dir3_leaf_hdr_from_disk(&leafhdr, leaf); | 1742 | dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); |
1795 | 1743 | ||
1796 | ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || | 1744 | ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || |
1797 | leafhdr.magic == XFS_DIR3_LEAFN_MAGIC); | 1745 | leafhdr.magic == XFS_DIR3_LEAFN_MAGIC); |
@@ -1803,7 +1751,7 @@ xfs_dir2_node_to_leaf( | |||
1803 | if (error) | 1751 | if (error) |
1804 | return error; | 1752 | return error; |
1805 | free = fbp->b_addr; | 1753 | free = fbp->b_addr; |
1806 | xfs_dir3_free_hdr_from_disk(&freehdr, free); | 1754 | dp->d_ops->free_hdr_from_disk(&freehdr, free); |
1807 | 1755 | ||
1808 | ASSERT(!freehdr.firstdb); | 1756 | ASSERT(!freehdr.firstdb); |
1809 | 1757 | ||
@@ -1840,7 +1788,7 @@ xfs_dir2_node_to_leaf( | |||
1840 | memcpy(xfs_dir2_leaf_bests_p(ltp), xfs_dir3_free_bests_p(mp, free), | 1788 | memcpy(xfs_dir2_leaf_bests_p(ltp), xfs_dir3_free_bests_p(mp, free), |
1841 | freehdr.nvalid * sizeof(xfs_dir2_data_off_t)); | 1789 | freehdr.nvalid * sizeof(xfs_dir2_data_off_t)); |
1842 | 1790 | ||
1843 | xfs_dir3_leaf_hdr_to_disk(leaf, &leafhdr); | 1791 | dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); |
1844 | xfs_dir3_leaf_log_header(tp, dp, lbp); | 1792 | xfs_dir3_leaf_log_header(tp, dp, lbp); |
1845 | xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); | 1793 | xfs_dir3_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); |
1846 | xfs_dir3_leaf_log_tail(tp, lbp); | 1794 | xfs_dir3_leaf_log_tail(tp, lbp); |