.. | .. |
---|
6 | 6 | */ |
---|
7 | 7 | #include "xfs.h" |
---|
8 | 8 | #include "xfs_fs.h" |
---|
| 9 | +#include "xfs_shared.h" |
---|
9 | 10 | #include "xfs_format.h" |
---|
10 | 11 | #include "xfs_log_format.h" |
---|
11 | 12 | #include "xfs_trans_resv.h" |
---|
12 | 13 | #include "xfs_mount.h" |
---|
13 | | -#include "xfs_da_format.h" |
---|
14 | | -#include "xfs_da_btree.h" |
---|
15 | 14 | #include "xfs_inode.h" |
---|
16 | 15 | #include "xfs_bmap.h" |
---|
17 | 16 | #include "xfs_dir2.h" |
---|
.. | .. |
---|
20 | 19 | #include "xfs_trace.h" |
---|
21 | 20 | #include "xfs_trans.h" |
---|
22 | 21 | #include "xfs_buf_item.h" |
---|
23 | | -#include "xfs_cksum.h" |
---|
24 | | -#include "xfs_log.h" |
---|
25 | 22 | |
---|
26 | 23 | /* |
---|
27 | 24 | * Local function declarations. |
---|
28 | 25 | */ |
---|
29 | 26 | static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, struct xfs_buf **lbpp, |
---|
30 | | - int *indexp, struct xfs_buf **dbpp); |
---|
| 27 | + int *indexp, struct xfs_buf **dbpp, |
---|
| 28 | + struct xfs_dir3_icleaf_hdr *leafhdr); |
---|
31 | 29 | static void xfs_dir3_leaf_log_bests(struct xfs_da_args *args, |
---|
32 | 30 | struct xfs_buf *bp, int first, int last); |
---|
33 | 31 | static void xfs_dir3_leaf_log_tail(struct xfs_da_args *args, |
---|
34 | 32 | struct xfs_buf *bp); |
---|
| 33 | + |
---|
| 34 | +void |
---|
| 35 | +xfs_dir2_leaf_hdr_from_disk( |
---|
| 36 | + struct xfs_mount *mp, |
---|
| 37 | + struct xfs_dir3_icleaf_hdr *to, |
---|
| 38 | + struct xfs_dir2_leaf *from) |
---|
| 39 | +{ |
---|
| 40 | + if (xfs_sb_version_hascrc(&mp->m_sb)) { |
---|
| 41 | + struct xfs_dir3_leaf *from3 = (struct xfs_dir3_leaf *)from; |
---|
| 42 | + |
---|
| 43 | + to->forw = be32_to_cpu(from3->hdr.info.hdr.forw); |
---|
| 44 | + to->back = be32_to_cpu(from3->hdr.info.hdr.back); |
---|
| 45 | + to->magic = be16_to_cpu(from3->hdr.info.hdr.magic); |
---|
| 46 | + to->count = be16_to_cpu(from3->hdr.count); |
---|
| 47 | + to->stale = be16_to_cpu(from3->hdr.stale); |
---|
| 48 | + to->ents = from3->__ents; |
---|
| 49 | + |
---|
| 50 | + ASSERT(to->magic == XFS_DIR3_LEAF1_MAGIC || |
---|
| 51 | + to->magic == XFS_DIR3_LEAFN_MAGIC); |
---|
| 52 | + } else { |
---|
| 53 | + to->forw = be32_to_cpu(from->hdr.info.forw); |
---|
| 54 | + to->back = be32_to_cpu(from->hdr.info.back); |
---|
| 55 | + to->magic = be16_to_cpu(from->hdr.info.magic); |
---|
| 56 | + to->count = be16_to_cpu(from->hdr.count); |
---|
| 57 | + to->stale = be16_to_cpu(from->hdr.stale); |
---|
| 58 | + to->ents = from->__ents; |
---|
| 59 | + |
---|
| 60 | + ASSERT(to->magic == XFS_DIR2_LEAF1_MAGIC || |
---|
| 61 | + to->magic == XFS_DIR2_LEAFN_MAGIC); |
---|
| 62 | + } |
---|
| 63 | +} |
---|
| 64 | + |
---|
| 65 | +void |
---|
| 66 | +xfs_dir2_leaf_hdr_to_disk( |
---|
| 67 | + struct xfs_mount *mp, |
---|
| 68 | + struct xfs_dir2_leaf *to, |
---|
| 69 | + struct xfs_dir3_icleaf_hdr *from) |
---|
| 70 | +{ |
---|
| 71 | + if (xfs_sb_version_hascrc(&mp->m_sb)) { |
---|
| 72 | + struct xfs_dir3_leaf *to3 = (struct xfs_dir3_leaf *)to; |
---|
| 73 | + |
---|
| 74 | + ASSERT(from->magic == XFS_DIR3_LEAF1_MAGIC || |
---|
| 75 | + from->magic == XFS_DIR3_LEAFN_MAGIC); |
---|
| 76 | + |
---|
| 77 | + to3->hdr.info.hdr.forw = cpu_to_be32(from->forw); |
---|
| 78 | + to3->hdr.info.hdr.back = cpu_to_be32(from->back); |
---|
| 79 | + to3->hdr.info.hdr.magic = cpu_to_be16(from->magic); |
---|
| 80 | + to3->hdr.count = cpu_to_be16(from->count); |
---|
| 81 | + to3->hdr.stale = cpu_to_be16(from->stale); |
---|
| 82 | + } else { |
---|
| 83 | + ASSERT(from->magic == XFS_DIR2_LEAF1_MAGIC || |
---|
| 84 | + from->magic == XFS_DIR2_LEAFN_MAGIC); |
---|
| 85 | + |
---|
| 86 | + to->hdr.info.forw = cpu_to_be32(from->forw); |
---|
| 87 | + to->hdr.info.back = cpu_to_be32(from->back); |
---|
| 88 | + to->hdr.info.magic = cpu_to_be16(from->magic); |
---|
| 89 | + to->hdr.count = cpu_to_be16(from->count); |
---|
| 90 | + to->hdr.stale = cpu_to_be16(from->stale); |
---|
| 91 | + } |
---|
| 92 | +} |
---|
35 | 93 | |
---|
36 | 94 | /* |
---|
37 | 95 | * Check the internal consistency of a leaf1 block. |
---|
.. | .. |
---|
46 | 104 | struct xfs_dir2_leaf *leaf = bp->b_addr; |
---|
47 | 105 | struct xfs_dir3_icleaf_hdr leafhdr; |
---|
48 | 106 | |
---|
49 | | - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); |
---|
| 107 | + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); |
---|
50 | 108 | |
---|
51 | 109 | if (leafhdr.magic == XFS_DIR3_LEAF1_MAGIC) { |
---|
52 | 110 | struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr; |
---|
.. | .. |
---|
55 | 113 | } else if (leafhdr.magic != XFS_DIR2_LEAF1_MAGIC) |
---|
56 | 114 | return __this_address; |
---|
57 | 115 | |
---|
58 | | - return xfs_dir3_leaf_check_int(dp->i_mount, dp, &leafhdr, leaf); |
---|
| 116 | + return xfs_dir3_leaf_check_int(dp->i_mount, &leafhdr, leaf); |
---|
59 | 117 | } |
---|
60 | 118 | |
---|
61 | 119 | static inline void |
---|
.. | .. |
---|
79 | 137 | |
---|
80 | 138 | xfs_failaddr_t |
---|
81 | 139 | xfs_dir3_leaf_check_int( |
---|
82 | | - struct xfs_mount *mp, |
---|
83 | | - struct xfs_inode *dp, |
---|
84 | | - struct xfs_dir3_icleaf_hdr *hdr, |
---|
85 | | - struct xfs_dir2_leaf *leaf) |
---|
| 140 | + struct xfs_mount *mp, |
---|
| 141 | + struct xfs_dir3_icleaf_hdr *hdr, |
---|
| 142 | + struct xfs_dir2_leaf *leaf) |
---|
86 | 143 | { |
---|
87 | | - struct xfs_dir2_leaf_entry *ents; |
---|
88 | | - xfs_dir2_leaf_tail_t *ltp; |
---|
89 | | - int stale; |
---|
90 | | - int i; |
---|
91 | | - const struct xfs_dir_ops *ops; |
---|
92 | | - struct xfs_dir3_icleaf_hdr leafhdr; |
---|
93 | | - struct xfs_da_geometry *geo = mp->m_dir_geo; |
---|
| 144 | + struct xfs_da_geometry *geo = mp->m_dir_geo; |
---|
| 145 | + xfs_dir2_leaf_tail_t *ltp; |
---|
| 146 | + int stale; |
---|
| 147 | + int i; |
---|
94 | 148 | |
---|
95 | | - /* |
---|
96 | | - * we can be passed a null dp here from a verifier, so we need to go the |
---|
97 | | - * hard way to get them. |
---|
98 | | - */ |
---|
99 | | - ops = xfs_dir_get_ops(mp, dp); |
---|
100 | | - |
---|
101 | | - if (!hdr) { |
---|
102 | | - ops->leaf_hdr_from_disk(&leafhdr, leaf); |
---|
103 | | - hdr = &leafhdr; |
---|
104 | | - } |
---|
105 | | - |
---|
106 | | - ents = ops->leaf_ents_p(leaf); |
---|
107 | 149 | ltp = xfs_dir2_leaf_tail_p(geo, leaf); |
---|
108 | 150 | |
---|
109 | 151 | /* |
---|
.. | .. |
---|
111 | 153 | * Should factor in the size of the bests table as well. |
---|
112 | 154 | * We can deduce a value for that from di_size. |
---|
113 | 155 | */ |
---|
114 | | - if (hdr->count > ops->leaf_max_ents(geo)) |
---|
| 156 | + if (hdr->count > geo->leaf_max_ents) |
---|
115 | 157 | return __this_address; |
---|
116 | 158 | |
---|
117 | 159 | /* Leaves and bests don't overlap in leaf format. */ |
---|
118 | 160 | if ((hdr->magic == XFS_DIR2_LEAF1_MAGIC || |
---|
119 | 161 | hdr->magic == XFS_DIR3_LEAF1_MAGIC) && |
---|
120 | | - (char *)&ents[hdr->count] > (char *)xfs_dir2_leaf_bests_p(ltp)) |
---|
| 162 | + (char *)&hdr->ents[hdr->count] > (char *)xfs_dir2_leaf_bests_p(ltp)) |
---|
121 | 163 | return __this_address; |
---|
122 | 164 | |
---|
123 | 165 | /* Check hash value order, count stale entries. */ |
---|
124 | 166 | for (i = stale = 0; i < hdr->count; i++) { |
---|
125 | 167 | if (i + 1 < hdr->count) { |
---|
126 | | - if (be32_to_cpu(ents[i].hashval) > |
---|
127 | | - be32_to_cpu(ents[i + 1].hashval)) |
---|
| 168 | + if (be32_to_cpu(hdr->ents[i].hashval) > |
---|
| 169 | + be32_to_cpu(hdr->ents[i + 1].hashval)) |
---|
128 | 170 | return __this_address; |
---|
129 | 171 | } |
---|
130 | | - if (ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) |
---|
| 172 | + if (hdr->ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) |
---|
131 | 173 | stale++; |
---|
132 | 174 | } |
---|
133 | 175 | if (hdr->stale != stale) |
---|
.. | .. |
---|
142 | 184 | */ |
---|
143 | 185 | static xfs_failaddr_t |
---|
144 | 186 | xfs_dir3_leaf_verify( |
---|
145 | | - struct xfs_buf *bp, |
---|
146 | | - uint16_t magic) |
---|
| 187 | + struct xfs_buf *bp) |
---|
147 | 188 | { |
---|
148 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
---|
149 | | - struct xfs_dir2_leaf *leaf = bp->b_addr; |
---|
| 189 | + struct xfs_mount *mp = bp->b_mount; |
---|
| 190 | + struct xfs_dir3_icleaf_hdr leafhdr; |
---|
| 191 | + xfs_failaddr_t fa; |
---|
150 | 192 | |
---|
151 | | - ASSERT(magic == XFS_DIR2_LEAF1_MAGIC || magic == XFS_DIR2_LEAFN_MAGIC); |
---|
| 193 | + fa = xfs_da3_blkinfo_verify(bp, bp->b_addr); |
---|
| 194 | + if (fa) |
---|
| 195 | + return fa; |
---|
152 | 196 | |
---|
153 | | - if (xfs_sb_version_hascrc(&mp->m_sb)) { |
---|
154 | | - struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr; |
---|
155 | | - uint16_t magic3; |
---|
156 | | - |
---|
157 | | - magic3 = (magic == XFS_DIR2_LEAF1_MAGIC) ? XFS_DIR3_LEAF1_MAGIC |
---|
158 | | - : XFS_DIR3_LEAFN_MAGIC; |
---|
159 | | - |
---|
160 | | - if (leaf3->info.hdr.magic != cpu_to_be16(magic3)) |
---|
161 | | - return __this_address; |
---|
162 | | - if (!uuid_equal(&leaf3->info.uuid, &mp->m_sb.sb_meta_uuid)) |
---|
163 | | - return __this_address; |
---|
164 | | - if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn) |
---|
165 | | - return __this_address; |
---|
166 | | - if (!xfs_log_check_lsn(mp, be64_to_cpu(leaf3->info.lsn))) |
---|
167 | | - return __this_address; |
---|
168 | | - } else { |
---|
169 | | - if (leaf->hdr.info.magic != cpu_to_be16(magic)) |
---|
170 | | - return __this_address; |
---|
171 | | - } |
---|
172 | | - |
---|
173 | | - return xfs_dir3_leaf_check_int(mp, NULL, NULL, leaf); |
---|
| 197 | + xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, bp->b_addr); |
---|
| 198 | + return xfs_dir3_leaf_check_int(mp, &leafhdr, bp->b_addr); |
---|
174 | 199 | } |
---|
175 | 200 | |
---|
176 | 201 | static void |
---|
177 | | -__read_verify( |
---|
178 | | - struct xfs_buf *bp, |
---|
179 | | - uint16_t magic) |
---|
| 202 | +xfs_dir3_leaf_read_verify( |
---|
| 203 | + struct xfs_buf *bp) |
---|
180 | 204 | { |
---|
181 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
---|
| 205 | + struct xfs_mount *mp = bp->b_mount; |
---|
182 | 206 | xfs_failaddr_t fa; |
---|
183 | 207 | |
---|
184 | 208 | if (xfs_sb_version_hascrc(&mp->m_sb) && |
---|
185 | 209 | !xfs_buf_verify_cksum(bp, XFS_DIR3_LEAF_CRC_OFF)) |
---|
186 | 210 | xfs_verifier_error(bp, -EFSBADCRC, __this_address); |
---|
187 | 211 | else { |
---|
188 | | - fa = xfs_dir3_leaf_verify(bp, magic); |
---|
| 212 | + fa = xfs_dir3_leaf_verify(bp); |
---|
189 | 213 | if (fa) |
---|
190 | 214 | xfs_verifier_error(bp, -EFSCORRUPTED, fa); |
---|
191 | 215 | } |
---|
192 | 216 | } |
---|
193 | 217 | |
---|
194 | 218 | static void |
---|
195 | | -__write_verify( |
---|
196 | | - struct xfs_buf *bp, |
---|
197 | | - uint16_t magic) |
---|
| 219 | +xfs_dir3_leaf_write_verify( |
---|
| 220 | + struct xfs_buf *bp) |
---|
198 | 221 | { |
---|
199 | | - struct xfs_mount *mp = bp->b_target->bt_mount; |
---|
| 222 | + struct xfs_mount *mp = bp->b_mount; |
---|
200 | 223 | struct xfs_buf_log_item *bip = bp->b_log_item; |
---|
201 | 224 | struct xfs_dir3_leaf_hdr *hdr3 = bp->b_addr; |
---|
202 | 225 | xfs_failaddr_t fa; |
---|
203 | 226 | |
---|
204 | | - fa = xfs_dir3_leaf_verify(bp, magic); |
---|
| 227 | + fa = xfs_dir3_leaf_verify(bp); |
---|
205 | 228 | if (fa) { |
---|
206 | 229 | xfs_verifier_error(bp, -EFSCORRUPTED, fa); |
---|
207 | 230 | return; |
---|
.. | .. |
---|
216 | 239 | xfs_buf_update_cksum(bp, XFS_DIR3_LEAF_CRC_OFF); |
---|
217 | 240 | } |
---|
218 | 241 | |
---|
219 | | -static xfs_failaddr_t |
---|
220 | | -xfs_dir3_leaf1_verify( |
---|
221 | | - struct xfs_buf *bp) |
---|
222 | | -{ |
---|
223 | | - return xfs_dir3_leaf_verify(bp, XFS_DIR2_LEAF1_MAGIC); |
---|
224 | | -} |
---|
225 | | - |
---|
226 | | -static void |
---|
227 | | -xfs_dir3_leaf1_read_verify( |
---|
228 | | - struct xfs_buf *bp) |
---|
229 | | -{ |
---|
230 | | - __read_verify(bp, XFS_DIR2_LEAF1_MAGIC); |
---|
231 | | -} |
---|
232 | | - |
---|
233 | | -static void |
---|
234 | | -xfs_dir3_leaf1_write_verify( |
---|
235 | | - struct xfs_buf *bp) |
---|
236 | | -{ |
---|
237 | | - __write_verify(bp, XFS_DIR2_LEAF1_MAGIC); |
---|
238 | | -} |
---|
239 | | - |
---|
240 | | -static xfs_failaddr_t |
---|
241 | | -xfs_dir3_leafn_verify( |
---|
242 | | - struct xfs_buf *bp) |
---|
243 | | -{ |
---|
244 | | - return xfs_dir3_leaf_verify(bp, XFS_DIR2_LEAFN_MAGIC); |
---|
245 | | -} |
---|
246 | | - |
---|
247 | | -static void |
---|
248 | | -xfs_dir3_leafn_read_verify( |
---|
249 | | - struct xfs_buf *bp) |
---|
250 | | -{ |
---|
251 | | - __read_verify(bp, XFS_DIR2_LEAFN_MAGIC); |
---|
252 | | -} |
---|
253 | | - |
---|
254 | | -static void |
---|
255 | | -xfs_dir3_leafn_write_verify( |
---|
256 | | - struct xfs_buf *bp) |
---|
257 | | -{ |
---|
258 | | - __write_verify(bp, XFS_DIR2_LEAFN_MAGIC); |
---|
259 | | -} |
---|
260 | | - |
---|
261 | 242 | const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops = { |
---|
262 | 243 | .name = "xfs_dir3_leaf1", |
---|
263 | | - .verify_read = xfs_dir3_leaf1_read_verify, |
---|
264 | | - .verify_write = xfs_dir3_leaf1_write_verify, |
---|
265 | | - .verify_struct = xfs_dir3_leaf1_verify, |
---|
| 244 | + .magic16 = { cpu_to_be16(XFS_DIR2_LEAF1_MAGIC), |
---|
| 245 | + cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) }, |
---|
| 246 | + .verify_read = xfs_dir3_leaf_read_verify, |
---|
| 247 | + .verify_write = xfs_dir3_leaf_write_verify, |
---|
| 248 | + .verify_struct = xfs_dir3_leaf_verify, |
---|
266 | 249 | }; |
---|
267 | 250 | |
---|
268 | 251 | const struct xfs_buf_ops xfs_dir3_leafn_buf_ops = { |
---|
269 | 252 | .name = "xfs_dir3_leafn", |
---|
270 | | - .verify_read = xfs_dir3_leafn_read_verify, |
---|
271 | | - .verify_write = xfs_dir3_leafn_write_verify, |
---|
272 | | - .verify_struct = xfs_dir3_leafn_verify, |
---|
| 253 | + .magic16 = { cpu_to_be16(XFS_DIR2_LEAFN_MAGIC), |
---|
| 254 | + cpu_to_be16(XFS_DIR3_LEAFN_MAGIC) }, |
---|
| 255 | + .verify_read = xfs_dir3_leaf_read_verify, |
---|
| 256 | + .verify_write = xfs_dir3_leaf_write_verify, |
---|
| 257 | + .verify_struct = xfs_dir3_leaf_verify, |
---|
273 | 258 | }; |
---|
274 | 259 | |
---|
275 | 260 | int |
---|
.. | .. |
---|
277 | 262 | struct xfs_trans *tp, |
---|
278 | 263 | struct xfs_inode *dp, |
---|
279 | 264 | xfs_dablk_t fbno, |
---|
280 | | - xfs_daddr_t mappedbno, |
---|
281 | 265 | struct xfs_buf **bpp) |
---|
282 | 266 | { |
---|
283 | 267 | int err; |
---|
284 | 268 | |
---|
285 | | - err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, |
---|
286 | | - XFS_DATA_FORK, &xfs_dir3_leaf1_buf_ops); |
---|
| 269 | + err = xfs_da_read_buf(tp, dp, fbno, 0, bpp, XFS_DATA_FORK, |
---|
| 270 | + &xfs_dir3_leaf1_buf_ops); |
---|
287 | 271 | if (!err && tp && *bpp) |
---|
288 | 272 | xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_LEAF1_BUF); |
---|
289 | 273 | return err; |
---|
.. | .. |
---|
294 | 278 | struct xfs_trans *tp, |
---|
295 | 279 | struct xfs_inode *dp, |
---|
296 | 280 | xfs_dablk_t fbno, |
---|
297 | | - xfs_daddr_t mappedbno, |
---|
298 | 281 | struct xfs_buf **bpp) |
---|
299 | 282 | { |
---|
300 | 283 | int err; |
---|
301 | 284 | |
---|
302 | | - err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp, |
---|
303 | | - XFS_DATA_FORK, &xfs_dir3_leafn_buf_ops); |
---|
| 285 | + err = xfs_da_read_buf(tp, dp, fbno, 0, bpp, XFS_DATA_FORK, |
---|
| 286 | + &xfs_dir3_leafn_buf_ops); |
---|
304 | 287 | if (!err && tp && *bpp) |
---|
305 | 288 | xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_LEAFN_BUF); |
---|
306 | 289 | return err; |
---|
.. | .. |
---|
372 | 355 | bno < xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET)); |
---|
373 | 356 | |
---|
374 | 357 | error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, bno), |
---|
375 | | - -1, &bp, XFS_DATA_FORK); |
---|
| 358 | + &bp, XFS_DATA_FORK); |
---|
376 | 359 | if (error) |
---|
377 | 360 | return error; |
---|
378 | 361 | |
---|
.. | .. |
---|
407 | 390 | int needscan; /* need to rescan bestfree */ |
---|
408 | 391 | xfs_trans_t *tp; /* transaction pointer */ |
---|
409 | 392 | struct xfs_dir2_data_free *bf; |
---|
410 | | - struct xfs_dir2_leaf_entry *ents; |
---|
411 | 393 | struct xfs_dir3_icleaf_hdr leafhdr; |
---|
412 | 394 | |
---|
413 | 395 | trace_xfs_dir2_block_to_leaf(args); |
---|
.. | .. |
---|
436 | 418 | xfs_dir3_data_check(dp, dbp); |
---|
437 | 419 | btp = xfs_dir2_block_tail_p(args->geo, hdr); |
---|
438 | 420 | blp = xfs_dir2_block_leaf_p(btp); |
---|
439 | | - bf = dp->d_ops->data_bestfree_p(hdr); |
---|
440 | | - ents = dp->d_ops->leaf_ents_p(leaf); |
---|
| 421 | + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); |
---|
441 | 422 | |
---|
442 | 423 | /* |
---|
443 | 424 | * Set the counts in the leaf header. |
---|
444 | 425 | */ |
---|
445 | | - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); |
---|
| 426 | + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); |
---|
446 | 427 | leafhdr.count = be32_to_cpu(btp->count); |
---|
447 | 428 | leafhdr.stale = be32_to_cpu(btp->stale); |
---|
448 | | - dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); |
---|
| 429 | + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); |
---|
449 | 430 | xfs_dir3_leaf_log_header(args, lbp); |
---|
450 | 431 | |
---|
451 | 432 | /* |
---|
452 | 433 | * Could compact these but I think we always do the conversion |
---|
453 | 434 | * after squeezing out stale entries. |
---|
454 | 435 | */ |
---|
455 | | - memcpy(ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t)); |
---|
456 | | - xfs_dir3_leaf_log_ents(args, lbp, 0, leafhdr.count - 1); |
---|
| 436 | + memcpy(leafhdr.ents, blp, |
---|
| 437 | + be32_to_cpu(btp->count) * sizeof(struct xfs_dir2_leaf_entry)); |
---|
| 438 | + xfs_dir3_leaf_log_ents(args, &leafhdr, lbp, 0, leafhdr.count - 1); |
---|
457 | 439 | needscan = 0; |
---|
458 | 440 | needlog = 1; |
---|
459 | 441 | /* |
---|
.. | .. |
---|
476 | 458 | hdr->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC); |
---|
477 | 459 | |
---|
478 | 460 | if (needscan) |
---|
479 | | - xfs_dir2_data_freescan(dp, hdr, &needlog); |
---|
| 461 | + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); |
---|
480 | 462 | /* |
---|
481 | 463 | * Set up leaf tail and bests table. |
---|
482 | 464 | */ |
---|
.. | .. |
---|
621 | 603 | */ |
---|
622 | 604 | int /* error */ |
---|
623 | 605 | xfs_dir2_leaf_addname( |
---|
624 | | - xfs_da_args_t *args) /* operation arguments */ |
---|
| 606 | + struct xfs_da_args *args) /* operation arguments */ |
---|
625 | 607 | { |
---|
| 608 | + struct xfs_dir3_icleaf_hdr leafhdr; |
---|
| 609 | + struct xfs_trans *tp = args->trans; |
---|
626 | 610 | __be16 *bestsp; /* freespace table in leaf */ |
---|
627 | | - int compact; /* need to compact leaves */ |
---|
628 | | - xfs_dir2_data_hdr_t *hdr; /* data block header */ |
---|
| 611 | + __be16 *tagp; /* end of data entry */ |
---|
629 | 612 | struct xfs_buf *dbp; /* data block buffer */ |
---|
630 | | - xfs_dir2_data_entry_t *dep; /* data block entry */ |
---|
631 | | - xfs_inode_t *dp; /* incore directory inode */ |
---|
632 | | - xfs_dir2_data_unused_t *dup; /* data unused entry */ |
---|
| 613 | + struct xfs_buf *lbp; /* leaf's buffer */ |
---|
| 614 | + struct xfs_dir2_leaf *leaf; /* leaf structure */ |
---|
| 615 | + struct xfs_inode *dp = args->dp; /* incore directory inode */ |
---|
| 616 | + struct xfs_dir2_data_hdr *hdr; /* data block header */ |
---|
| 617 | + struct xfs_dir2_data_entry *dep; /* data block entry */ |
---|
| 618 | + struct xfs_dir2_leaf_entry *lep; /* leaf entry table pointer */ |
---|
| 619 | + struct xfs_dir2_leaf_entry *ents; |
---|
| 620 | + struct xfs_dir2_data_unused *dup; /* data unused entry */ |
---|
| 621 | + struct xfs_dir2_leaf_tail *ltp; /* leaf tail pointer */ |
---|
| 622 | + struct xfs_dir2_data_free *bf; /* bestfree table */ |
---|
| 623 | + int compact; /* need to compact leaves */ |
---|
633 | 624 | int error; /* error return value */ |
---|
634 | 625 | int grown; /* allocated new data block */ |
---|
635 | | - int highstale; /* index of next stale leaf */ |
---|
| 626 | + int highstale = 0; /* index of next stale leaf */ |
---|
636 | 627 | int i; /* temporary, index */ |
---|
637 | 628 | int index; /* leaf table position */ |
---|
638 | | - struct xfs_buf *lbp; /* leaf's buffer */ |
---|
639 | | - xfs_dir2_leaf_t *leaf; /* leaf structure */ |
---|
640 | 629 | int length; /* length of new entry */ |
---|
641 | | - xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */ |
---|
642 | 630 | int lfloglow; /* low leaf logging index */ |
---|
643 | 631 | int lfloghigh; /* high leaf logging index */ |
---|
644 | | - int lowstale; /* index of prev stale leaf */ |
---|
645 | | - xfs_dir2_leaf_tail_t *ltp; /* leaf tail pointer */ |
---|
| 632 | + int lowstale = 0; /* index of prev stale leaf */ |
---|
646 | 633 | int needbytes; /* leaf block bytes needed */ |
---|
647 | 634 | int needlog; /* need to log data header */ |
---|
648 | 635 | int needscan; /* need to rescan data free */ |
---|
649 | | - __be16 *tagp; /* end of data entry */ |
---|
650 | | - xfs_trans_t *tp; /* transaction pointer */ |
---|
651 | 636 | xfs_dir2_db_t use_block; /* data block number */ |
---|
652 | | - struct xfs_dir2_data_free *bf; /* bestfree table */ |
---|
653 | | - struct xfs_dir2_leaf_entry *ents; |
---|
654 | | - struct xfs_dir3_icleaf_hdr leafhdr; |
---|
655 | 637 | |
---|
656 | 638 | trace_xfs_dir2_leaf_addname(args); |
---|
657 | 639 | |
---|
658 | | - dp = args->dp; |
---|
659 | | - tp = args->trans; |
---|
660 | | - |
---|
661 | | - error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, -1, &lbp); |
---|
| 640 | + error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, &lbp); |
---|
662 | 641 | if (error) |
---|
663 | 642 | return error; |
---|
664 | 643 | |
---|
.. | .. |
---|
671 | 650 | index = xfs_dir2_leaf_search_hash(args, lbp); |
---|
672 | 651 | leaf = lbp->b_addr; |
---|
673 | 652 | ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); |
---|
674 | | - ents = dp->d_ops->leaf_ents_p(leaf); |
---|
675 | | - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); |
---|
| 653 | + xfs_dir2_leaf_hdr_from_disk(dp->i_mount, &leafhdr, leaf); |
---|
| 654 | + ents = leafhdr.ents; |
---|
676 | 655 | bestsp = xfs_dir2_leaf_bests_p(ltp); |
---|
677 | | - length = dp->d_ops->data_entsize(args->namelen); |
---|
| 656 | + length = xfs_dir2_data_entsize(dp->i_mount, args->namelen); |
---|
678 | 657 | |
---|
679 | 658 | /* |
---|
680 | 659 | * See if there are any entries with the same hash value |
---|
.. | .. |
---|
837 | 816 | else |
---|
838 | 817 | xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block); |
---|
839 | 818 | hdr = dbp->b_addr; |
---|
840 | | - bf = dp->d_ops->data_bestfree_p(hdr); |
---|
| 819 | + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); |
---|
841 | 820 | bestsp[use_block] = bf[0].length; |
---|
842 | 821 | grown = 1; |
---|
843 | 822 | } else { |
---|
.. | .. |
---|
847 | 826 | */ |
---|
848 | 827 | error = xfs_dir3_data_read(tp, dp, |
---|
849 | 828 | xfs_dir2_db_to_da(args->geo, use_block), |
---|
850 | | - -1, &dbp); |
---|
| 829 | + 0, &dbp); |
---|
851 | 830 | if (error) { |
---|
852 | 831 | xfs_trans_brelse(tp, lbp); |
---|
853 | 832 | return error; |
---|
854 | 833 | } |
---|
855 | 834 | hdr = dbp->b_addr; |
---|
856 | | - bf = dp->d_ops->data_bestfree_p(hdr); |
---|
| 835 | + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); |
---|
857 | 836 | grown = 0; |
---|
858 | 837 | } |
---|
859 | 838 | /* |
---|
.. | .. |
---|
879 | 858 | dep->inumber = cpu_to_be64(args->inumber); |
---|
880 | 859 | dep->namelen = args->namelen; |
---|
881 | 860 | memcpy(dep->name, args->name, dep->namelen); |
---|
882 | | - dp->d_ops->data_put_ftype(dep, args->filetype); |
---|
883 | | - tagp = dp->d_ops->data_entry_tag_p(dep); |
---|
| 861 | + xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); |
---|
| 862 | + tagp = xfs_dir2_data_entry_tag_p(dp->i_mount, dep); |
---|
884 | 863 | *tagp = cpu_to_be16((char *)dep - (char *)hdr); |
---|
885 | 864 | /* |
---|
886 | 865 | * Need to scan fix up the bestfree table. |
---|
887 | 866 | */ |
---|
888 | 867 | if (needscan) |
---|
889 | | - xfs_dir2_data_freescan(dp, hdr, &needlog); |
---|
| 868 | + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); |
---|
890 | 869 | /* |
---|
891 | 870 | * Need to log the data block's header. |
---|
892 | 871 | */ |
---|
.. | .. |
---|
916 | 895 | /* |
---|
917 | 896 | * Log the leaf fields and give up the buffers. |
---|
918 | 897 | */ |
---|
919 | | - dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); |
---|
| 898 | + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); |
---|
920 | 899 | xfs_dir3_leaf_log_header(args, lbp); |
---|
921 | | - xfs_dir3_leaf_log_ents(args, lbp, lfloglow, lfloghigh); |
---|
| 900 | + xfs_dir3_leaf_log_ents(args, &leafhdr, lbp, lfloglow, lfloghigh); |
---|
922 | 901 | xfs_dir3_leaf_check(dp, lbp); |
---|
923 | 902 | xfs_dir3_data_check(dp, dbp); |
---|
924 | 903 | return 0; |
---|
.. | .. |
---|
938 | 917 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
---|
939 | 918 | int loglow; /* first leaf entry to log */ |
---|
940 | 919 | int to; /* target leaf index */ |
---|
941 | | - struct xfs_dir2_leaf_entry *ents; |
---|
942 | 920 | struct xfs_inode *dp = args->dp; |
---|
943 | 921 | |
---|
944 | 922 | leaf = bp->b_addr; |
---|
.. | .. |
---|
948 | 926 | /* |
---|
949 | 927 | * Compress out the stale entries in place. |
---|
950 | 928 | */ |
---|
951 | | - ents = dp->d_ops->leaf_ents_p(leaf); |
---|
952 | 929 | for (from = to = 0, loglow = -1; from < leafhdr->count; from++) { |
---|
953 | | - if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) |
---|
| 930 | + if (leafhdr->ents[from].address == |
---|
| 931 | + cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) |
---|
954 | 932 | continue; |
---|
955 | 933 | /* |
---|
956 | 934 | * Only actually copy the entries that are different. |
---|
.. | .. |
---|
958 | 936 | if (from > to) { |
---|
959 | 937 | if (loglow == -1) |
---|
960 | 938 | loglow = to; |
---|
961 | | - ents[to] = ents[from]; |
---|
| 939 | + leafhdr->ents[to] = leafhdr->ents[from]; |
---|
962 | 940 | } |
---|
963 | 941 | to++; |
---|
964 | 942 | } |
---|
.. | .. |
---|
969 | 947 | leafhdr->count -= leafhdr->stale; |
---|
970 | 948 | leafhdr->stale = 0; |
---|
971 | 949 | |
---|
972 | | - dp->d_ops->leaf_hdr_to_disk(leaf, leafhdr); |
---|
| 950 | + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, leafhdr); |
---|
973 | 951 | xfs_dir3_leaf_log_header(args, bp); |
---|
974 | 952 | if (loglow != -1) |
---|
975 | | - xfs_dir3_leaf_log_ents(args, bp, loglow, to - 1); |
---|
| 953 | + xfs_dir3_leaf_log_ents(args, leafhdr, bp, loglow, to - 1); |
---|
976 | 954 | } |
---|
977 | 955 | |
---|
978 | 956 | /* |
---|
.. | .. |
---|
1101 | 1079 | void |
---|
1102 | 1080 | xfs_dir3_leaf_log_ents( |
---|
1103 | 1081 | struct xfs_da_args *args, |
---|
| 1082 | + struct xfs_dir3_icleaf_hdr *hdr, |
---|
1104 | 1083 | struct xfs_buf *bp, |
---|
1105 | 1084 | int first, |
---|
1106 | 1085 | int last) |
---|
.. | .. |
---|
1108 | 1087 | xfs_dir2_leaf_entry_t *firstlep; /* pointer to first entry */ |
---|
1109 | 1088 | xfs_dir2_leaf_entry_t *lastlep; /* pointer to last entry */ |
---|
1110 | 1089 | struct xfs_dir2_leaf *leaf = bp->b_addr; |
---|
1111 | | - struct xfs_dir2_leaf_entry *ents; |
---|
1112 | 1090 | |
---|
1113 | 1091 | ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) || |
---|
1114 | 1092 | leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) || |
---|
1115 | 1093 | leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) || |
---|
1116 | 1094 | leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)); |
---|
1117 | 1095 | |
---|
1118 | | - ents = args->dp->d_ops->leaf_ents_p(leaf); |
---|
1119 | | - firstlep = &ents[first]; |
---|
1120 | | - lastlep = &ents[last]; |
---|
| 1096 | + firstlep = &hdr->ents[first]; |
---|
| 1097 | + lastlep = &hdr->ents[last]; |
---|
1121 | 1098 | xfs_trans_log_buf(args->trans, bp, |
---|
1122 | 1099 | (uint)((char *)firstlep - (char *)leaf), |
---|
1123 | 1100 | (uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1)); |
---|
.. | .. |
---|
1140 | 1117 | |
---|
1141 | 1118 | xfs_trans_log_buf(args->trans, bp, |
---|
1142 | 1119 | (uint)((char *)&leaf->hdr - (char *)leaf), |
---|
1143 | | - args->dp->d_ops->leaf_hdr_size - 1); |
---|
| 1120 | + args->geo->leaf_hdr_size - 1); |
---|
1144 | 1121 | } |
---|
1145 | 1122 | |
---|
1146 | 1123 | /* |
---|
.. | .. |
---|
1179 | 1156 | int error; /* error return code */ |
---|
1180 | 1157 | int index; /* found entry index */ |
---|
1181 | 1158 | struct xfs_buf *lbp; /* leaf buffer */ |
---|
1182 | | - xfs_dir2_leaf_t *leaf; /* leaf structure */ |
---|
1183 | 1159 | xfs_dir2_leaf_entry_t *lep; /* leaf entry */ |
---|
1184 | 1160 | xfs_trans_t *tp; /* transaction pointer */ |
---|
1185 | | - struct xfs_dir2_leaf_entry *ents; |
---|
| 1161 | + struct xfs_dir3_icleaf_hdr leafhdr; |
---|
1186 | 1162 | |
---|
1187 | 1163 | trace_xfs_dir2_leaf_lookup(args); |
---|
1188 | 1164 | |
---|
1189 | 1165 | /* |
---|
1190 | 1166 | * Look up name in the leaf block, returning both buffers and index. |
---|
1191 | 1167 | */ |
---|
1192 | | - if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { |
---|
| 1168 | + error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp, &leafhdr); |
---|
| 1169 | + if (error) |
---|
1193 | 1170 | return error; |
---|
1194 | | - } |
---|
| 1171 | + |
---|
1195 | 1172 | tp = args->trans; |
---|
1196 | 1173 | dp = args->dp; |
---|
1197 | 1174 | xfs_dir3_leaf_check(dp, lbp); |
---|
1198 | | - leaf = lbp->b_addr; |
---|
1199 | | - ents = dp->d_ops->leaf_ents_p(leaf); |
---|
| 1175 | + |
---|
1200 | 1176 | /* |
---|
1201 | 1177 | * Get to the leaf entry and contained data entry address. |
---|
1202 | 1178 | */ |
---|
1203 | | - lep = &ents[index]; |
---|
| 1179 | + lep = &leafhdr.ents[index]; |
---|
1204 | 1180 | |
---|
1205 | 1181 | /* |
---|
1206 | 1182 | * Point to the data entry. |
---|
.. | .. |
---|
1212 | 1188 | * Return the found inode number & CI name if appropriate |
---|
1213 | 1189 | */ |
---|
1214 | 1190 | args->inumber = be64_to_cpu(dep->inumber); |
---|
1215 | | - args->filetype = dp->d_ops->data_get_ftype(dep); |
---|
| 1191 | + args->filetype = xfs_dir2_data_get_ftype(dp->i_mount, dep); |
---|
1216 | 1192 | error = xfs_dir_cilookup_result(args, dep->name, dep->namelen); |
---|
1217 | 1193 | xfs_trans_brelse(tp, dbp); |
---|
1218 | 1194 | xfs_trans_brelse(tp, lbp); |
---|
.. | .. |
---|
1230 | 1206 | xfs_da_args_t *args, /* operation arguments */ |
---|
1231 | 1207 | struct xfs_buf **lbpp, /* out: leaf buffer */ |
---|
1232 | 1208 | int *indexp, /* out: index in leaf block */ |
---|
1233 | | - struct xfs_buf **dbpp) /* out: data buffer */ |
---|
| 1209 | + struct xfs_buf **dbpp, /* out: data buffer */ |
---|
| 1210 | + struct xfs_dir3_icleaf_hdr *leafhdr) |
---|
1234 | 1211 | { |
---|
1235 | 1212 | xfs_dir2_db_t curdb = -1; /* current data block number */ |
---|
1236 | 1213 | struct xfs_buf *dbp = NULL; /* data buffer */ |
---|
.. | .. |
---|
1246 | 1223 | xfs_trans_t *tp; /* transaction pointer */ |
---|
1247 | 1224 | xfs_dir2_db_t cidb = -1; /* case match data block no. */ |
---|
1248 | 1225 | enum xfs_dacmp cmp; /* name compare result */ |
---|
1249 | | - struct xfs_dir2_leaf_entry *ents; |
---|
1250 | | - struct xfs_dir3_icleaf_hdr leafhdr; |
---|
1251 | 1226 | |
---|
1252 | 1227 | dp = args->dp; |
---|
1253 | 1228 | tp = args->trans; |
---|
1254 | 1229 | mp = dp->i_mount; |
---|
1255 | 1230 | |
---|
1256 | | - error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, -1, &lbp); |
---|
| 1231 | + error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, &lbp); |
---|
1257 | 1232 | if (error) |
---|
1258 | 1233 | return error; |
---|
1259 | 1234 | |
---|
1260 | 1235 | *lbpp = lbp; |
---|
1261 | 1236 | leaf = lbp->b_addr; |
---|
1262 | 1237 | xfs_dir3_leaf_check(dp, lbp); |
---|
1263 | | - ents = dp->d_ops->leaf_ents_p(leaf); |
---|
1264 | | - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); |
---|
| 1238 | + xfs_dir2_leaf_hdr_from_disk(mp, leafhdr, leaf); |
---|
1265 | 1239 | |
---|
1266 | 1240 | /* |
---|
1267 | 1241 | * Look for the first leaf entry with our hash value. |
---|
.. | .. |
---|
1271 | 1245 | * Loop over all the entries with the right hash value |
---|
1272 | 1246 | * looking to match the name. |
---|
1273 | 1247 | */ |
---|
1274 | | - for (lep = &ents[index]; |
---|
1275 | | - index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval; |
---|
| 1248 | + for (lep = &leafhdr->ents[index]; |
---|
| 1249 | + index < leafhdr->count && |
---|
| 1250 | + be32_to_cpu(lep->hashval) == args->hashval; |
---|
1276 | 1251 | lep++, index++) { |
---|
1277 | 1252 | /* |
---|
1278 | 1253 | * Skip over stale leaf entries. |
---|
.. | .. |
---|
1293 | 1268 | xfs_trans_brelse(tp, dbp); |
---|
1294 | 1269 | error = xfs_dir3_data_read(tp, dp, |
---|
1295 | 1270 | xfs_dir2_db_to_da(args->geo, newdb), |
---|
1296 | | - -1, &dbp); |
---|
| 1271 | + 0, &dbp); |
---|
1297 | 1272 | if (error) { |
---|
1298 | 1273 | xfs_trans_brelse(tp, lbp); |
---|
1299 | 1274 | return error; |
---|
.. | .. |
---|
1311 | 1286 | * and buffer. If it's the first case-insensitive match, store |
---|
1312 | 1287 | * the index and buffer and continue looking for an exact match. |
---|
1313 | 1288 | */ |
---|
1314 | | - cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen); |
---|
| 1289 | + cmp = xfs_dir2_compname(args, dep->name, dep->namelen); |
---|
1315 | 1290 | if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { |
---|
1316 | 1291 | args->cmpresult = cmp; |
---|
1317 | 1292 | *indexp = index; |
---|
.. | .. |
---|
1335 | 1310 | xfs_trans_brelse(tp, dbp); |
---|
1336 | 1311 | error = xfs_dir3_data_read(tp, dp, |
---|
1337 | 1312 | xfs_dir2_db_to_da(args->geo, cidb), |
---|
1338 | | - -1, &dbp); |
---|
| 1313 | + 0, &dbp); |
---|
1339 | 1314 | if (error) { |
---|
1340 | 1315 | xfs_trans_brelse(tp, lbp); |
---|
1341 | 1316 | return error; |
---|
.. | .. |
---|
1361 | 1336 | xfs_dir2_leaf_removename( |
---|
1362 | 1337 | xfs_da_args_t *args) /* operation arguments */ |
---|
1363 | 1338 | { |
---|
| 1339 | + struct xfs_da_geometry *geo = args->geo; |
---|
1364 | 1340 | __be16 *bestsp; /* leaf block best freespace */ |
---|
1365 | 1341 | xfs_dir2_data_hdr_t *hdr; /* data block header */ |
---|
1366 | 1342 | xfs_dir2_db_t db; /* data block number */ |
---|
.. | .. |
---|
1378 | 1354 | int needscan; /* need to rescan data frees */ |
---|
1379 | 1355 | xfs_dir2_data_off_t oldbest; /* old value of best free */ |
---|
1380 | 1356 | struct xfs_dir2_data_free *bf; /* bestfree table */ |
---|
1381 | | - struct xfs_dir2_leaf_entry *ents; |
---|
1382 | 1357 | struct xfs_dir3_icleaf_hdr leafhdr; |
---|
1383 | 1358 | |
---|
1384 | 1359 | trace_xfs_dir2_leaf_removename(args); |
---|
.. | .. |
---|
1386 | 1361 | /* |
---|
1387 | 1362 | * Lookup the leaf entry, get the leaf and data blocks read in. |
---|
1388 | 1363 | */ |
---|
1389 | | - if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { |
---|
| 1364 | + error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp, &leafhdr); |
---|
| 1365 | + if (error) |
---|
1390 | 1366 | return error; |
---|
1391 | | - } |
---|
| 1367 | + |
---|
1392 | 1368 | dp = args->dp; |
---|
1393 | 1369 | leaf = lbp->b_addr; |
---|
1394 | 1370 | hdr = dbp->b_addr; |
---|
1395 | 1371 | xfs_dir3_data_check(dp, dbp); |
---|
1396 | | - bf = dp->d_ops->data_bestfree_p(hdr); |
---|
1397 | | - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); |
---|
1398 | | - ents = dp->d_ops->leaf_ents_p(leaf); |
---|
| 1372 | + bf = xfs_dir2_data_bestfree_p(dp->i_mount, hdr); |
---|
| 1373 | + |
---|
1399 | 1374 | /* |
---|
1400 | 1375 | * Point to the leaf entry, use that to point to the data entry. |
---|
1401 | 1376 | */ |
---|
1402 | | - lep = &ents[index]; |
---|
1403 | | - db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address)); |
---|
| 1377 | + lep = &leafhdr.ents[index]; |
---|
| 1378 | + db = xfs_dir2_dataptr_to_db(geo, be32_to_cpu(lep->address)); |
---|
1404 | 1379 | dep = (xfs_dir2_data_entry_t *)((char *)hdr + |
---|
1405 | | - xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address))); |
---|
| 1380 | + xfs_dir2_dataptr_to_off(geo, be32_to_cpu(lep->address))); |
---|
1406 | 1381 | needscan = needlog = 0; |
---|
1407 | 1382 | oldbest = be16_to_cpu(bf[0].length); |
---|
1408 | | - ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); |
---|
| 1383 | + ltp = xfs_dir2_leaf_tail_p(geo, leaf); |
---|
1409 | 1384 | bestsp = xfs_dir2_leaf_bests_p(ltp); |
---|
1410 | | - if (be16_to_cpu(bestsp[db]) != oldbest) |
---|
| 1385 | + if (be16_to_cpu(bestsp[db]) != oldbest) { |
---|
| 1386 | + xfs_buf_mark_corrupt(lbp); |
---|
1411 | 1387 | return -EFSCORRUPTED; |
---|
| 1388 | + } |
---|
1412 | 1389 | /* |
---|
1413 | 1390 | * Mark the former data entry unused. |
---|
1414 | 1391 | */ |
---|
1415 | 1392 | xfs_dir2_data_make_free(args, dbp, |
---|
1416 | 1393 | (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr), |
---|
1417 | | - dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan); |
---|
| 1394 | + xfs_dir2_data_entsize(dp->i_mount, dep->namelen), &needlog, |
---|
| 1395 | + &needscan); |
---|
1418 | 1396 | /* |
---|
1419 | 1397 | * We just mark the leaf entry stale by putting a null in it. |
---|
1420 | 1398 | */ |
---|
1421 | 1399 | leafhdr.stale++; |
---|
1422 | | - dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); |
---|
| 1400 | + xfs_dir2_leaf_hdr_to_disk(dp->i_mount, leaf, &leafhdr); |
---|
1423 | 1401 | xfs_dir3_leaf_log_header(args, lbp); |
---|
1424 | 1402 | |
---|
1425 | 1403 | lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR); |
---|
1426 | | - xfs_dir3_leaf_log_ents(args, lbp, index, index); |
---|
| 1404 | + xfs_dir3_leaf_log_ents(args, &leafhdr, lbp, index, index); |
---|
1427 | 1405 | |
---|
1428 | 1406 | /* |
---|
1429 | 1407 | * Scan the freespace in the data block again if necessary, |
---|
1430 | 1408 | * log the data block header if necessary. |
---|
1431 | 1409 | */ |
---|
1432 | 1410 | if (needscan) |
---|
1433 | | - xfs_dir2_data_freescan(dp, hdr, &needlog); |
---|
| 1411 | + xfs_dir2_data_freescan(dp->i_mount, hdr, &needlog); |
---|
1434 | 1412 | if (needlog) |
---|
1435 | 1413 | xfs_dir2_data_log_header(args, dbp); |
---|
1436 | 1414 | /* |
---|
.. | .. |
---|
1446 | 1424 | * If the data block is now empty then get rid of the data block. |
---|
1447 | 1425 | */ |
---|
1448 | 1426 | if (be16_to_cpu(bf[0].length) == |
---|
1449 | | - args->geo->blksize - dp->d_ops->data_entry_offset) { |
---|
1450 | | - ASSERT(db != args->geo->datablk); |
---|
| 1427 | + geo->blksize - geo->data_entry_offset) { |
---|
| 1428 | + ASSERT(db != geo->datablk); |
---|
1451 | 1429 | if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { |
---|
1452 | 1430 | /* |
---|
1453 | 1431 | * Nope, can't get rid of it because it caused |
---|
.. | .. |
---|
1489 | 1467 | /* |
---|
1490 | 1468 | * If the data block was not the first one, drop it. |
---|
1491 | 1469 | */ |
---|
1492 | | - else if (db != args->geo->datablk) |
---|
| 1470 | + else if (db != geo->datablk) |
---|
1493 | 1471 | dbp = NULL; |
---|
1494 | 1472 | |
---|
1495 | 1473 | xfs_dir3_leaf_check(dp, lbp); |
---|
.. | .. |
---|
1512 | 1490 | int error; /* error return code */ |
---|
1513 | 1491 | int index; /* index of leaf entry */ |
---|
1514 | 1492 | struct xfs_buf *lbp; /* leaf buffer */ |
---|
1515 | | - xfs_dir2_leaf_t *leaf; /* leaf structure */ |
---|
1516 | 1493 | xfs_dir2_leaf_entry_t *lep; /* leaf entry */ |
---|
1517 | 1494 | xfs_trans_t *tp; /* transaction pointer */ |
---|
1518 | | - struct xfs_dir2_leaf_entry *ents; |
---|
| 1495 | + struct xfs_dir3_icleaf_hdr leafhdr; |
---|
1519 | 1496 | |
---|
1520 | 1497 | trace_xfs_dir2_leaf_replace(args); |
---|
1521 | 1498 | |
---|
1522 | 1499 | /* |
---|
1523 | 1500 | * Look up the entry. |
---|
1524 | 1501 | */ |
---|
1525 | | - if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) { |
---|
| 1502 | + error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp, &leafhdr); |
---|
| 1503 | + if (error) |
---|
1526 | 1504 | return error; |
---|
1527 | | - } |
---|
| 1505 | + |
---|
1528 | 1506 | dp = args->dp; |
---|
1529 | | - leaf = lbp->b_addr; |
---|
1530 | | - ents = dp->d_ops->leaf_ents_p(leaf); |
---|
1531 | 1507 | /* |
---|
1532 | 1508 | * Point to the leaf entry, get data address from it. |
---|
1533 | 1509 | */ |
---|
1534 | | - lep = &ents[index]; |
---|
| 1510 | + lep = &leafhdr.ents[index]; |
---|
1535 | 1511 | /* |
---|
1536 | 1512 | * Point to the data entry. |
---|
1537 | 1513 | */ |
---|
.. | .. |
---|
1543 | 1519 | * Put the new inode number in, log it. |
---|
1544 | 1520 | */ |
---|
1545 | 1521 | dep->inumber = cpu_to_be64(args->inumber); |
---|
1546 | | - dp->d_ops->data_put_ftype(dep, args->filetype); |
---|
| 1522 | + xfs_dir2_data_put_ftype(dp->i_mount, dep, args->filetype); |
---|
1547 | 1523 | tp = args->trans; |
---|
1548 | 1524 | xfs_dir2_data_log_entry(args, dbp, dep); |
---|
1549 | 1525 | xfs_dir3_leaf_check(dp, lbp); |
---|
.. | .. |
---|
1565 | 1541 | xfs_dahash_t hashwant; /* hash value looking for */ |
---|
1566 | 1542 | int high; /* high leaf index */ |
---|
1567 | 1543 | int low; /* low leaf index */ |
---|
1568 | | - xfs_dir2_leaf_t *leaf; /* leaf structure */ |
---|
1569 | 1544 | xfs_dir2_leaf_entry_t *lep; /* leaf entry */ |
---|
1570 | 1545 | int mid=0; /* current leaf index */ |
---|
1571 | | - struct xfs_dir2_leaf_entry *ents; |
---|
1572 | 1546 | struct xfs_dir3_icleaf_hdr leafhdr; |
---|
1573 | 1547 | |
---|
1574 | | - leaf = lbp->b_addr; |
---|
1575 | | - ents = args->dp->d_ops->leaf_ents_p(leaf); |
---|
1576 | | - args->dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); |
---|
| 1548 | + xfs_dir2_leaf_hdr_from_disk(args->dp->i_mount, &leafhdr, lbp->b_addr); |
---|
1577 | 1549 | |
---|
1578 | 1550 | /* |
---|
1579 | 1551 | * Note, the table cannot be empty, so we have to go through the loop. |
---|
1580 | 1552 | * Binary search the leaf entries looking for our hash value. |
---|
1581 | 1553 | */ |
---|
1582 | | - for (lep = ents, low = 0, high = leafhdr.count - 1, |
---|
| 1554 | + for (lep = leafhdr.ents, low = 0, high = leafhdr.count - 1, |
---|
1583 | 1555 | hashwant = args->hashval; |
---|
1584 | 1556 | low <= high; ) { |
---|
1585 | 1557 | mid = (low + high) >> 1; |
---|
.. | .. |
---|
1616 | 1588 | struct xfs_buf *lbp, /* leaf buffer */ |
---|
1617 | 1589 | xfs_dir2_db_t db) /* data block number */ |
---|
1618 | 1590 | { |
---|
| 1591 | + struct xfs_da_geometry *geo = args->geo; |
---|
1619 | 1592 | __be16 *bestsp; /* leaf bests table */ |
---|
1620 | 1593 | struct xfs_buf *dbp; /* data block buffer */ |
---|
1621 | 1594 | xfs_inode_t *dp; /* incore directory inode */ |
---|
.. | .. |
---|
1629 | 1602 | /* |
---|
1630 | 1603 | * Read the offending data block. We need its buffer. |
---|
1631 | 1604 | */ |
---|
1632 | | - error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(args->geo, db), |
---|
1633 | | - -1, &dbp); |
---|
| 1605 | + error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(geo, db), 0, &dbp); |
---|
1634 | 1606 | if (error) |
---|
1635 | 1607 | return error; |
---|
1636 | 1608 | |
---|
1637 | 1609 | leaf = lbp->b_addr; |
---|
1638 | | - ltp = xfs_dir2_leaf_tail_p(args->geo, leaf); |
---|
| 1610 | + ltp = xfs_dir2_leaf_tail_p(geo, leaf); |
---|
1639 | 1611 | |
---|
1640 | 1612 | #ifdef DEBUG |
---|
1641 | 1613 | { |
---|
1642 | 1614 | struct xfs_dir2_data_hdr *hdr = dbp->b_addr; |
---|
1643 | | - struct xfs_dir2_data_free *bf = dp->d_ops->data_bestfree_p(hdr); |
---|
| 1615 | + struct xfs_dir2_data_free *bf = |
---|
| 1616 | + xfs_dir2_data_bestfree_p(dp->i_mount, hdr); |
---|
1644 | 1617 | |
---|
1645 | 1618 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || |
---|
1646 | 1619 | hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC)); |
---|
1647 | 1620 | ASSERT(be16_to_cpu(bf[0].length) == |
---|
1648 | | - args->geo->blksize - dp->d_ops->data_entry_offset); |
---|
| 1621 | + geo->blksize - geo->data_entry_offset); |
---|
1649 | 1622 | ASSERT(db == be32_to_cpu(ltp->bestcount) - 1); |
---|
1650 | 1623 | } |
---|
1651 | 1624 | #endif |
---|
.. | .. |
---|
1703 | 1676 | int error; /* error return code */ |
---|
1704 | 1677 | struct xfs_buf *fbp; /* buffer for freespace block */ |
---|
1705 | 1678 | xfs_fileoff_t fo; /* freespace file offset */ |
---|
1706 | | - xfs_dir2_free_t *free; /* freespace structure */ |
---|
1707 | 1679 | struct xfs_buf *lbp; /* buffer for leaf block */ |
---|
1708 | 1680 | xfs_dir2_leaf_tail_t *ltp; /* tail of leaf structure */ |
---|
1709 | 1681 | xfs_dir2_leaf_t *leaf; /* leaf structure */ |
---|
.. | .. |
---|
1761 | 1733 | return 0; |
---|
1762 | 1734 | lbp = state->path.blk[0].bp; |
---|
1763 | 1735 | leaf = lbp->b_addr; |
---|
1764 | | - dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf); |
---|
| 1736 | + xfs_dir2_leaf_hdr_from_disk(mp, &leafhdr, leaf); |
---|
1765 | 1737 | |
---|
1766 | 1738 | ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC || |
---|
1767 | 1739 | leafhdr.magic == XFS_DIR3_LEAFN_MAGIC); |
---|
.. | .. |
---|
1772 | 1744 | error = xfs_dir2_free_read(tp, dp, args->geo->freeblk, &fbp); |
---|
1773 | 1745 | if (error) |
---|
1774 | 1746 | return error; |
---|
1775 | | - free = fbp->b_addr; |
---|
1776 | | - dp->d_ops->free_hdr_from_disk(&freehdr, free); |
---|
| 1747 | + xfs_dir2_free_hdr_from_disk(mp, &freehdr, fbp->b_addr); |
---|
1777 | 1748 | |
---|
1778 | 1749 | ASSERT(!freehdr.firstdb); |
---|
1779 | 1750 | |
---|
.. | .. |
---|
1807 | 1778 | /* |
---|
1808 | 1779 | * Set up the leaf bests table. |
---|
1809 | 1780 | */ |
---|
1810 | | - memcpy(xfs_dir2_leaf_bests_p(ltp), dp->d_ops->free_bests_p(free), |
---|
| 1781 | + memcpy(xfs_dir2_leaf_bests_p(ltp), freehdr.bests, |
---|
1811 | 1782 | freehdr.nvalid * sizeof(xfs_dir2_data_off_t)); |
---|
1812 | 1783 | |
---|
1813 | | - dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr); |
---|
| 1784 | + xfs_dir2_leaf_hdr_to_disk(mp, leaf, &leafhdr); |
---|
1814 | 1785 | xfs_dir3_leaf_log_header(args, lbp); |
---|
1815 | 1786 | xfs_dir3_leaf_log_bests(args, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); |
---|
1816 | 1787 | xfs_dir3_leaf_log_tail(args, lbp); |
---|