diff options
author | Dave Chinner <dchinner@redhat.com> | 2013-04-03 01:11:20 -0400 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2013-04-27 12:51:56 -0400 |
commit | f5f3d9b0161633e8943520e83df634ad540b3b7f (patch) | |
tree | bd1a014fd6472904e53d7680e5692b49431ca6ab /fs/xfs/xfs_dir2_data.c | |
parent | f948dd76dde021c050c7c35720dc066a8b9a5e35 (diff) |
xfs: add CRC checks to block format directory blocks
Now that directory buffers are made from a single struct xfs_buf, we
can add CRC calculation and checking callbacks. While there, add all
the fields to the on disk structures for future functionality such
as d_type support, uuids, block numbers, owner inode, etc.
To distinguish between the different on disk formats, change the
magic numbers for the new format directory blocks.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Ben Myers <bpm@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_dir2_data.c')
-rw-r--r-- | fs/xfs/xfs_dir2_data.c | 160 |
1 files changed, 99 insertions, 61 deletions
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c index ffcf1774152e..8484ec4848ea 100644 --- a/fs/xfs/xfs_dir2_data.c +++ b/fs/xfs/xfs_dir2_data.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. | 2 | * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. |
3 | * Copyright (c) 2013 Red Hat, Inc. | ||
3 | * All Rights Reserved. | 4 | * All Rights Reserved. |
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
@@ -65,10 +66,11 @@ __xfs_dir2_data_check( | |||
65 | 66 | ||
66 | mp = bp->b_target->bt_mount; | 67 | mp = bp->b_target->bt_mount; |
67 | hdr = bp->b_addr; | 68 | hdr = bp->b_addr; |
68 | bf = hdr->bestfree; | 69 | bf = xfs_dir3_data_bestfree_p(hdr); |
69 | p = (char *)(hdr + 1); | 70 | p = (char *)xfs_dir3_data_entry_p(hdr); |
70 | 71 | ||
71 | switch (hdr->magic) { | 72 | switch (hdr->magic) { |
73 | case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC): | ||
72 | case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC): | 74 | case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC): |
73 | btp = xfs_dir2_block_tail_p(mp, hdr); | 75 | btp = xfs_dir2_block_tail_p(mp, hdr); |
74 | lep = xfs_dir2_block_leaf_p(btp); | 76 | lep = xfs_dir2_block_leaf_p(btp); |
@@ -148,7 +150,8 @@ __xfs_dir2_data_check( | |||
148 | (char *)dep - (char *)hdr); | 150 | (char *)dep - (char *)hdr); |
149 | count++; | 151 | count++; |
150 | lastfree = 0; | 152 | lastfree = 0; |
151 | if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) { | 153 | if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || |
154 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { | ||
152 | addr = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, | 155 | addr = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, |
153 | (xfs_dir2_data_aoff_t) | 156 | (xfs_dir2_data_aoff_t) |
154 | ((char *)dep - (char *)hdr)); | 157 | ((char *)dep - (char *)hdr)); |
@@ -168,7 +171,8 @@ __xfs_dir2_data_check( | |||
168 | * Need to have seen all the entries and all the bestfree slots. | 171 | * Need to have seen all the entries and all the bestfree slots. |
169 | */ | 172 | */ |
170 | XFS_WANT_CORRUPTED_RETURN(freeseen == 7); | 173 | XFS_WANT_CORRUPTED_RETURN(freeseen == 7); |
171 | if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) { | 174 | if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || |
175 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { | ||
172 | for (i = stale = 0; i < be32_to_cpu(btp->count); i++) { | 176 | for (i = stale = 0; i < be32_to_cpu(btp->count); i++) { |
173 | if (lep[i].address == | 177 | if (lep[i].address == |
174 | cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) | 178 | cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) |
@@ -216,7 +220,8 @@ xfs_dir2_data_reada_verify( | |||
216 | 220 | ||
217 | switch (hdr->magic) { | 221 | switch (hdr->magic) { |
218 | case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC): | 222 | case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC): |
219 | bp->b_ops = &xfs_dir2_block_buf_ops; | 223 | case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC): |
224 | bp->b_ops = &xfs_dir3_block_buf_ops; | ||
220 | bp->b_ops->verify_read(bp); | 225 | bp->b_ops->verify_read(bp); |
221 | return; | 226 | return; |
222 | case cpu_to_be32(XFS_DIR2_DATA_MAGIC): | 227 | case cpu_to_be32(XFS_DIR2_DATA_MAGIC): |
@@ -288,12 +293,15 @@ xfs_dir2_data_freefind( | |||
288 | { | 293 | { |
289 | xfs_dir2_data_free_t *dfp; /* bestfree entry */ | 294 | xfs_dir2_data_free_t *dfp; /* bestfree entry */ |
290 | xfs_dir2_data_aoff_t off; /* offset value needed */ | 295 | xfs_dir2_data_aoff_t off; /* offset value needed */ |
296 | struct xfs_dir2_data_free *bf; | ||
291 | #if defined(DEBUG) && defined(__KERNEL__) | 297 | #if defined(DEBUG) && defined(__KERNEL__) |
292 | int matched; /* matched the value */ | 298 | int matched; /* matched the value */ |
293 | int seenzero; /* saw a 0 bestfree entry */ | 299 | int seenzero; /* saw a 0 bestfree entry */ |
294 | #endif | 300 | #endif |
295 | 301 | ||
296 | off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr); | 302 | off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr); |
303 | bf = xfs_dir3_data_bestfree_p(hdr); | ||
304 | |||
297 | #if defined(DEBUG) && defined(__KERNEL__) | 305 | #if defined(DEBUG) && defined(__KERNEL__) |
298 | /* | 306 | /* |
299 | * Validate some consistency in the bestfree table. | 307 | * Validate some consistency in the bestfree table. |
@@ -301,9 +309,10 @@ xfs_dir2_data_freefind( | |||
301 | * one we're looking for it has to be exact. | 309 | * one we're looking for it has to be exact. |
302 | */ | 310 | */ |
303 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || | 311 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || |
304 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); | 312 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || |
305 | for (dfp = &hdr->bestfree[0], seenzero = matched = 0; | 313 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); |
306 | dfp < &hdr->bestfree[XFS_DIR2_DATA_FD_COUNT]; | 314 | for (dfp = &bf[0], seenzero = matched = 0; |
315 | dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; | ||
307 | dfp++) { | 316 | dfp++) { |
308 | if (!dfp->offset) { | 317 | if (!dfp->offset) { |
309 | ASSERT(!dfp->length); | 318 | ASSERT(!dfp->length); |
@@ -319,7 +328,7 @@ xfs_dir2_data_freefind( | |||
319 | else | 328 | else |
320 | ASSERT(be16_to_cpu(dfp->offset) + be16_to_cpu(dfp->length) <= off); | 329 | ASSERT(be16_to_cpu(dfp->offset) + be16_to_cpu(dfp->length) <= off); |
321 | ASSERT(matched || be16_to_cpu(dfp->length) >= be16_to_cpu(dup->length)); | 330 | ASSERT(matched || be16_to_cpu(dfp->length) >= be16_to_cpu(dup->length)); |
322 | if (dfp > &hdr->bestfree[0]) | 331 | if (dfp > &bf[0]) |
323 | ASSERT(be16_to_cpu(dfp[-1].length) >= be16_to_cpu(dfp[0].length)); | 332 | ASSERT(be16_to_cpu(dfp[-1].length) >= be16_to_cpu(dfp[0].length)); |
324 | } | 333 | } |
325 | #endif | 334 | #endif |
@@ -328,14 +337,12 @@ xfs_dir2_data_freefind( | |||
328 | * it can't be there since they're sorted. | 337 | * it can't be there since they're sorted. |
329 | */ | 338 | */ |
330 | if (be16_to_cpu(dup->length) < | 339 | if (be16_to_cpu(dup->length) < |
331 | be16_to_cpu(hdr->bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length)) | 340 | be16_to_cpu(bf[XFS_DIR2_DATA_FD_COUNT - 1].length)) |
332 | return NULL; | 341 | return NULL; |
333 | /* | 342 | /* |
334 | * Look at the three bestfree entries for our guy. | 343 | * Look at the three bestfree entries for our guy. |
335 | */ | 344 | */ |
336 | for (dfp = &hdr->bestfree[0]; | 345 | for (dfp = &bf[0]; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) { |
337 | dfp < &hdr->bestfree[XFS_DIR2_DATA_FD_COUNT]; | ||
338 | dfp++) { | ||
339 | if (!dfp->offset) | 346 | if (!dfp->offset) |
340 | return NULL; | 347 | return NULL; |
341 | if (be16_to_cpu(dfp->offset) == off) | 348 | if (be16_to_cpu(dfp->offset) == off) |
@@ -359,11 +366,12 @@ xfs_dir2_data_freeinsert( | |||
359 | xfs_dir2_data_free_t *dfp; /* bestfree table pointer */ | 366 | xfs_dir2_data_free_t *dfp; /* bestfree table pointer */ |
360 | xfs_dir2_data_free_t new; /* new bestfree entry */ | 367 | xfs_dir2_data_free_t new; /* new bestfree entry */ |
361 | 368 | ||
362 | #ifdef __KERNEL__ | ||
363 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || | 369 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || |
364 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); | 370 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || |
365 | #endif | 371 | hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || |
366 | dfp = hdr->bestfree; | 372 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); |
373 | |||
374 | dfp = xfs_dir3_data_bestfree_p(hdr); | ||
367 | new.length = dup->length; | 375 | new.length = dup->length; |
368 | new.offset = cpu_to_be16((char *)dup - (char *)hdr); | 376 | new.offset = cpu_to_be16((char *)dup - (char *)hdr); |
369 | 377 | ||
@@ -400,32 +408,36 @@ xfs_dir2_data_freeremove( | |||
400 | xfs_dir2_data_free_t *dfp, /* bestfree entry pointer */ | 408 | xfs_dir2_data_free_t *dfp, /* bestfree entry pointer */ |
401 | int *loghead) /* out: log data header */ | 409 | int *loghead) /* out: log data header */ |
402 | { | 410 | { |
403 | #ifdef __KERNEL__ | 411 | struct xfs_dir2_data_free *bf; |
412 | |||
404 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || | 413 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || |
405 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); | 414 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || |
406 | #endif | 415 | hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || |
416 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); | ||
417 | |||
407 | /* | 418 | /* |
408 | * It's the first entry, slide the next 2 up. | 419 | * It's the first entry, slide the next 2 up. |
409 | */ | 420 | */ |
410 | if (dfp == &hdr->bestfree[0]) { | 421 | bf = xfs_dir3_data_bestfree_p(hdr); |
411 | hdr->bestfree[0] = hdr->bestfree[1]; | 422 | if (dfp == &bf[0]) { |
412 | hdr->bestfree[1] = hdr->bestfree[2]; | 423 | bf[0] = bf[1]; |
424 | bf[1] = bf[2]; | ||
413 | } | 425 | } |
414 | /* | 426 | /* |
415 | * It's the second entry, slide the 3rd entry up. | 427 | * It's the second entry, slide the 3rd entry up. |
416 | */ | 428 | */ |
417 | else if (dfp == &hdr->bestfree[1]) | 429 | else if (dfp == &bf[1]) |
418 | hdr->bestfree[1] = hdr->bestfree[2]; | 430 | bf[1] = bf[2]; |
419 | /* | 431 | /* |
420 | * Must be the last entry. | 432 | * Must be the last entry. |
421 | */ | 433 | */ |
422 | else | 434 | else |
423 | ASSERT(dfp == &hdr->bestfree[2]); | 435 | ASSERT(dfp == &bf[2]); |
424 | /* | 436 | /* |
425 | * Clear the 3rd entry, must be zero now. | 437 | * Clear the 3rd entry, must be zero now. |
426 | */ | 438 | */ |
427 | hdr->bestfree[2].length = 0; | 439 | bf[2].length = 0; |
428 | hdr->bestfree[2].offset = 0; | 440 | bf[2].offset = 0; |
429 | *loghead = 1; | 441 | *loghead = 1; |
430 | } | 442 | } |
431 | 443 | ||
@@ -441,23 +453,26 @@ xfs_dir2_data_freescan( | |||
441 | xfs_dir2_block_tail_t *btp; /* block tail */ | 453 | xfs_dir2_block_tail_t *btp; /* block tail */ |
442 | xfs_dir2_data_entry_t *dep; /* active data entry */ | 454 | xfs_dir2_data_entry_t *dep; /* active data entry */ |
443 | xfs_dir2_data_unused_t *dup; /* unused data entry */ | 455 | xfs_dir2_data_unused_t *dup; /* unused data entry */ |
456 | struct xfs_dir2_data_free *bf; | ||
444 | char *endp; /* end of block's data */ | 457 | char *endp; /* end of block's data */ |
445 | char *p; /* current entry pointer */ | 458 | char *p; /* current entry pointer */ |
446 | 459 | ||
447 | #ifdef __KERNEL__ | ||
448 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || | 460 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || |
449 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); | 461 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || |
450 | #endif | 462 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); |
463 | |||
451 | /* | 464 | /* |
452 | * Start by clearing the table. | 465 | * Start by clearing the table. |
453 | */ | 466 | */ |
454 | memset(hdr->bestfree, 0, sizeof(hdr->bestfree)); | 467 | bf = xfs_dir3_data_bestfree_p(hdr); |
468 | memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT); | ||
455 | *loghead = 1; | 469 | *loghead = 1; |
456 | /* | 470 | /* |
457 | * Set up pointers. | 471 | * Set up pointers. |
458 | */ | 472 | */ |
459 | p = (char *)(hdr + 1); | 473 | p = (char *)xfs_dir3_data_entry_p(hdr); |
460 | if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) { | 474 | if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || |
475 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { | ||
461 | btp = xfs_dir2_block_tail_p(mp, hdr); | 476 | btp = xfs_dir2_block_tail_p(mp, hdr); |
462 | endp = (char *)xfs_dir2_block_leaf_p(btp); | 477 | endp = (char *)xfs_dir2_block_leaf_p(btp); |
463 | } else | 478 | } else |
@@ -493,7 +508,7 @@ xfs_dir2_data_freescan( | |||
493 | * Give back the buffer for the created block. | 508 | * Give back the buffer for the created block. |
494 | */ | 509 | */ |
495 | int /* error */ | 510 | int /* error */ |
496 | xfs_dir2_data_init( | 511 | xfs_dir3_data_init( |
497 | xfs_da_args_t *args, /* directory operation args */ | 512 | xfs_da_args_t *args, /* directory operation args */ |
498 | xfs_dir2_db_t blkno, /* logical dir block number */ | 513 | xfs_dir2_db_t blkno, /* logical dir block number */ |
499 | struct xfs_buf **bpp) /* output block buffer */ | 514 | struct xfs_buf **bpp) /* output block buffer */ |
@@ -502,6 +517,7 @@ xfs_dir2_data_init( | |||
502 | xfs_dir2_data_hdr_t *hdr; /* data block header */ | 517 | xfs_dir2_data_hdr_t *hdr; /* data block header */ |
503 | xfs_inode_t *dp; /* incore directory inode */ | 518 | xfs_inode_t *dp; /* incore directory inode */ |
504 | xfs_dir2_data_unused_t *dup; /* unused entry pointer */ | 519 | xfs_dir2_data_unused_t *dup; /* unused entry pointer */ |
520 | struct xfs_dir2_data_free *bf; | ||
505 | int error; /* error return value */ | 521 | int error; /* error return value */ |
506 | int i; /* bestfree index */ | 522 | int i; /* bestfree index */ |
507 | xfs_mount_t *mp; /* filesystem mount point */ | 523 | xfs_mount_t *mp; /* filesystem mount point */ |
@@ -524,21 +540,34 @@ xfs_dir2_data_init( | |||
524 | * Initialize the header. | 540 | * Initialize the header. |
525 | */ | 541 | */ |
526 | hdr = bp->b_addr; | 542 | hdr = bp->b_addr; |
527 | hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); | 543 | |
528 | hdr->bestfree[0].offset = cpu_to_be16(sizeof(*hdr)); | 544 | if (xfs_sb_version_hascrc(&mp->m_sb)) { |
545 | struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; | ||
546 | |||
547 | memset(hdr3, 0, sizeof(*hdr3)); | ||
548 | hdr3->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC); | ||
549 | hdr3->blkno = cpu_to_be64(bp->b_bn); | ||
550 | hdr3->owner = cpu_to_be64(dp->i_ino); | ||
551 | uuid_copy(&hdr3->uuid, &mp->m_sb.sb_uuid); | ||
552 | |||
553 | } else | ||
554 | hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); | ||
555 | |||
556 | bf = xfs_dir3_data_bestfree_p(hdr); | ||
557 | bf[0].offset = cpu_to_be16(xfs_dir3_data_entry_offset(hdr)); | ||
529 | for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) { | 558 | for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) { |
530 | hdr->bestfree[i].length = 0; | 559 | bf[i].length = 0; |
531 | hdr->bestfree[i].offset = 0; | 560 | bf[i].offset = 0; |
532 | } | 561 | } |
533 | 562 | ||
534 | /* | 563 | /* |
535 | * Set up an unused entry for the block's body. | 564 | * Set up an unused entry for the block's body. |
536 | */ | 565 | */ |
537 | dup = (xfs_dir2_data_unused_t *)(hdr + 1); | 566 | dup = xfs_dir3_data_unused_p(hdr); |
538 | dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); | 567 | dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); |
539 | 568 | ||
540 | t = mp->m_dirblksize - (uint)sizeof(*hdr); | 569 | t = mp->m_dirblksize - (uint)xfs_dir3_data_entry_offset(hdr); |
541 | hdr->bestfree[0].length = cpu_to_be16(t); | 570 | bf[0].length = cpu_to_be16(t); |
542 | dup->length = cpu_to_be16(t); | 571 | dup->length = cpu_to_be16(t); |
543 | *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr); | 572 | *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr); |
544 | /* | 573 | /* |
@@ -562,7 +591,8 @@ xfs_dir2_data_log_entry( | |||
562 | xfs_dir2_data_hdr_t *hdr = bp->b_addr; | 591 | xfs_dir2_data_hdr_t *hdr = bp->b_addr; |
563 | 592 | ||
564 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || | 593 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || |
565 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); | 594 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || |
595 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); | ||
566 | 596 | ||
567 | xfs_trans_log_buf(tp, bp, (uint)((char *)dep - (char *)hdr), | 597 | xfs_trans_log_buf(tp, bp, (uint)((char *)dep - (char *)hdr), |
568 | (uint)((char *)(xfs_dir2_data_entry_tag_p(dep) + 1) - | 598 | (uint)((char *)(xfs_dir2_data_entry_tag_p(dep) + 1) - |
@@ -580,9 +610,10 @@ xfs_dir2_data_log_header( | |||
580 | xfs_dir2_data_hdr_t *hdr = bp->b_addr; | 610 | xfs_dir2_data_hdr_t *hdr = bp->b_addr; |
581 | 611 | ||
582 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || | 612 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || |
583 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); | 613 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || |
614 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); | ||
584 | 615 | ||
585 | xfs_trans_log_buf(tp, bp, 0, sizeof(*hdr) - 1); | 616 | xfs_trans_log_buf(tp, bp, 0, xfs_dir3_data_entry_offset(hdr) - 1); |
586 | } | 617 | } |
587 | 618 | ||
588 | /* | 619 | /* |
@@ -597,7 +628,8 @@ xfs_dir2_data_log_unused( | |||
597 | xfs_dir2_data_hdr_t *hdr = bp->b_addr; | 628 | xfs_dir2_data_hdr_t *hdr = bp->b_addr; |
598 | 629 | ||
599 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || | 630 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || |
600 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); | 631 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || |
632 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); | ||
601 | 633 | ||
602 | /* | 634 | /* |
603 | * Log the first part of the unused entry. | 635 | * Log the first part of the unused entry. |
@@ -635,6 +667,7 @@ xfs_dir2_data_make_free( | |||
635 | xfs_dir2_data_unused_t *newdup; /* new unused entry */ | 667 | xfs_dir2_data_unused_t *newdup; /* new unused entry */ |
636 | xfs_dir2_data_unused_t *postdup; /* unused entry after us */ | 668 | xfs_dir2_data_unused_t *postdup; /* unused entry after us */ |
637 | xfs_dir2_data_unused_t *prevdup; /* unused entry before us */ | 669 | xfs_dir2_data_unused_t *prevdup; /* unused entry before us */ |
670 | struct xfs_dir2_data_free *bf; | ||
638 | 671 | ||
639 | mp = tp->t_mountp; | 672 | mp = tp->t_mountp; |
640 | hdr = bp->b_addr; | 673 | hdr = bp->b_addr; |
@@ -647,7 +680,8 @@ xfs_dir2_data_make_free( | |||
647 | else { | 680 | else { |
648 | xfs_dir2_block_tail_t *btp; /* block tail */ | 681 | xfs_dir2_block_tail_t *btp; /* block tail */ |
649 | 682 | ||
650 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); | 683 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || |
684 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); | ||
651 | btp = xfs_dir2_block_tail_p(mp, hdr); | 685 | btp = xfs_dir2_block_tail_p(mp, hdr); |
652 | endptr = (char *)xfs_dir2_block_leaf_p(btp); | 686 | endptr = (char *)xfs_dir2_block_leaf_p(btp); |
653 | } | 687 | } |
@@ -655,7 +689,7 @@ xfs_dir2_data_make_free( | |||
655 | * If this isn't the start of the block, then back up to | 689 | * If this isn't the start of the block, then back up to |
656 | * the previous entry and see if it's free. | 690 | * the previous entry and see if it's free. |
657 | */ | 691 | */ |
658 | if (offset > sizeof(*hdr)) { | 692 | if (offset > xfs_dir3_data_entry_offset(hdr)) { |
659 | __be16 *tagp; /* tag just before us */ | 693 | __be16 *tagp; /* tag just before us */ |
660 | 694 | ||
661 | tagp = (__be16 *)((char *)hdr + offset) - 1; | 695 | tagp = (__be16 *)((char *)hdr + offset) - 1; |
@@ -681,6 +715,7 @@ xfs_dir2_data_make_free( | |||
681 | * Previous and following entries are both free, | 715 | * Previous and following entries are both free, |
682 | * merge everything into a single free entry. | 716 | * merge everything into a single free entry. |
683 | */ | 717 | */ |
718 | bf = xfs_dir3_data_bestfree_p(hdr); | ||
684 | if (prevdup && postdup) { | 719 | if (prevdup && postdup) { |
685 | xfs_dir2_data_free_t *dfp2; /* another bestfree pointer */ | 720 | xfs_dir2_data_free_t *dfp2; /* another bestfree pointer */ |
686 | 721 | ||
@@ -695,7 +730,7 @@ xfs_dir2_data_make_free( | |||
695 | * since the third bestfree is there, there might be more | 730 | * since the third bestfree is there, there might be more |
696 | * entries. | 731 | * entries. |
697 | */ | 732 | */ |
698 | needscan = (hdr->bestfree[2].length != 0); | 733 | needscan = (bf[2].length != 0); |
699 | /* | 734 | /* |
700 | * Fix up the new big freespace. | 735 | * Fix up the new big freespace. |
701 | */ | 736 | */ |
@@ -711,10 +746,10 @@ xfs_dir2_data_make_free( | |||
711 | * Remove entry 1 first then entry 0. | 746 | * Remove entry 1 first then entry 0. |
712 | */ | 747 | */ |
713 | ASSERT(dfp && dfp2); | 748 | ASSERT(dfp && dfp2); |
714 | if (dfp == &hdr->bestfree[1]) { | 749 | if (dfp == &bf[1]) { |
715 | dfp = &hdr->bestfree[0]; | 750 | dfp = &bf[0]; |
716 | ASSERT(dfp2 == dfp); | 751 | ASSERT(dfp2 == dfp); |
717 | dfp2 = &hdr->bestfree[1]; | 752 | dfp2 = &bf[1]; |
718 | } | 753 | } |
719 | xfs_dir2_data_freeremove(hdr, dfp2, needlogp); | 754 | xfs_dir2_data_freeremove(hdr, dfp2, needlogp); |
720 | xfs_dir2_data_freeremove(hdr, dfp, needlogp); | 755 | xfs_dir2_data_freeremove(hdr, dfp, needlogp); |
@@ -722,7 +757,7 @@ xfs_dir2_data_make_free( | |||
722 | * Now insert the new entry. | 757 | * Now insert the new entry. |
723 | */ | 758 | */ |
724 | dfp = xfs_dir2_data_freeinsert(hdr, prevdup, needlogp); | 759 | dfp = xfs_dir2_data_freeinsert(hdr, prevdup, needlogp); |
725 | ASSERT(dfp == &hdr->bestfree[0]); | 760 | ASSERT(dfp == &bf[0]); |
726 | ASSERT(dfp->length == prevdup->length); | 761 | ASSERT(dfp->length == prevdup->length); |
727 | ASSERT(!dfp[1].length); | 762 | ASSERT(!dfp[1].length); |
728 | ASSERT(!dfp[2].length); | 763 | ASSERT(!dfp[2].length); |
@@ -751,7 +786,7 @@ xfs_dir2_data_make_free( | |||
751 | */ | 786 | */ |
752 | else { | 787 | else { |
753 | needscan = be16_to_cpu(prevdup->length) > | 788 | needscan = be16_to_cpu(prevdup->length) > |
754 | be16_to_cpu(hdr->bestfree[2].length); | 789 | be16_to_cpu(bf[2].length); |
755 | } | 790 | } |
756 | } | 791 | } |
757 | /* | 792 | /* |
@@ -779,7 +814,7 @@ xfs_dir2_data_make_free( | |||
779 | */ | 814 | */ |
780 | else { | 815 | else { |
781 | needscan = be16_to_cpu(newdup->length) > | 816 | needscan = be16_to_cpu(newdup->length) > |
782 | be16_to_cpu(hdr->bestfree[2].length); | 817 | be16_to_cpu(bf[2].length); |
783 | } | 818 | } |
784 | } | 819 | } |
785 | /* | 820 | /* |
@@ -818,10 +853,12 @@ xfs_dir2_data_use_free( | |||
818 | xfs_dir2_data_unused_t *newdup; /* new unused entry */ | 853 | xfs_dir2_data_unused_t *newdup; /* new unused entry */ |
819 | xfs_dir2_data_unused_t *newdup2; /* another new unused entry */ | 854 | xfs_dir2_data_unused_t *newdup2; /* another new unused entry */ |
820 | int oldlen; /* old unused entry's length */ | 855 | int oldlen; /* old unused entry's length */ |
856 | struct xfs_dir2_data_free *bf; | ||
821 | 857 | ||
822 | hdr = bp->b_addr; | 858 | hdr = bp->b_addr; |
823 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || | 859 | ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || |
824 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); | 860 | hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || |
861 | hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); | ||
825 | ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG); | 862 | ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG); |
826 | ASSERT(offset >= (char *)dup - (char *)hdr); | 863 | ASSERT(offset >= (char *)dup - (char *)hdr); |
827 | ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)hdr); | 864 | ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)hdr); |
@@ -831,7 +868,8 @@ xfs_dir2_data_use_free( | |||
831 | */ | 868 | */ |
832 | dfp = xfs_dir2_data_freefind(hdr, dup); | 869 | dfp = xfs_dir2_data_freefind(hdr, dup); |
833 | oldlen = be16_to_cpu(dup->length); | 870 | oldlen = be16_to_cpu(dup->length); |
834 | ASSERT(dfp || oldlen <= be16_to_cpu(hdr->bestfree[2].length)); | 871 | bf = xfs_dir3_data_bestfree_p(hdr); |
872 | ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length)); | ||
835 | /* | 873 | /* |
836 | * Check for alignment with front and back of the entry. | 874 | * Check for alignment with front and back of the entry. |
837 | */ | 875 | */ |
@@ -845,7 +883,7 @@ xfs_dir2_data_use_free( | |||
845 | */ | 883 | */ |
846 | if (matchfront && matchback) { | 884 | if (matchfront && matchback) { |
847 | if (dfp) { | 885 | if (dfp) { |
848 | needscan = (hdr->bestfree[2].offset != 0); | 886 | needscan = (bf[2].offset != 0); |
849 | if (!needscan) | 887 | if (!needscan) |
850 | xfs_dir2_data_freeremove(hdr, dfp, needlogp); | 888 | xfs_dir2_data_freeremove(hdr, dfp, needlogp); |
851 | } | 889 | } |
@@ -875,7 +913,7 @@ xfs_dir2_data_use_free( | |||
875 | * that means we don't know if there was a better | 913 | * that means we don't know if there was a better |
876 | * choice for the last slot, or not. Rescan. | 914 | * choice for the last slot, or not. Rescan. |
877 | */ | 915 | */ |
878 | needscan = dfp == &hdr->bestfree[2]; | 916 | needscan = dfp == &bf[2]; |
879 | } | 917 | } |
880 | } | 918 | } |
881 | /* | 919 | /* |
@@ -902,7 +940,7 @@ xfs_dir2_data_use_free( | |||
902 | * that means we don't know if there was a better | 940 | * that means we don't know if there was a better |
903 | * choice for the last slot, or not. Rescan. | 941 | * choice for the last slot, or not. Rescan. |
904 | */ | 942 | */ |
905 | needscan = dfp == &hdr->bestfree[2]; | 943 | needscan = dfp == &bf[2]; |
906 | } | 944 | } |
907 | } | 945 | } |
908 | /* | 946 | /* |
@@ -930,7 +968,7 @@ xfs_dir2_data_use_free( | |||
930 | * the 2 new will work. | 968 | * the 2 new will work. |
931 | */ | 969 | */ |
932 | if (dfp) { | 970 | if (dfp) { |
933 | needscan = (hdr->bestfree[2].length != 0); | 971 | needscan = (bf[2].length != 0); |
934 | if (!needscan) { | 972 | if (!needscan) { |
935 | xfs_dir2_data_freeremove(hdr, dfp, needlogp); | 973 | xfs_dir2_data_freeremove(hdr, dfp, needlogp); |
936 | xfs_dir2_data_freeinsert(hdr, newdup, needlogp); | 974 | xfs_dir2_data_freeinsert(hdr, newdup, needlogp); |