.. | .. |
---|
5 | 5 | */ |
---|
6 | 6 | #include "xfs.h" |
---|
7 | 7 | #include "xfs_fs.h" |
---|
| 8 | +#include "xfs_shared.h" |
---|
8 | 9 | #include "xfs_format.h" |
---|
9 | 10 | #include "xfs_log_format.h" |
---|
10 | 11 | #include "xfs_trans_resv.h" |
---|
11 | 12 | #include "xfs_mount.h" |
---|
12 | | -#include "xfs_da_format.h" |
---|
13 | | -#include "xfs_da_btree.h" |
---|
14 | 13 | #include "xfs_inode.h" |
---|
15 | 14 | #include "xfs_trans.h" |
---|
16 | | -#include "xfs_inode_item.h" |
---|
17 | | -#include "xfs_error.h" |
---|
18 | 15 | #include "xfs_dir2.h" |
---|
19 | 16 | #include "xfs_dir2_priv.h" |
---|
20 | 17 | #include "xfs_trace.h" |
---|
.. | .. |
---|
39 | 36 | |
---|
40 | 37 | static void xfs_dir2_sf_toino4(xfs_da_args_t *args); |
---|
41 | 38 | static void xfs_dir2_sf_toino8(xfs_da_args_t *args); |
---|
| 39 | + |
---|
| 40 | +int |
---|
| 41 | +xfs_dir2_sf_entsize( |
---|
| 42 | + struct xfs_mount *mp, |
---|
| 43 | + struct xfs_dir2_sf_hdr *hdr, |
---|
| 44 | + int len) |
---|
| 45 | +{ |
---|
| 46 | + int count = len; |
---|
| 47 | + |
---|
| 48 | + count += sizeof(struct xfs_dir2_sf_entry); /* namelen + offset */ |
---|
| 49 | + count += hdr->i8count ? XFS_INO64_SIZE : XFS_INO32_SIZE; /* ino # */ |
---|
| 50 | + |
---|
| 51 | + if (xfs_sb_version_hasftype(&mp->m_sb)) |
---|
| 52 | + count += sizeof(uint8_t); |
---|
| 53 | + return count; |
---|
| 54 | +} |
---|
| 55 | + |
---|
| 56 | +struct xfs_dir2_sf_entry * |
---|
| 57 | +xfs_dir2_sf_nextentry( |
---|
| 58 | + struct xfs_mount *mp, |
---|
| 59 | + struct xfs_dir2_sf_hdr *hdr, |
---|
| 60 | + struct xfs_dir2_sf_entry *sfep) |
---|
| 61 | +{ |
---|
| 62 | + return (void *)sfep + xfs_dir2_sf_entsize(mp, hdr, sfep->namelen); |
---|
| 63 | +} |
---|
| 64 | + |
---|
| 65 | +/* |
---|
| 66 | + * In short-form directory entries the inode numbers are stored at variable |
---|
| 67 | + * offset behind the entry name. If the entry stores a filetype value, then it |
---|
| 68 | + * sits between the name and the inode number. The actual inode numbers can |
---|
| 69 | + * come in two formats as well, either 4 bytes or 8 bytes wide. |
---|
| 70 | + */ |
---|
| 71 | +xfs_ino_t |
---|
| 72 | +xfs_dir2_sf_get_ino( |
---|
| 73 | + struct xfs_mount *mp, |
---|
| 74 | + struct xfs_dir2_sf_hdr *hdr, |
---|
| 75 | + struct xfs_dir2_sf_entry *sfep) |
---|
| 76 | +{ |
---|
| 77 | + uint8_t *from = sfep->name + sfep->namelen; |
---|
| 78 | + |
---|
| 79 | + if (xfs_sb_version_hasftype(&mp->m_sb)) |
---|
| 80 | + from++; |
---|
| 81 | + |
---|
| 82 | + if (!hdr->i8count) |
---|
| 83 | + return get_unaligned_be32(from); |
---|
| 84 | + return get_unaligned_be64(from) & XFS_MAXINUMBER; |
---|
| 85 | +} |
---|
| 86 | + |
---|
| 87 | +void |
---|
| 88 | +xfs_dir2_sf_put_ino( |
---|
| 89 | + struct xfs_mount *mp, |
---|
| 90 | + struct xfs_dir2_sf_hdr *hdr, |
---|
| 91 | + struct xfs_dir2_sf_entry *sfep, |
---|
| 92 | + xfs_ino_t ino) |
---|
| 93 | +{ |
---|
| 94 | + uint8_t *to = sfep->name + sfep->namelen; |
---|
| 95 | + |
---|
| 96 | + ASSERT(ino <= XFS_MAXINUMBER); |
---|
| 97 | + |
---|
| 98 | + if (xfs_sb_version_hasftype(&mp->m_sb)) |
---|
| 99 | + to++; |
---|
| 100 | + |
---|
| 101 | + if (hdr->i8count) |
---|
| 102 | + put_unaligned_be64(ino, to); |
---|
| 103 | + else |
---|
| 104 | + put_unaligned_be32(ino, to); |
---|
| 105 | +} |
---|
| 106 | + |
---|
| 107 | +xfs_ino_t |
---|
| 108 | +xfs_dir2_sf_get_parent_ino( |
---|
| 109 | + struct xfs_dir2_sf_hdr *hdr) |
---|
| 110 | +{ |
---|
| 111 | + if (!hdr->i8count) |
---|
| 112 | + return get_unaligned_be32(hdr->parent); |
---|
| 113 | + return get_unaligned_be64(hdr->parent) & XFS_MAXINUMBER; |
---|
| 114 | +} |
---|
| 115 | + |
---|
| 116 | +void |
---|
| 117 | +xfs_dir2_sf_put_parent_ino( |
---|
| 118 | + struct xfs_dir2_sf_hdr *hdr, |
---|
| 119 | + xfs_ino_t ino) |
---|
| 120 | +{ |
---|
| 121 | + ASSERT(ino <= XFS_MAXINUMBER); |
---|
| 122 | + |
---|
| 123 | + if (hdr->i8count) |
---|
| 124 | + put_unaligned_be64(ino, hdr->parent); |
---|
| 125 | + else |
---|
| 126 | + put_unaligned_be32(ino, hdr->parent); |
---|
| 127 | +} |
---|
| 128 | + |
---|
| 129 | +/* |
---|
| 130 | + * The file type field is stored at the end of the name for filetype enabled |
---|
| 131 | + * shortform directories, or not at all otherwise. |
---|
| 132 | + */ |
---|
| 133 | +uint8_t |
---|
| 134 | +xfs_dir2_sf_get_ftype( |
---|
| 135 | + struct xfs_mount *mp, |
---|
| 136 | + struct xfs_dir2_sf_entry *sfep) |
---|
| 137 | +{ |
---|
| 138 | + if (xfs_sb_version_hasftype(&mp->m_sb)) { |
---|
| 139 | + uint8_t ftype = sfep->name[sfep->namelen]; |
---|
| 140 | + |
---|
| 141 | + if (ftype < XFS_DIR3_FT_MAX) |
---|
| 142 | + return ftype; |
---|
| 143 | + } |
---|
| 144 | + |
---|
| 145 | + return XFS_DIR3_FT_UNKNOWN; |
---|
| 146 | +} |
---|
| 147 | + |
---|
| 148 | +void |
---|
| 149 | +xfs_dir2_sf_put_ftype( |
---|
| 150 | + struct xfs_mount *mp, |
---|
| 151 | + struct xfs_dir2_sf_entry *sfep, |
---|
| 152 | + uint8_t ftype) |
---|
| 153 | +{ |
---|
| 154 | + ASSERT(ftype < XFS_DIR3_FT_MAX); |
---|
| 155 | + |
---|
| 156 | + if (xfs_sb_version_hasftype(&mp->m_sb)) |
---|
| 157 | + sfep->name[sfep->namelen] = ftype; |
---|
| 158 | +} |
---|
42 | 159 | |
---|
43 | 160 | /* |
---|
44 | 161 | * Given a block directory (dp/block), calculate its size as a shortform (sf) |
---|
.. | .. |
---|
128 | 245 | */ |
---|
129 | 246 | sfhp->count = count; |
---|
130 | 247 | sfhp->i8count = i8count; |
---|
131 | | - dp->d_ops->sf_put_parent_ino(sfhp, parent); |
---|
| 248 | + xfs_dir2_sf_put_parent_ino(sfhp, parent); |
---|
132 | 249 | return size; |
---|
133 | 250 | } |
---|
134 | 251 | |
---|
.. | .. |
---|
138 | 255 | */ |
---|
139 | 256 | int /* error */ |
---|
140 | 257 | xfs_dir2_block_to_sf( |
---|
141 | | - xfs_da_args_t *args, /* operation arguments */ |
---|
| 258 | + struct xfs_da_args *args, /* operation arguments */ |
---|
142 | 259 | struct xfs_buf *bp, |
---|
143 | 260 | int size, /* shortform directory size */ |
---|
144 | | - xfs_dir2_sf_hdr_t *sfhp) /* shortform directory hdr */ |
---|
| 261 | + struct xfs_dir2_sf_hdr *sfhp) /* shortform directory hdr */ |
---|
145 | 262 | { |
---|
146 | | - xfs_dir2_data_hdr_t *hdr; /* block header */ |
---|
147 | | - xfs_dir2_data_entry_t *dep; /* data entry pointer */ |
---|
148 | | - xfs_inode_t *dp; /* incore directory inode */ |
---|
149 | | - xfs_dir2_data_unused_t *dup; /* unused data pointer */ |
---|
150 | | - char *endptr; /* end of data entries */ |
---|
| 263 | + struct xfs_inode *dp = args->dp; |
---|
| 264 | + struct xfs_mount *mp = dp->i_mount; |
---|
151 | 265 | int error; /* error return value */ |
---|
152 | 266 | int logflags; /* inode logging flags */ |
---|
153 | | - xfs_mount_t *mp; /* filesystem mount point */ |
---|
154 | | - char *ptr; /* current data pointer */ |
---|
155 | | - xfs_dir2_sf_entry_t *sfep; /* shortform entry */ |
---|
156 | | - xfs_dir2_sf_hdr_t *sfp; /* shortform directory header */ |
---|
157 | | - xfs_dir2_sf_hdr_t *dst; /* temporary data buffer */ |
---|
| 267 | + struct xfs_dir2_sf_entry *sfep; /* shortform entry */ |
---|
| 268 | + struct xfs_dir2_sf_hdr *sfp; /* shortform directory header */ |
---|
| 269 | + unsigned int offset = args->geo->data_entry_offset; |
---|
| 270 | + unsigned int end; |
---|
158 | 271 | |
---|
159 | 272 | trace_xfs_dir2_block_to_sf(args); |
---|
160 | 273 | |
---|
161 | | - dp = args->dp; |
---|
162 | | - mp = dp->i_mount; |
---|
163 | | - |
---|
164 | 274 | /* |
---|
165 | | - * allocate a temporary destination buffer the size of the inode |
---|
166 | | - * to format the data into. Once we have formatted the data, we |
---|
167 | | - * can free the block and copy the formatted data into the inode literal |
---|
168 | | - * area. |
---|
| 275 | + * Allocate a temporary destination buffer the size of the inode to |
---|
| 276 | + * format the data into. Once we have formatted the data, we can free |
---|
| 277 | + * the block and copy the formatted data into the inode literal area. |
---|
169 | 278 | */ |
---|
170 | | - dst = kmem_alloc(mp->m_sb.sb_inodesize, KM_SLEEP); |
---|
171 | | - hdr = bp->b_addr; |
---|
172 | | - |
---|
173 | | - /* |
---|
174 | | - * Copy the header into the newly allocate local space. |
---|
175 | | - */ |
---|
176 | | - sfp = (xfs_dir2_sf_hdr_t *)dst; |
---|
| 279 | + sfp = kmem_alloc(mp->m_sb.sb_inodesize, 0); |
---|
177 | 280 | memcpy(sfp, sfhp, xfs_dir2_sf_hdr_size(sfhp->i8count)); |
---|
178 | 281 | |
---|
179 | 282 | /* |
---|
180 | | - * Set up to loop over the block's entries. |
---|
| 283 | + * Loop over the active and unused entries. Stop when we reach the |
---|
| 284 | + * leaf/tail portion of the block. |
---|
181 | 285 | */ |
---|
182 | | - ptr = (char *)dp->d_ops->data_entry_p(hdr); |
---|
183 | | - endptr = xfs_dir3_data_endp(args->geo, hdr); |
---|
| 286 | + end = xfs_dir3_data_end_offset(args->geo, bp->b_addr); |
---|
184 | 287 | sfep = xfs_dir2_sf_firstentry(sfp); |
---|
185 | | - /* |
---|
186 | | - * Loop over the active and unused entries. |
---|
187 | | - * Stop when we reach the leaf/tail portion of the block. |
---|
188 | | - */ |
---|
189 | | - while (ptr < endptr) { |
---|
| 288 | + while (offset < end) { |
---|
| 289 | + struct xfs_dir2_data_unused *dup = bp->b_addr + offset; |
---|
| 290 | + struct xfs_dir2_data_entry *dep = bp->b_addr + offset; |
---|
| 291 | + |
---|
190 | 292 | /* |
---|
191 | 293 | * If it's unused, just skip over it. |
---|
192 | 294 | */ |
---|
193 | | - dup = (xfs_dir2_data_unused_t *)ptr; |
---|
194 | 295 | if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { |
---|
195 | | - ptr += be16_to_cpu(dup->length); |
---|
| 296 | + offset += be16_to_cpu(dup->length); |
---|
196 | 297 | continue; |
---|
197 | 298 | } |
---|
198 | | - dep = (xfs_dir2_data_entry_t *)ptr; |
---|
| 299 | + |
---|
199 | 300 | /* |
---|
200 | 301 | * Skip . |
---|
201 | 302 | */ |
---|
.. | .. |
---|
207 | 308 | else if (dep->namelen == 2 && |
---|
208 | 309 | dep->name[0] == '.' && dep->name[1] == '.') |
---|
209 | 310 | ASSERT(be64_to_cpu(dep->inumber) == |
---|
210 | | - dp->d_ops->sf_get_parent_ino(sfp)); |
---|
| 311 | + xfs_dir2_sf_get_parent_ino(sfp)); |
---|
211 | 312 | /* |
---|
212 | 313 | * Normal entry, copy it into shortform. |
---|
213 | 314 | */ |
---|
214 | 315 | else { |
---|
215 | 316 | sfep->namelen = dep->namelen; |
---|
216 | | - xfs_dir2_sf_put_offset(sfep, |
---|
217 | | - (xfs_dir2_data_aoff_t) |
---|
218 | | - ((char *)dep - (char *)hdr)); |
---|
| 317 | + xfs_dir2_sf_put_offset(sfep, offset); |
---|
219 | 318 | memcpy(sfep->name, dep->name, dep->namelen); |
---|
220 | | - dp->d_ops->sf_put_ino(sfp, sfep, |
---|
| 319 | + xfs_dir2_sf_put_ino(mp, sfp, sfep, |
---|
221 | 320 | be64_to_cpu(dep->inumber)); |
---|
222 | | - dp->d_ops->sf_put_ftype(sfep, |
---|
223 | | - dp->d_ops->data_get_ftype(dep)); |
---|
| 321 | + xfs_dir2_sf_put_ftype(mp, sfep, |
---|
| 322 | + xfs_dir2_data_get_ftype(mp, dep)); |
---|
224 | 323 | |
---|
225 | | - sfep = dp->d_ops->sf_nextentry(sfp, sfep); |
---|
| 324 | + sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); |
---|
226 | 325 | } |
---|
227 | | - ptr += dp->d_ops->data_entsize(dep->namelen); |
---|
| 326 | + offset += xfs_dir2_data_entsize(mp, dep->namelen); |
---|
228 | 327 | } |
---|
229 | 328 | ASSERT((char *)sfep - (char *)sfp == size); |
---|
230 | 329 | |
---|
.. | .. |
---|
243 | 342 | * Convert the inode to local format and copy the data in. |
---|
244 | 343 | */ |
---|
245 | 344 | ASSERT(dp->i_df.if_bytes == 0); |
---|
246 | | - xfs_init_local_fork(dp, XFS_DATA_FORK, dst, size); |
---|
247 | | - dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; |
---|
| 345 | + xfs_init_local_fork(dp, XFS_DATA_FORK, sfp, size); |
---|
| 346 | + dp->i_df.if_format = XFS_DINODE_FMT_LOCAL; |
---|
248 | 347 | dp->i_d.di_size = size; |
---|
249 | 348 | |
---|
250 | 349 | logflags |= XFS_ILOG_DDATA; |
---|
251 | 350 | xfs_dir2_sf_check(args); |
---|
252 | 351 | out: |
---|
253 | 352 | xfs_trans_log_inode(args->trans, dp, logflags); |
---|
254 | | - kmem_free(dst); |
---|
| 353 | + kmem_free(sfp); |
---|
255 | 354 | return error; |
---|
256 | 355 | } |
---|
257 | 356 | |
---|
.. | .. |
---|
280 | 379 | ASSERT(xfs_dir2_sf_lookup(args) == -ENOENT); |
---|
281 | 380 | dp = args->dp; |
---|
282 | 381 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); |
---|
283 | | - /* |
---|
284 | | - * Make sure the shortform value has some of its header. |
---|
285 | | - */ |
---|
286 | | - if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { |
---|
287 | | - ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); |
---|
288 | | - return -EIO; |
---|
289 | | - } |
---|
| 382 | + ASSERT(dp->i_d.di_size >= offsetof(struct xfs_dir2_sf_hdr, parent)); |
---|
290 | 383 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); |
---|
291 | 384 | ASSERT(dp->i_df.if_u1.if_data != NULL); |
---|
292 | 385 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
---|
.. | .. |
---|
294 | 387 | /* |
---|
295 | 388 | * Compute entry (and change in) size. |
---|
296 | 389 | */ |
---|
297 | | - incr_isize = dp->d_ops->sf_entsize(sfp, args->namelen); |
---|
| 390 | + incr_isize = xfs_dir2_sf_entsize(dp->i_mount, sfp, args->namelen); |
---|
298 | 391 | objchange = 0; |
---|
299 | 392 | |
---|
300 | 393 | /* |
---|
.. | .. |
---|
367 | 460 | xfs_dir2_data_aoff_t offset, /* offset to use for new ent */ |
---|
368 | 461 | int new_isize) /* new directory size */ |
---|
369 | 462 | { |
---|
| 463 | + struct xfs_inode *dp = args->dp; |
---|
| 464 | + struct xfs_mount *mp = dp->i_mount; |
---|
370 | 465 | int byteoff; /* byte offset in sf dir */ |
---|
371 | | - xfs_inode_t *dp; /* incore directory inode */ |
---|
372 | 466 | xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ |
---|
373 | | - |
---|
374 | | - dp = args->dp; |
---|
375 | 467 | |
---|
376 | 468 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
---|
377 | 469 | byteoff = (int)((char *)sfep - (char *)sfp); |
---|
378 | 470 | /* |
---|
379 | 471 | * Grow the in-inode space. |
---|
380 | 472 | */ |
---|
381 | | - xfs_idata_realloc(dp, dp->d_ops->sf_entsize(sfp, args->namelen), |
---|
| 473 | + xfs_idata_realloc(dp, xfs_dir2_sf_entsize(mp, sfp, args->namelen), |
---|
382 | 474 | XFS_DATA_FORK); |
---|
383 | 475 | /* |
---|
384 | 476 | * Need to set up again due to realloc of the inode data. |
---|
.. | .. |
---|
391 | 483 | sfep->namelen = args->namelen; |
---|
392 | 484 | xfs_dir2_sf_put_offset(sfep, offset); |
---|
393 | 485 | memcpy(sfep->name, args->name, sfep->namelen); |
---|
394 | | - dp->d_ops->sf_put_ino(sfp, sfep, args->inumber); |
---|
395 | | - dp->d_ops->sf_put_ftype(sfep, args->filetype); |
---|
| 486 | + xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber); |
---|
| 487 | + xfs_dir2_sf_put_ftype(mp, sfep, args->filetype); |
---|
396 | 488 | |
---|
397 | 489 | /* |
---|
398 | 490 | * Update the header and inode. |
---|
.. | .. |
---|
419 | 511 | int objchange, /* changing inode number size */ |
---|
420 | 512 | int new_isize) /* new directory size */ |
---|
421 | 513 | { |
---|
| 514 | + struct xfs_inode *dp = args->dp; |
---|
| 515 | + struct xfs_mount *mp = dp->i_mount; |
---|
422 | 516 | int add_datasize; /* data size need for new ent */ |
---|
423 | 517 | char *buf; /* buffer for old */ |
---|
424 | | - xfs_inode_t *dp; /* incore directory inode */ |
---|
425 | 518 | int eof; /* reached end of old dir */ |
---|
426 | 519 | int nbytes; /* temp for byte copies */ |
---|
427 | 520 | xfs_dir2_data_aoff_t new_offset; /* next offset value */ |
---|
.. | .. |
---|
435 | 528 | /* |
---|
436 | 529 | * Copy the old directory to the stack buffer. |
---|
437 | 530 | */ |
---|
438 | | - dp = args->dp; |
---|
439 | | - |
---|
440 | 531 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
---|
441 | 532 | old_isize = (int)dp->i_d.di_size; |
---|
442 | | - buf = kmem_alloc(old_isize, KM_SLEEP); |
---|
| 533 | + buf = kmem_alloc(old_isize, 0); |
---|
443 | 534 | oldsfp = (xfs_dir2_sf_hdr_t *)buf; |
---|
444 | 535 | memcpy(oldsfp, sfp, old_isize); |
---|
445 | 536 | /* |
---|
.. | .. |
---|
447 | 538 | * to insert the new entry. |
---|
448 | 539 | * If it's going to end up at the end then oldsfep will point there. |
---|
449 | 540 | */ |
---|
450 | | - for (offset = dp->d_ops->data_first_offset, |
---|
| 541 | + for (offset = args->geo->data_first_offset, |
---|
451 | 542 | oldsfep = xfs_dir2_sf_firstentry(oldsfp), |
---|
452 | | - add_datasize = dp->d_ops->data_entsize(args->namelen), |
---|
| 543 | + add_datasize = xfs_dir2_data_entsize(mp, args->namelen), |
---|
453 | 544 | eof = (char *)oldsfep == &buf[old_isize]; |
---|
454 | 545 | !eof; |
---|
455 | | - offset = new_offset + dp->d_ops->data_entsize(oldsfep->namelen), |
---|
456 | | - oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep), |
---|
| 546 | + offset = new_offset + xfs_dir2_data_entsize(mp, oldsfep->namelen), |
---|
| 547 | + oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep), |
---|
457 | 548 | eof = (char *)oldsfep == &buf[old_isize]) { |
---|
458 | 549 | new_offset = xfs_dir2_sf_get_offset(oldsfep); |
---|
459 | 550 | if (offset + add_datasize <= new_offset) |
---|
.. | .. |
---|
482 | 573 | sfep->namelen = args->namelen; |
---|
483 | 574 | xfs_dir2_sf_put_offset(sfep, offset); |
---|
484 | 575 | memcpy(sfep->name, args->name, sfep->namelen); |
---|
485 | | - dp->d_ops->sf_put_ino(sfp, sfep, args->inumber); |
---|
486 | | - dp->d_ops->sf_put_ftype(sfep, args->filetype); |
---|
| 576 | + xfs_dir2_sf_put_ino(mp, sfp, sfep, args->inumber); |
---|
| 577 | + xfs_dir2_sf_put_ftype(mp, sfep, args->filetype); |
---|
487 | 578 | sfp->count++; |
---|
488 | 579 | if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange) |
---|
489 | 580 | sfp->i8count++; |
---|
.. | .. |
---|
491 | 582 | * If there's more left to copy, do that. |
---|
492 | 583 | */ |
---|
493 | 584 | if (!eof) { |
---|
494 | | - sfep = dp->d_ops->sf_nextentry(sfp, sfep); |
---|
| 585 | + sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); |
---|
495 | 586 | memcpy(sfep, oldsfep, old_isize - nbytes); |
---|
496 | 587 | } |
---|
497 | 588 | kmem_free(buf); |
---|
.. | .. |
---|
513 | 604 | xfs_dir2_sf_entry_t **sfepp, /* out(1): new entry ptr */ |
---|
514 | 605 | xfs_dir2_data_aoff_t *offsetp) /* out(1): new offset */ |
---|
515 | 606 | { |
---|
516 | | - xfs_inode_t *dp; /* incore directory inode */ |
---|
| 607 | + struct xfs_inode *dp = args->dp; |
---|
| 608 | + struct xfs_mount *mp = dp->i_mount; |
---|
517 | 609 | int holefit; /* found hole it will fit in */ |
---|
518 | 610 | int i; /* entry number */ |
---|
519 | 611 | xfs_dir2_data_aoff_t offset; /* data block offset */ |
---|
.. | .. |
---|
522 | 614 | int size; /* entry's data size */ |
---|
523 | 615 | int used; /* data bytes used */ |
---|
524 | 616 | |
---|
525 | | - dp = args->dp; |
---|
526 | | - |
---|
527 | 617 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
---|
528 | | - size = dp->d_ops->data_entsize(args->namelen); |
---|
529 | | - offset = dp->d_ops->data_first_offset; |
---|
| 618 | + size = xfs_dir2_data_entsize(mp, args->namelen); |
---|
| 619 | + offset = args->geo->data_first_offset; |
---|
530 | 620 | sfep = xfs_dir2_sf_firstentry(sfp); |
---|
531 | 621 | holefit = 0; |
---|
532 | 622 | /* |
---|
.. | .. |
---|
538 | 628 | if (!holefit) |
---|
539 | 629 | holefit = offset + size <= xfs_dir2_sf_get_offset(sfep); |
---|
540 | 630 | offset = xfs_dir2_sf_get_offset(sfep) + |
---|
541 | | - dp->d_ops->data_entsize(sfep->namelen); |
---|
542 | | - sfep = dp->d_ops->sf_nextentry(sfp, sfep); |
---|
| 631 | + xfs_dir2_data_entsize(mp, sfep->namelen); |
---|
| 632 | + sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); |
---|
543 | 633 | } |
---|
544 | 634 | /* |
---|
545 | 635 | * Calculate data bytes used excluding the new entry, if this |
---|
.. | .. |
---|
581 | 671 | xfs_dir2_sf_check( |
---|
582 | 672 | xfs_da_args_t *args) /* operation arguments */ |
---|
583 | 673 | { |
---|
584 | | - xfs_inode_t *dp; /* incore directory inode */ |
---|
| 674 | + struct xfs_inode *dp = args->dp; |
---|
| 675 | + struct xfs_mount *mp = dp->i_mount; |
---|
585 | 676 | int i; /* entry number */ |
---|
586 | 677 | int i8count; /* number of big inode#s */ |
---|
587 | 678 | xfs_ino_t ino; /* entry inode number */ |
---|
.. | .. |
---|
589 | 680 | xfs_dir2_sf_entry_t *sfep; /* shortform dir entry */ |
---|
590 | 681 | xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ |
---|
591 | 682 | |
---|
592 | | - dp = args->dp; |
---|
593 | | - |
---|
594 | 683 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
---|
595 | | - offset = dp->d_ops->data_first_offset; |
---|
596 | | - ino = dp->d_ops->sf_get_parent_ino(sfp); |
---|
| 684 | + offset = args->geo->data_first_offset; |
---|
| 685 | + ino = xfs_dir2_sf_get_parent_ino(sfp); |
---|
597 | 686 | i8count = ino > XFS_DIR2_MAX_SHORT_INUM; |
---|
598 | 687 | |
---|
599 | 688 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); |
---|
600 | 689 | i < sfp->count; |
---|
601 | | - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { |
---|
| 690 | + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) { |
---|
602 | 691 | ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset); |
---|
603 | | - ino = dp->d_ops->sf_get_ino(sfp, sfep); |
---|
| 692 | + ino = xfs_dir2_sf_get_ino(mp, sfp, sfep); |
---|
604 | 693 | i8count += ino > XFS_DIR2_MAX_SHORT_INUM; |
---|
605 | 694 | offset = |
---|
606 | 695 | xfs_dir2_sf_get_offset(sfep) + |
---|
607 | | - dp->d_ops->data_entsize(sfep->namelen); |
---|
608 | | - ASSERT(dp->d_ops->sf_get_ftype(sfep) < XFS_DIR3_FT_MAX); |
---|
| 696 | + xfs_dir2_data_entsize(mp, sfep->namelen); |
---|
| 697 | + ASSERT(xfs_dir2_sf_get_ftype(mp, sfep) < XFS_DIR3_FT_MAX); |
---|
609 | 698 | } |
---|
610 | 699 | ASSERT(i8count == sfp->i8count); |
---|
611 | 700 | ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size); |
---|
.. | .. |
---|
621 | 710 | struct xfs_inode *ip) |
---|
622 | 711 | { |
---|
623 | 712 | struct xfs_mount *mp = ip->i_mount; |
---|
| 713 | + struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); |
---|
624 | 714 | struct xfs_dir2_sf_hdr *sfp; |
---|
625 | 715 | struct xfs_dir2_sf_entry *sfep; |
---|
626 | 716 | struct xfs_dir2_sf_entry *next_sfep; |
---|
627 | 717 | char *endp; |
---|
628 | | - const struct xfs_dir_ops *dops; |
---|
629 | | - struct xfs_ifork *ifp; |
---|
630 | 718 | xfs_ino_t ino; |
---|
631 | 719 | int i; |
---|
632 | 720 | int i8count; |
---|
633 | 721 | int offset; |
---|
634 | | - int size; |
---|
| 722 | + int64_t size; |
---|
635 | 723 | int error; |
---|
636 | 724 | uint8_t filetype; |
---|
637 | 725 | |
---|
638 | | - ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_LOCAL); |
---|
639 | | - /* |
---|
640 | | - * xfs_iread calls us before xfs_setup_inode sets up ip->d_ops, |
---|
641 | | - * so we can only trust the mountpoint to have the right pointer. |
---|
642 | | - */ |
---|
643 | | - dops = xfs_dir_get_ops(mp, NULL); |
---|
| 726 | + ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL); |
---|
644 | 727 | |
---|
645 | | - ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); |
---|
646 | 728 | sfp = (struct xfs_dir2_sf_hdr *)ifp->if_u1.if_data; |
---|
647 | 729 | size = ifp->if_bytes; |
---|
648 | 730 | |
---|
.. | .. |
---|
656 | 738 | endp = (char *)sfp + size; |
---|
657 | 739 | |
---|
658 | 740 | /* Check .. entry */ |
---|
659 | | - ino = dops->sf_get_parent_ino(sfp); |
---|
| 741 | + ino = xfs_dir2_sf_get_parent_ino(sfp); |
---|
660 | 742 | i8count = ino > XFS_DIR2_MAX_SHORT_INUM; |
---|
661 | 743 | error = xfs_dir_ino_validate(mp, ino); |
---|
662 | 744 | if (error) |
---|
663 | 745 | return __this_address; |
---|
664 | | - offset = dops->data_first_offset; |
---|
| 746 | + offset = mp->m_dir_geo->data_first_offset; |
---|
665 | 747 | |
---|
666 | 748 | /* Check all reported entries */ |
---|
667 | 749 | sfep = xfs_dir2_sf_firstentry(sfp); |
---|
.. | .. |
---|
683 | 765 | * within the data buffer. The next entry starts after the |
---|
684 | 766 | * name component, so nextentry is an acceptable test. |
---|
685 | 767 | */ |
---|
686 | | - next_sfep = dops->sf_nextentry(sfp, sfep); |
---|
| 768 | + next_sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep); |
---|
687 | 769 | if (endp < (char *)next_sfep) |
---|
688 | 770 | return __this_address; |
---|
689 | 771 | |
---|
.. | .. |
---|
692 | 774 | return __this_address; |
---|
693 | 775 | |
---|
694 | 776 | /* Check the inode number. */ |
---|
695 | | - ino = dops->sf_get_ino(sfp, sfep); |
---|
| 777 | + ino = xfs_dir2_sf_get_ino(mp, sfp, sfep); |
---|
696 | 778 | i8count += ino > XFS_DIR2_MAX_SHORT_INUM; |
---|
697 | 779 | error = xfs_dir_ino_validate(mp, ino); |
---|
698 | 780 | if (error) |
---|
699 | 781 | return __this_address; |
---|
700 | 782 | |
---|
701 | 783 | /* Check the file type. */ |
---|
702 | | - filetype = dops->sf_get_ftype(sfep); |
---|
| 784 | + filetype = xfs_dir2_sf_get_ftype(mp, sfep); |
---|
703 | 785 | if (filetype >= XFS_DIR3_FT_MAX) |
---|
704 | 786 | return __this_address; |
---|
705 | 787 | |
---|
706 | 788 | offset = xfs_dir2_sf_get_offset(sfep) + |
---|
707 | | - dops->data_entsize(sfep->namelen); |
---|
| 789 | + xfs_dir2_data_entsize(mp, sfep->namelen); |
---|
708 | 790 | |
---|
709 | 791 | sfep = next_sfep; |
---|
710 | 792 | } |
---|
.. | .. |
---|
744 | 826 | * If it's currently a zero-length extent file, |
---|
745 | 827 | * convert it to local format. |
---|
746 | 828 | */ |
---|
747 | | - if (dp->i_d.di_format == XFS_DINODE_FMT_EXTENTS) { |
---|
| 829 | + if (dp->i_df.if_format == XFS_DINODE_FMT_EXTENTS) { |
---|
748 | 830 | dp->i_df.if_flags &= ~XFS_IFEXTENTS; /* just in case */ |
---|
749 | | - dp->i_d.di_format = XFS_DINODE_FMT_LOCAL; |
---|
| 831 | + dp->i_df.if_format = XFS_DINODE_FMT_LOCAL; |
---|
750 | 832 | xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE); |
---|
751 | 833 | dp->i_df.if_flags |= XFS_IFINLINE; |
---|
752 | 834 | } |
---|
.. | .. |
---|
766 | 848 | /* |
---|
767 | 849 | * Now can put in the inode number, since i8count is set. |
---|
768 | 850 | */ |
---|
769 | | - dp->d_ops->sf_put_parent_ino(sfp, pino); |
---|
| 851 | + xfs_dir2_sf_put_parent_ino(sfp, pino); |
---|
770 | 852 | sfp->count = 0; |
---|
771 | 853 | dp->i_d.di_size = size; |
---|
772 | 854 | xfs_dir2_sf_check(args); |
---|
.. | .. |
---|
782 | 864 | xfs_dir2_sf_lookup( |
---|
783 | 865 | xfs_da_args_t *args) /* operation arguments */ |
---|
784 | 866 | { |
---|
785 | | - xfs_inode_t *dp; /* incore directory inode */ |
---|
| 867 | + struct xfs_inode *dp = args->dp; |
---|
| 868 | + struct xfs_mount *mp = dp->i_mount; |
---|
786 | 869 | int i; /* entry index */ |
---|
787 | 870 | int error; |
---|
788 | 871 | xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ |
---|
.. | .. |
---|
793 | 876 | trace_xfs_dir2_sf_lookup(args); |
---|
794 | 877 | |
---|
795 | 878 | xfs_dir2_sf_check(args); |
---|
796 | | - dp = args->dp; |
---|
797 | 879 | |
---|
798 | 880 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); |
---|
799 | | - /* |
---|
800 | | - * Bail out if the directory is way too short. |
---|
801 | | - */ |
---|
802 | | - if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { |
---|
803 | | - ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); |
---|
804 | | - return -EIO; |
---|
805 | | - } |
---|
| 881 | + ASSERT(dp->i_d.di_size >= offsetof(struct xfs_dir2_sf_hdr, parent)); |
---|
806 | 882 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); |
---|
807 | 883 | ASSERT(dp->i_df.if_u1.if_data != NULL); |
---|
808 | 884 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
---|
.. | .. |
---|
821 | 897 | */ |
---|
822 | 898 | if (args->namelen == 2 && |
---|
823 | 899 | args->name[0] == '.' && args->name[1] == '.') { |
---|
824 | | - args->inumber = dp->d_ops->sf_get_parent_ino(sfp); |
---|
| 900 | + args->inumber = xfs_dir2_sf_get_parent_ino(sfp); |
---|
825 | 901 | args->cmpresult = XFS_CMP_EXACT; |
---|
826 | 902 | args->filetype = XFS_DIR3_FT_DIR; |
---|
827 | 903 | return -EEXIST; |
---|
.. | .. |
---|
831 | 907 | */ |
---|
832 | 908 | ci_sfep = NULL; |
---|
833 | 909 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; |
---|
834 | | - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { |
---|
| 910 | + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) { |
---|
835 | 911 | /* |
---|
836 | 912 | * Compare name and if it's an exact match, return the inode |
---|
837 | 913 | * number. If it's the first case-insensitive match, store the |
---|
838 | 914 | * inode number and continue looking for an exact match. |
---|
839 | 915 | */ |
---|
840 | | - cmp = dp->i_mount->m_dirnameops->compname(args, sfep->name, |
---|
841 | | - sfep->namelen); |
---|
| 916 | + cmp = xfs_dir2_compname(args, sfep->name, sfep->namelen); |
---|
842 | 917 | if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { |
---|
843 | 918 | args->cmpresult = cmp; |
---|
844 | | - args->inumber = dp->d_ops->sf_get_ino(sfp, sfep); |
---|
845 | | - args->filetype = dp->d_ops->sf_get_ftype(sfep); |
---|
| 919 | + args->inumber = xfs_dir2_sf_get_ino(mp, sfp, sfep); |
---|
| 920 | + args->filetype = xfs_dir2_sf_get_ftype(mp, sfep); |
---|
846 | 921 | if (cmp == XFS_CMP_EXACT) |
---|
847 | 922 | return -EEXIST; |
---|
848 | 923 | ci_sfep = sfep; |
---|
.. | .. |
---|
867 | 942 | xfs_dir2_sf_removename( |
---|
868 | 943 | xfs_da_args_t *args) |
---|
869 | 944 | { |
---|
| 945 | + struct xfs_inode *dp = args->dp; |
---|
| 946 | + struct xfs_mount *mp = dp->i_mount; |
---|
870 | 947 | int byteoff; /* offset of removed entry */ |
---|
871 | | - xfs_inode_t *dp; /* incore directory inode */ |
---|
872 | 948 | int entsize; /* this entry's size */ |
---|
873 | 949 | int i; /* shortform entry index */ |
---|
874 | 950 | int newsize; /* new inode size */ |
---|
.. | .. |
---|
878 | 954 | |
---|
879 | 955 | trace_xfs_dir2_sf_removename(args); |
---|
880 | 956 | |
---|
881 | | - dp = args->dp; |
---|
882 | | - |
---|
883 | 957 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); |
---|
884 | 958 | oldsize = (int)dp->i_d.di_size; |
---|
885 | | - /* |
---|
886 | | - * Bail out if the directory is way too short. |
---|
887 | | - */ |
---|
888 | | - if (oldsize < offsetof(xfs_dir2_sf_hdr_t, parent)) { |
---|
889 | | - ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); |
---|
890 | | - return -EIO; |
---|
891 | | - } |
---|
| 959 | + ASSERT(oldsize >= offsetof(struct xfs_dir2_sf_hdr, parent)); |
---|
892 | 960 | ASSERT(dp->i_df.if_bytes == oldsize); |
---|
893 | 961 | ASSERT(dp->i_df.if_u1.if_data != NULL); |
---|
894 | 962 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
---|
.. | .. |
---|
898 | 966 | * Find the one we're deleting. |
---|
899 | 967 | */ |
---|
900 | 968 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; |
---|
901 | | - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { |
---|
| 969 | + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) { |
---|
902 | 970 | if (xfs_da_compname(args, sfep->name, sfep->namelen) == |
---|
903 | 971 | XFS_CMP_EXACT) { |
---|
904 | | - ASSERT(dp->d_ops->sf_get_ino(sfp, sfep) == |
---|
| 972 | + ASSERT(xfs_dir2_sf_get_ino(mp, sfp, sfep) == |
---|
905 | 973 | args->inumber); |
---|
906 | 974 | break; |
---|
907 | 975 | } |
---|
.. | .. |
---|
915 | 983 | * Calculate sizes. |
---|
916 | 984 | */ |
---|
917 | 985 | byteoff = (int)((char *)sfep - (char *)sfp); |
---|
918 | | - entsize = dp->d_ops->sf_entsize(sfp, args->namelen); |
---|
| 986 | + entsize = xfs_dir2_sf_entsize(mp, sfp, args->namelen); |
---|
919 | 987 | newsize = oldsize - entsize; |
---|
920 | 988 | /* |
---|
921 | 989 | * Copy the part if any after the removed entry, sliding it down. |
---|
.. | .. |
---|
948 | 1016 | } |
---|
949 | 1017 | |
---|
950 | 1018 | /* |
---|
| 1019 | + * Check whether the sf dir replace operation need more blocks. |
---|
| 1020 | + */ |
---|
| 1021 | +static bool |
---|
| 1022 | +xfs_dir2_sf_replace_needblock( |
---|
| 1023 | + struct xfs_inode *dp, |
---|
| 1024 | + xfs_ino_t inum) |
---|
| 1025 | +{ |
---|
| 1026 | + int newsize; |
---|
| 1027 | + struct xfs_dir2_sf_hdr *sfp; |
---|
| 1028 | + |
---|
| 1029 | + if (dp->i_df.if_format != XFS_DINODE_FMT_LOCAL) |
---|
| 1030 | + return false; |
---|
| 1031 | + |
---|
| 1032 | + sfp = (struct xfs_dir2_sf_hdr *)dp->i_df.if_u1.if_data; |
---|
| 1033 | + newsize = dp->i_df.if_bytes + (sfp->count + 1) * XFS_INO64_DIFF; |
---|
| 1034 | + |
---|
| 1035 | + return inum > XFS_DIR2_MAX_SHORT_INUM && |
---|
| 1036 | + sfp->i8count == 0 && newsize > XFS_IFORK_DSIZE(dp); |
---|
| 1037 | +} |
---|
| 1038 | + |
---|
| 1039 | +/* |
---|
951 | 1040 | * Replace the inode number of an entry in a shortform directory. |
---|
952 | 1041 | */ |
---|
953 | 1042 | int /* error */ |
---|
954 | 1043 | xfs_dir2_sf_replace( |
---|
955 | 1044 | xfs_da_args_t *args) /* operation arguments */ |
---|
956 | 1045 | { |
---|
957 | | - xfs_inode_t *dp; /* incore directory inode */ |
---|
| 1046 | + struct xfs_inode *dp = args->dp; |
---|
| 1047 | + struct xfs_mount *mp = dp->i_mount; |
---|
958 | 1048 | int i; /* entry index */ |
---|
959 | 1049 | xfs_ino_t ino=0; /* entry old inode number */ |
---|
960 | 1050 | int i8elevated; /* sf_toino8 set i8count=1 */ |
---|
.. | .. |
---|
963 | 1053 | |
---|
964 | 1054 | trace_xfs_dir2_sf_replace(args); |
---|
965 | 1055 | |
---|
966 | | - dp = args->dp; |
---|
967 | | - |
---|
968 | 1056 | ASSERT(dp->i_df.if_flags & XFS_IFINLINE); |
---|
969 | | - /* |
---|
970 | | - * Bail out if the shortform directory is way too small. |
---|
971 | | - */ |
---|
972 | | - if (dp->i_d.di_size < offsetof(xfs_dir2_sf_hdr_t, parent)) { |
---|
973 | | - ASSERT(XFS_FORCED_SHUTDOWN(dp->i_mount)); |
---|
974 | | - return -EIO; |
---|
975 | | - } |
---|
| 1057 | + ASSERT(dp->i_d.di_size >= offsetof(struct xfs_dir2_sf_hdr, parent)); |
---|
976 | 1058 | ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); |
---|
977 | 1059 | ASSERT(dp->i_df.if_u1.if_data != NULL); |
---|
978 | 1060 | sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
---|
.. | .. |
---|
983 | 1065 | */ |
---|
984 | 1066 | if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->i8count == 0) { |
---|
985 | 1067 | int error; /* error return value */ |
---|
986 | | - int newsize; /* new inode size */ |
---|
987 | 1068 | |
---|
988 | | - newsize = dp->i_df.if_bytes + (sfp->count + 1) * XFS_INO64_DIFF; |
---|
989 | 1069 | /* |
---|
990 | 1070 | * Won't fit as shortform, convert to block then do replace. |
---|
991 | 1071 | */ |
---|
992 | | - if (newsize > XFS_IFORK_DSIZE(dp)) { |
---|
| 1072 | + if (xfs_dir2_sf_replace_needblock(dp, args->inumber)) { |
---|
993 | 1073 | error = xfs_dir2_sf_to_block(args); |
---|
994 | | - if (error) { |
---|
| 1074 | + if (error) |
---|
995 | 1075 | return error; |
---|
996 | | - } |
---|
997 | 1076 | return xfs_dir2_block_replace(args); |
---|
998 | 1077 | } |
---|
999 | 1078 | /* |
---|
.. | .. |
---|
1011 | 1090 | */ |
---|
1012 | 1091 | if (args->namelen == 2 && |
---|
1013 | 1092 | args->name[0] == '.' && args->name[1] == '.') { |
---|
1014 | | - ino = dp->d_ops->sf_get_parent_ino(sfp); |
---|
| 1093 | + ino = xfs_dir2_sf_get_parent_ino(sfp); |
---|
1015 | 1094 | ASSERT(args->inumber != ino); |
---|
1016 | | - dp->d_ops->sf_put_parent_ino(sfp, args->inumber); |
---|
| 1095 | + xfs_dir2_sf_put_parent_ino(sfp, args->inumber); |
---|
1017 | 1096 | } |
---|
1018 | 1097 | /* |
---|
1019 | 1098 | * Normal entry, look for the name. |
---|
1020 | 1099 | */ |
---|
1021 | 1100 | else { |
---|
1022 | 1101 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; |
---|
1023 | | - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep)) { |
---|
| 1102 | + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep)) { |
---|
1024 | 1103 | if (xfs_da_compname(args, sfep->name, sfep->namelen) == |
---|
1025 | 1104 | XFS_CMP_EXACT) { |
---|
1026 | | - ino = dp->d_ops->sf_get_ino(sfp, sfep); |
---|
| 1105 | + ino = xfs_dir2_sf_get_ino(mp, sfp, sfep); |
---|
1027 | 1106 | ASSERT(args->inumber != ino); |
---|
1028 | | - dp->d_ops->sf_put_ino(sfp, sfep, args->inumber); |
---|
1029 | | - dp->d_ops->sf_put_ftype(sfep, args->filetype); |
---|
| 1107 | + xfs_dir2_sf_put_ino(mp, sfp, sfep, |
---|
| 1108 | + args->inumber); |
---|
| 1109 | + xfs_dir2_sf_put_ftype(mp, sfep, args->filetype); |
---|
1030 | 1110 | break; |
---|
1031 | 1111 | } |
---|
1032 | 1112 | } |
---|
.. | .. |
---|
1079 | 1159 | xfs_dir2_sf_toino4( |
---|
1080 | 1160 | xfs_da_args_t *args) /* operation arguments */ |
---|
1081 | 1161 | { |
---|
| 1162 | + struct xfs_inode *dp = args->dp; |
---|
| 1163 | + struct xfs_mount *mp = dp->i_mount; |
---|
1082 | 1164 | char *buf; /* old dir's buffer */ |
---|
1083 | | - xfs_inode_t *dp; /* incore directory inode */ |
---|
1084 | 1165 | int i; /* entry index */ |
---|
1085 | 1166 | int newsize; /* new inode size */ |
---|
1086 | 1167 | xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ |
---|
.. | .. |
---|
1091 | 1172 | |
---|
1092 | 1173 | trace_xfs_dir2_sf_toino4(args); |
---|
1093 | 1174 | |
---|
1094 | | - dp = args->dp; |
---|
1095 | | - |
---|
1096 | 1175 | /* |
---|
1097 | 1176 | * Copy the old directory to the buffer. |
---|
1098 | 1177 | * Then nuke it from the inode, and add the new buffer to the inode. |
---|
1099 | 1178 | * Don't want xfs_idata_realloc copying the data here. |
---|
1100 | 1179 | */ |
---|
1101 | 1180 | oldsize = dp->i_df.if_bytes; |
---|
1102 | | - buf = kmem_alloc(oldsize, KM_SLEEP); |
---|
| 1181 | + buf = kmem_alloc(oldsize, 0); |
---|
1103 | 1182 | oldsfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
---|
1104 | 1183 | ASSERT(oldsfp->i8count == 1); |
---|
1105 | 1184 | memcpy(buf, oldsfp, oldsize); |
---|
.. | .. |
---|
1119 | 1198 | */ |
---|
1120 | 1199 | sfp->count = oldsfp->count; |
---|
1121 | 1200 | sfp->i8count = 0; |
---|
1122 | | - dp->d_ops->sf_put_parent_ino(sfp, dp->d_ops->sf_get_parent_ino(oldsfp)); |
---|
| 1201 | + xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp)); |
---|
1123 | 1202 | /* |
---|
1124 | 1203 | * Copy the entries field by field. |
---|
1125 | 1204 | */ |
---|
1126 | 1205 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), |
---|
1127 | 1206 | oldsfep = xfs_dir2_sf_firstentry(oldsfp); |
---|
1128 | 1207 | i < sfp->count; |
---|
1129 | | - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep), |
---|
1130 | | - oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep)) { |
---|
| 1208 | + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep), |
---|
| 1209 | + oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep)) { |
---|
1131 | 1210 | sfep->namelen = oldsfep->namelen; |
---|
1132 | 1211 | memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset)); |
---|
1133 | 1212 | memcpy(sfep->name, oldsfep->name, sfep->namelen); |
---|
1134 | | - dp->d_ops->sf_put_ino(sfp, sfep, |
---|
1135 | | - dp->d_ops->sf_get_ino(oldsfp, oldsfep)); |
---|
1136 | | - dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep)); |
---|
| 1213 | + xfs_dir2_sf_put_ino(mp, sfp, sfep, |
---|
| 1214 | + xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep)); |
---|
| 1215 | + xfs_dir2_sf_put_ftype(mp, sfep, |
---|
| 1216 | + xfs_dir2_sf_get_ftype(mp, oldsfep)); |
---|
1137 | 1217 | } |
---|
1138 | 1218 | /* |
---|
1139 | 1219 | * Clean up the inode. |
---|
.. | .. |
---|
1152 | 1232 | xfs_dir2_sf_toino8( |
---|
1153 | 1233 | xfs_da_args_t *args) /* operation arguments */ |
---|
1154 | 1234 | { |
---|
| 1235 | + struct xfs_inode *dp = args->dp; |
---|
| 1236 | + struct xfs_mount *mp = dp->i_mount; |
---|
1155 | 1237 | char *buf; /* old dir's buffer */ |
---|
1156 | | - xfs_inode_t *dp; /* incore directory inode */ |
---|
1157 | 1238 | int i; /* entry index */ |
---|
1158 | 1239 | int newsize; /* new inode size */ |
---|
1159 | 1240 | xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ |
---|
.. | .. |
---|
1164 | 1245 | |
---|
1165 | 1246 | trace_xfs_dir2_sf_toino8(args); |
---|
1166 | 1247 | |
---|
1167 | | - dp = args->dp; |
---|
1168 | | - |
---|
1169 | 1248 | /* |
---|
1170 | 1249 | * Copy the old directory to the buffer. |
---|
1171 | 1250 | * Then nuke it from the inode, and add the new buffer to the inode. |
---|
1172 | 1251 | * Don't want xfs_idata_realloc copying the data here. |
---|
1173 | 1252 | */ |
---|
1174 | 1253 | oldsize = dp->i_df.if_bytes; |
---|
1175 | | - buf = kmem_alloc(oldsize, KM_SLEEP); |
---|
| 1254 | + buf = kmem_alloc(oldsize, 0); |
---|
1176 | 1255 | oldsfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; |
---|
1177 | 1256 | ASSERT(oldsfp->i8count == 0); |
---|
1178 | 1257 | memcpy(buf, oldsfp, oldsize); |
---|
.. | .. |
---|
1192 | 1271 | */ |
---|
1193 | 1272 | sfp->count = oldsfp->count; |
---|
1194 | 1273 | sfp->i8count = 1; |
---|
1195 | | - dp->d_ops->sf_put_parent_ino(sfp, dp->d_ops->sf_get_parent_ino(oldsfp)); |
---|
| 1274 | + xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp)); |
---|
1196 | 1275 | /* |
---|
1197 | 1276 | * Copy the entries field by field. |
---|
1198 | 1277 | */ |
---|
1199 | 1278 | for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), |
---|
1200 | 1279 | oldsfep = xfs_dir2_sf_firstentry(oldsfp); |
---|
1201 | 1280 | i < sfp->count; |
---|
1202 | | - i++, sfep = dp->d_ops->sf_nextentry(sfp, sfep), |
---|
1203 | | - oldsfep = dp->d_ops->sf_nextentry(oldsfp, oldsfep)) { |
---|
| 1281 | + i++, sfep = xfs_dir2_sf_nextentry(mp, sfp, sfep), |
---|
| 1282 | + oldsfep = xfs_dir2_sf_nextentry(mp, oldsfp, oldsfep)) { |
---|
1204 | 1283 | sfep->namelen = oldsfep->namelen; |
---|
1205 | 1284 | memcpy(sfep->offset, oldsfep->offset, sizeof(sfep->offset)); |
---|
1206 | 1285 | memcpy(sfep->name, oldsfep->name, sfep->namelen); |
---|
1207 | | - dp->d_ops->sf_put_ino(sfp, sfep, |
---|
1208 | | - dp->d_ops->sf_get_ino(oldsfp, oldsfep)); |
---|
1209 | | - dp->d_ops->sf_put_ftype(sfep, dp->d_ops->sf_get_ftype(oldsfep)); |
---|
| 1286 | + xfs_dir2_sf_put_ino(mp, sfp, sfep, |
---|
| 1287 | + xfs_dir2_sf_get_ino(mp, oldsfp, oldsfep)); |
---|
| 1288 | + xfs_dir2_sf_put_ftype(mp, sfep, |
---|
| 1289 | + xfs_dir2_sf_get_ftype(mp, oldsfep)); |
---|
1210 | 1290 | } |
---|
1211 | 1291 | /* |
---|
1212 | 1292 | * Clean up the inode. |
---|