aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_dir2_block.c22
-rw-r--r--fs/xfs/xfs_dir2_data.c100
-rw-r--r--fs/xfs/xfs_dir2_format.h21
-rw-r--r--fs/xfs/xfs_dir2_leaf.c71
-rw-r--r--fs/xfs/xfs_dir2_node.c39
-rw-r--r--fs/xfs/xfs_dir2_priv.h12
-rw-r--r--fs/xfs/xfs_file.c2
7 files changed, 162 insertions, 105 deletions
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index 79a3f1b2bc7d..7ec87c20cbd2 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -77,7 +77,7 @@ xfs_dir3_block_verify(
77 if (hdr3->magic != cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) 77 if (hdr3->magic != cpu_to_be32(XFS_DIR2_BLOCK_MAGIC))
78 return false; 78 return false;
79 } 79 }
80 if (__xfs_dir2_data_check(NULL, bp)) 80 if (__xfs_dir3_data_check(NULL, bp))
81 return false; 81 return false;
82 return true; 82 return true;
83} 83}
@@ -553,7 +553,7 @@ xfs_dir2_block_addname(
553 xfs_dir2_data_log_header(tp, bp); 553 xfs_dir2_data_log_header(tp, bp);
554 xfs_dir2_block_log_tail(tp, bp); 554 xfs_dir2_block_log_tail(tp, bp);
555 xfs_dir2_data_log_entry(tp, bp, dep); 555 xfs_dir2_data_log_entry(tp, bp, dep);
556 xfs_dir2_data_check(dp, bp); 556 xfs_dir3_data_check(dp, bp);
557 return 0; 557 return 0;
558} 558}
559 559
@@ -596,7 +596,7 @@ xfs_dir2_block_getdents(
596 */ 596 */
597 wantoff = xfs_dir2_dataptr_to_off(mp, *offset); 597 wantoff = xfs_dir2_dataptr_to_off(mp, *offset);
598 hdr = bp->b_addr; 598 hdr = bp->b_addr;
599 xfs_dir2_data_check(dp, bp); 599 xfs_dir3_data_check(dp, bp);
600 /* 600 /*
601 * Set up values for the loop. 601 * Set up values for the loop.
602 */ 602 */
@@ -720,7 +720,7 @@ xfs_dir2_block_lookup(
720 dp = args->dp; 720 dp = args->dp;
721 mp = dp->i_mount; 721 mp = dp->i_mount;
722 hdr = bp->b_addr; 722 hdr = bp->b_addr;
723 xfs_dir2_data_check(dp, bp); 723 xfs_dir3_data_check(dp, bp);
724 btp = xfs_dir2_block_tail_p(mp, hdr); 724 btp = xfs_dir2_block_tail_p(mp, hdr);
725 blp = xfs_dir2_block_leaf_p(btp); 725 blp = xfs_dir2_block_leaf_p(btp);
726 /* 726 /*
@@ -771,7 +771,7 @@ xfs_dir2_block_lookup_int(
771 return error; 771 return error;
772 772
773 hdr = bp->b_addr; 773 hdr = bp->b_addr;
774 xfs_dir2_data_check(dp, bp); 774 xfs_dir3_data_check(dp, bp);
775 btp = xfs_dir2_block_tail_p(mp, hdr); 775 btp = xfs_dir2_block_tail_p(mp, hdr);
776 blp = xfs_dir2_block_leaf_p(btp); 776 blp = xfs_dir2_block_leaf_p(btp);
777 /* 777 /*
@@ -908,7 +908,7 @@ xfs_dir2_block_removename(
908 xfs_dir2_data_freescan(mp, hdr, &needlog); 908 xfs_dir2_data_freescan(mp, hdr, &needlog);
909 if (needlog) 909 if (needlog)
910 xfs_dir2_data_log_header(tp, bp); 910 xfs_dir2_data_log_header(tp, bp);
911 xfs_dir2_data_check(dp, bp); 911 xfs_dir3_data_check(dp, bp);
912 /* 912 /*
913 * See if the size as a shortform is good enough. 913 * See if the size as a shortform is good enough.
914 */ 914 */
@@ -965,7 +965,7 @@ xfs_dir2_block_replace(
965 */ 965 */
966 dep->inumber = cpu_to_be64(args->inumber); 966 dep->inumber = cpu_to_be64(args->inumber);
967 xfs_dir2_data_log_entry(args->trans, bp, dep); 967 xfs_dir2_data_log_entry(args->trans, bp, dep);
968 xfs_dir2_data_check(dp, bp); 968 xfs_dir3_data_check(dp, bp);
969 return 0; 969 return 0;
970} 970}
971 971
@@ -1046,12 +1046,14 @@ xfs_dir2_leaf_to_block(
1046 * Read the data block if we don't already have it, give up if it fails. 1046 * Read the data block if we don't already have it, give up if it fails.
1047 */ 1047 */
1048 if (!dbp) { 1048 if (!dbp) {
1049 error = xfs_dir2_data_read(tp, dp, mp->m_dirdatablk, -1, &dbp); 1049 error = xfs_dir3_data_read(tp, dp, mp->m_dirdatablk, -1, &dbp);
1050 if (error) 1050 if (error)
1051 return error; 1051 return error;
1052 } 1052 }
1053 hdr = dbp->b_addr; 1053 hdr = dbp->b_addr;
1054 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC)); 1054 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
1055 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
1056
1055 /* 1057 /*
1056 * Size of the "leaf" area in the block. 1058 * Size of the "leaf" area in the block.
1057 */ 1059 */
@@ -1329,6 +1331,6 @@ xfs_dir2_sf_to_block(
1329 ASSERT(needscan == 0); 1331 ASSERT(needscan == 0);
1330 xfs_dir2_block_log_leaf(tp, bp, 0, be32_to_cpu(btp->count) - 1); 1332 xfs_dir2_block_log_leaf(tp, bp, 0, be32_to_cpu(btp->count) - 1);
1331 xfs_dir2_block_log_tail(tp, bp); 1333 xfs_dir2_block_log_tail(tp, bp);
1332 xfs_dir2_data_check(dp, bp); 1334 xfs_dir3_data_check(dp, bp);
1333 return 0; 1335 return 0;
1334} 1336}
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index 8484ec4848ea..78320df3743f 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -31,6 +31,8 @@
31#include "xfs_dir2_format.h" 31#include "xfs_dir2_format.h"
32#include "xfs_dir2_priv.h" 32#include "xfs_dir2_priv.h"
33#include "xfs_error.h" 33#include "xfs_error.h"
34#include "xfs_buf_item.h"
35#include "xfs_cksum.h"
34 36
35STATIC xfs_dir2_data_free_t * 37STATIC xfs_dir2_data_free_t *
36xfs_dir2_data_freefind(xfs_dir2_data_hdr_t *hdr, xfs_dir2_data_unused_t *dup); 38xfs_dir2_data_freefind(xfs_dir2_data_hdr_t *hdr, xfs_dir2_data_unused_t *dup);
@@ -41,7 +43,7 @@ xfs_dir2_data_freefind(xfs_dir2_data_hdr_t *hdr, xfs_dir2_data_unused_t *dup);
41 * Return 0 is the buffer is good, otherwise an error. 43 * Return 0 is the buffer is good, otherwise an error.
42 */ 44 */
43int 45int
44__xfs_dir2_data_check( 46__xfs_dir3_data_check(
45 struct xfs_inode *dp, /* incore inode pointer */ 47 struct xfs_inode *dp, /* incore inode pointer */
46 struct xfs_buf *bp) /* data block's buffer */ 48 struct xfs_buf *bp) /* data block's buffer */
47{ 49{
@@ -76,6 +78,7 @@ __xfs_dir2_data_check(
76 lep = xfs_dir2_block_leaf_p(btp); 78 lep = xfs_dir2_block_leaf_p(btp);
77 endp = (char *)lep; 79 endp = (char *)lep;
78 break; 80 break;
81 case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
79 case cpu_to_be32(XFS_DIR2_DATA_MAGIC): 82 case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
80 endp = (char *)hdr + mp->m_dirblksize; 83 endp = (char *)hdr + mp->m_dirblksize;
81 break; 84 break;
@@ -189,21 +192,27 @@ __xfs_dir2_data_check(
189 return 0; 192 return 0;
190} 193}
191 194
192static void 195static bool
193xfs_dir2_data_verify( 196xfs_dir3_data_verify(
194 struct xfs_buf *bp) 197 struct xfs_buf *bp)
195{ 198{
196 struct xfs_mount *mp = bp->b_target->bt_mount; 199 struct xfs_mount *mp = bp->b_target->bt_mount;
197 struct xfs_dir2_data_hdr *hdr = bp->b_addr; 200 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
198 int block_ok = 0;
199 201
200 block_ok = hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC); 202 if (xfs_sb_version_hascrc(&mp->m_sb)) {
201 block_ok = block_ok && __xfs_dir2_data_check(NULL, bp) == 0; 203 if (hdr3->magic != cpu_to_be32(XFS_DIR3_DATA_MAGIC))
202 204 return false;
203 if (!block_ok) { 205 if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_uuid))
204 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr); 206 return false;
205 xfs_buf_ioerror(bp, EFSCORRUPTED); 207 if (be64_to_cpu(hdr3->blkno) != bp->b_bn)
208 return false;
209 } else {
210 if (hdr3->magic != cpu_to_be32(XFS_DIR2_DATA_MAGIC))
211 return false;
206 } 212 }
213 if (__xfs_dir3_data_check(NULL, bp))
214 return false;
215 return true;
207} 216}
208 217
209/* 218/*
@@ -212,7 +221,7 @@ xfs_dir2_data_verify(
212 * format buffer or a data format buffer on readahead. 221 * format buffer or a data format buffer on readahead.
213 */ 222 */
214static void 223static void
215xfs_dir2_data_reada_verify( 224xfs_dir3_data_reada_verify(
216 struct xfs_buf *bp) 225 struct xfs_buf *bp)
217{ 226{
218 struct xfs_mount *mp = bp->b_target->bt_mount; 227 struct xfs_mount *mp = bp->b_target->bt_mount;
@@ -225,7 +234,8 @@ xfs_dir2_data_reada_verify(
225 bp->b_ops->verify_read(bp); 234 bp->b_ops->verify_read(bp);
226 return; 235 return;
227 case cpu_to_be32(XFS_DIR2_DATA_MAGIC): 236 case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
228 xfs_dir2_data_verify(bp); 237 case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
238 xfs_dir3_data_verify(bp);
229 return; 239 return;
230 default: 240 default:
231 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr); 241 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr);
@@ -235,32 +245,56 @@ xfs_dir2_data_reada_verify(
235} 245}
236 246
237static void 247static void
238xfs_dir2_data_read_verify( 248xfs_dir3_data_read_verify(
239 struct xfs_buf *bp) 249 struct xfs_buf *bp)
240{ 250{
241 xfs_dir2_data_verify(bp); 251 struct xfs_mount *mp = bp->b_target->bt_mount;
252
253 if ((xfs_sb_version_hascrc(&mp->m_sb) &&
254 !xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
255 XFS_DIR3_DATA_CRC_OFF)) ||
256 !xfs_dir3_data_verify(bp)) {
257 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
258 xfs_buf_ioerror(bp, EFSCORRUPTED);
259 }
242} 260}
243 261
244static void 262static void
245xfs_dir2_data_write_verify( 263xfs_dir3_data_write_verify(
246 struct xfs_buf *bp) 264 struct xfs_buf *bp)
247{ 265{
248 xfs_dir2_data_verify(bp); 266 struct xfs_mount *mp = bp->b_target->bt_mount;
267 struct xfs_buf_log_item *bip = bp->b_fspriv;
268 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
269
270 if (!xfs_dir3_data_verify(bp)) {
271 XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
272 xfs_buf_ioerror(bp, EFSCORRUPTED);
273 return;
274 }
275
276 if (!xfs_sb_version_hascrc(&mp->m_sb))
277 return;
278
279 if (bip)
280 hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
281
282 xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_DATA_CRC_OFF);
249} 283}
250 284
251const struct xfs_buf_ops xfs_dir2_data_buf_ops = { 285const struct xfs_buf_ops xfs_dir3_data_buf_ops = {
252 .verify_read = xfs_dir2_data_read_verify, 286 .verify_read = xfs_dir3_data_read_verify,
253 .verify_write = xfs_dir2_data_write_verify, 287 .verify_write = xfs_dir3_data_write_verify,
254}; 288};
255 289
256static const struct xfs_buf_ops xfs_dir2_data_reada_buf_ops = { 290static const struct xfs_buf_ops xfs_dir3_data_reada_buf_ops = {
257 .verify_read = xfs_dir2_data_reada_verify, 291 .verify_read = xfs_dir3_data_reada_verify,
258 .verify_write = xfs_dir2_data_write_verify, 292 .verify_write = xfs_dir3_data_write_verify,
259}; 293};
260 294
261 295
262int 296int
263xfs_dir2_data_read( 297xfs_dir3_data_read(
264 struct xfs_trans *tp, 298 struct xfs_trans *tp,
265 struct xfs_inode *dp, 299 struct xfs_inode *dp,
266 xfs_dablk_t bno, 300 xfs_dablk_t bno,
@@ -268,18 +302,18 @@ xfs_dir2_data_read(
268 struct xfs_buf **bpp) 302 struct xfs_buf **bpp)
269{ 303{
270 return xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp, 304 return xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp,
271 XFS_DATA_FORK, &xfs_dir2_data_buf_ops); 305 XFS_DATA_FORK, &xfs_dir3_data_buf_ops);
272} 306}
273 307
274int 308int
275xfs_dir2_data_readahead( 309xfs_dir3_data_readahead(
276 struct xfs_trans *tp, 310 struct xfs_trans *tp,
277 struct xfs_inode *dp, 311 struct xfs_inode *dp,
278 xfs_dablk_t bno, 312 xfs_dablk_t bno,
279 xfs_daddr_t mapped_bno) 313 xfs_daddr_t mapped_bno)
280{ 314{
281 return xfs_da_reada_buf(tp, dp, bno, mapped_bno, 315 return xfs_da_reada_buf(tp, dp, bno, mapped_bno,
282 XFS_DATA_FORK, &xfs_dir2_data_reada_buf_ops); 316 XFS_DATA_FORK, &xfs_dir3_data_reada_buf_ops);
283} 317}
284 318
285/* 319/*
@@ -309,6 +343,7 @@ xfs_dir2_data_freefind(
309 * one we're looking for it has to be exact. 343 * one we're looking for it has to be exact.
310 */ 344 */
311 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 345 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
346 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
312 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 347 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
313 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 348 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
314 for (dfp = &bf[0], seenzero = matched = 0; 349 for (dfp = &bf[0], seenzero = matched = 0;
@@ -458,6 +493,7 @@ xfs_dir2_data_freescan(
458 char *p; /* current entry pointer */ 493 char *p; /* current entry pointer */
459 494
460 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 495 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
496 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
461 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 497 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
462 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 498 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
463 499
@@ -534,13 +570,12 @@ xfs_dir3_data_init(
534 XFS_DATA_FORK); 570 XFS_DATA_FORK);
535 if (error) 571 if (error)
536 return error; 572 return error;
537 bp->b_ops = &xfs_dir2_data_buf_ops; 573 bp->b_ops = &xfs_dir3_data_buf_ops;
538 574
539 /* 575 /*
540 * Initialize the header. 576 * Initialize the header.
541 */ 577 */
542 hdr = bp->b_addr; 578 hdr = bp->b_addr;
543
544 if (xfs_sb_version_hascrc(&mp->m_sb)) { 579 if (xfs_sb_version_hascrc(&mp->m_sb)) {
545 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr; 580 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
546 581
@@ -591,6 +626,7 @@ xfs_dir2_data_log_entry(
591 xfs_dir2_data_hdr_t *hdr = bp->b_addr; 626 xfs_dir2_data_hdr_t *hdr = bp->b_addr;
592 627
593 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 628 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
629 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
594 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 630 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
595 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 631 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
596 632
@@ -610,6 +646,7 @@ xfs_dir2_data_log_header(
610 xfs_dir2_data_hdr_t *hdr = bp->b_addr; 646 xfs_dir2_data_hdr_t *hdr = bp->b_addr;
611 647
612 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 648 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
649 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
613 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 650 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
614 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 651 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
615 652
@@ -628,6 +665,7 @@ xfs_dir2_data_log_unused(
628 xfs_dir2_data_hdr_t *hdr = bp->b_addr; 665 xfs_dir2_data_hdr_t *hdr = bp->b_addr;
629 666
630 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 667 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
668 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
631 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 669 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
632 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 670 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
633 671
@@ -675,7 +713,8 @@ xfs_dir2_data_make_free(
675 /* 713 /*
676 * Figure out where the end of the data area is. 714 * Figure out where the end of the data area is.
677 */ 715 */
678 if (hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC)) 716 if (hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
717 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC))
679 endptr = (char *)hdr + mp->m_dirblksize; 718 endptr = (char *)hdr + mp->m_dirblksize;
680 else { 719 else {
681 xfs_dir2_block_tail_t *btp; /* block tail */ 720 xfs_dir2_block_tail_t *btp; /* block tail */
@@ -857,6 +896,7 @@ xfs_dir2_data_use_free(
857 896
858 hdr = bp->b_addr; 897 hdr = bp->b_addr;
859 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || 898 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
899 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
860 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) || 900 hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
861 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)); 901 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
862 ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG); 902 ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG);
diff --git a/fs/xfs/xfs_dir2_format.h b/fs/xfs/xfs_dir2_format.h
index ec5044a92b70..0ac09502b830 100644
--- a/fs/xfs/xfs_dir2_format.h
+++ b/fs/xfs/xfs_dir2_format.h
@@ -283,7 +283,8 @@ struct xfs_dir3_data_hdr {
283static inline struct xfs_dir2_data_free * 283static inline struct xfs_dir2_data_free *
284xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr) 284xfs_dir3_data_bestfree_p(struct xfs_dir2_data_hdr *hdr)
285{ 285{
286 if (hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) { 286 if (hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
287 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
287 struct xfs_dir3_data_hdr *hdr3 = (struct xfs_dir3_data_hdr *)hdr; 288 struct xfs_dir3_data_hdr *hdr3 = (struct xfs_dir3_data_hdr *)hdr;
288 return hdr3->best_free; 289 return hdr3->best_free;
289 } 290 }
@@ -345,17 +346,6 @@ xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused *dup)
345 be16_to_cpu(dup->length) - sizeof(__be16)); 346 be16_to_cpu(dup->length) - sizeof(__be16));
346} 347}
347 348
348static inline struct xfs_dir2_data_unused *
349xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
350{
351 if (hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
352 return (struct xfs_dir2_data_unused *)
353 ((char *)hdr + sizeof(struct xfs_dir3_data_hdr));
354 }
355 return (struct xfs_dir2_data_unused *)
356 ((char *)hdr + sizeof(struct xfs_dir2_data_hdr));
357}
358
359static inline size_t 349static inline size_t
360xfs_dir3_data_hdr_size(bool dir3) 350xfs_dir3_data_hdr_size(bool dir3)
361{ 351{
@@ -379,6 +369,13 @@ xfs_dir3_data_entry_p(struct xfs_dir2_data_hdr *hdr)
379 ((char *)hdr + xfs_dir3_data_entry_offset(hdr)); 369 ((char *)hdr + xfs_dir3_data_entry_offset(hdr));
380} 370}
381 371
372static inline struct xfs_dir2_data_unused *
373xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
374{
375 return (struct xfs_dir2_data_unused *)
376 ((char *)hdr + xfs_dir3_data_entry_offset(hdr));
377}
378
382/* 379/*
383 * Offsets of . and .. in data space (always block 0) 380 * Offsets of . and .. in data space (always block 0)
384 */ 381 */
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index 979735b0c76d..c7dca950f768 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -149,7 +149,7 @@ xfs_dir2_block_to_leaf(
149 int needlog; /* need to log block header */ 149 int needlog; /* need to log block header */
150 int needscan; /* need to rescan bestfree */ 150 int needscan; /* need to rescan bestfree */
151 xfs_trans_t *tp; /* transaction pointer */ 151 xfs_trans_t *tp; /* transaction pointer */
152 struct xfs_dir2_data_free *bf; 152 struct xfs_dir2_data_free *bf;
153 153
154 trace_xfs_dir2_block_to_leaf(args); 154 trace_xfs_dir2_block_to_leaf(args);
155 155
@@ -175,7 +175,7 @@ xfs_dir2_block_to_leaf(
175 ASSERT(lbp != NULL); 175 ASSERT(lbp != NULL);
176 leaf = lbp->b_addr; 176 leaf = lbp->b_addr;
177 hdr = dbp->b_addr; 177 hdr = dbp->b_addr;
178 xfs_dir2_data_check(dp, dbp); 178 xfs_dir3_data_check(dp, dbp);
179 btp = xfs_dir2_block_tail_p(mp, hdr); 179 btp = xfs_dir2_block_tail_p(mp, hdr);
180 blp = xfs_dir2_block_leaf_p(btp); 180 blp = xfs_dir2_block_leaf_p(btp);
181 bf = xfs_dir3_data_bestfree_p(hdr); 181 bf = xfs_dir3_data_bestfree_p(hdr);
@@ -204,8 +204,12 @@ xfs_dir2_block_to_leaf(
204 /* 204 /*
205 * Fix up the block header, make it a data block. 205 * Fix up the block header, make it a data block.
206 */ 206 */
207 dbp->b_ops = &xfs_dir2_data_buf_ops; 207 dbp->b_ops = &xfs_dir3_data_buf_ops;
208 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); 208 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC))
209 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
210 else
211 hdr->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC);
212
209 if (needscan) 213 if (needscan)
210 xfs_dir2_data_freescan(mp, hdr, &needlog); 214 xfs_dir2_data_freescan(mp, hdr, &needlog);
211 /* 215 /*
@@ -221,7 +225,7 @@ xfs_dir2_block_to_leaf(
221 if (needlog) 225 if (needlog)
222 xfs_dir2_data_log_header(tp, dbp); 226 xfs_dir2_data_log_header(tp, dbp);
223 xfs_dir2_leaf_check(dp, lbp); 227 xfs_dir2_leaf_check(dp, lbp);
224 xfs_dir2_data_check(dp, dbp); 228 xfs_dir3_data_check(dp, dbp);
225 xfs_dir2_leaf_log_bests(tp, lbp, 0, 0); 229 xfs_dir2_leaf_log_bests(tp, lbp, 0, 0);
226 return 0; 230 return 0;
227} 231}
@@ -385,6 +389,7 @@ xfs_dir2_leaf_addname(
385 __be16 *tagp; /* end of data entry */ 389 __be16 *tagp; /* end of data entry */
386 xfs_trans_t *tp; /* transaction pointer */ 390 xfs_trans_t *tp; /* transaction pointer */
387 xfs_dir2_db_t use_block; /* data block number */ 391 xfs_dir2_db_t use_block; /* data block number */
392 struct xfs_dir2_data_free *bf; /* bestfree table */
388 393
389 trace_xfs_dir2_leaf_addname(args); 394 trace_xfs_dir2_leaf_addname(args);
390 395
@@ -568,14 +573,15 @@ xfs_dir2_leaf_addname(
568 else 573 else
569 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); 574 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block);
570 hdr = dbp->b_addr; 575 hdr = dbp->b_addr;
571 bestsp[use_block] = hdr->bestfree[0].length; 576 bf = xfs_dir3_data_bestfree_p(hdr);
577 bestsp[use_block] = bf[0].length;
572 grown = 1; 578 grown = 1;
573 } else { 579 } else {
574 /* 580 /*
575 * Already had space in some data block. 581 * Already had space in some data block.
576 * Just read that one in. 582 * Just read that one in.
577 */ 583 */
578 error = xfs_dir2_data_read(tp, dp, 584 error = xfs_dir3_data_read(tp, dp,
579 xfs_dir2_db_to_da(mp, use_block), 585 xfs_dir2_db_to_da(mp, use_block),
580 -1, &dbp); 586 -1, &dbp);
581 if (error) { 587 if (error) {
@@ -583,13 +589,14 @@ xfs_dir2_leaf_addname(
583 return error; 589 return error;
584 } 590 }
585 hdr = dbp->b_addr; 591 hdr = dbp->b_addr;
592 bf = xfs_dir3_data_bestfree_p(hdr);
586 grown = 0; 593 grown = 0;
587 } 594 }
588 /* 595 /*
589 * Point to the biggest freespace in our data block. 596 * Point to the biggest freespace in our data block.
590 */ 597 */
591 dup = (xfs_dir2_data_unused_t *) 598 dup = (xfs_dir2_data_unused_t *)
592 ((char *)hdr + be16_to_cpu(hdr->bestfree[0].offset)); 599 ((char *)hdr + be16_to_cpu(bf[0].offset));
593 ASSERT(be16_to_cpu(dup->length) >= length); 600 ASSERT(be16_to_cpu(dup->length) >= length);
594 needscan = needlog = 0; 601 needscan = needlog = 0;
595 /* 602 /*
@@ -622,8 +629,8 @@ xfs_dir2_leaf_addname(
622 * If the bests table needs to be changed, do it. 629 * If the bests table needs to be changed, do it.
623 * Log the change unless we've already done that. 630 * Log the change unless we've already done that.
624 */ 631 */
625 if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(hdr->bestfree[0].length)) { 632 if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(bf[0].length)) {
626 bestsp[use_block] = hdr->bestfree[0].length; 633 bestsp[use_block] = bf[0].length;
627 if (!grown) 634 if (!grown)
628 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); 635 xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block);
629 } 636 }
@@ -643,7 +650,7 @@ xfs_dir2_leaf_addname(
643 xfs_dir2_leaf_log_header(tp, lbp); 650 xfs_dir2_leaf_log_header(tp, lbp);
644 xfs_dir2_leaf_log_ents(tp, lbp, lfloglow, lfloghigh); 651 xfs_dir2_leaf_log_ents(tp, lbp, lfloglow, lfloghigh);
645 xfs_dir2_leaf_check(dp, lbp); 652 xfs_dir2_leaf_check(dp, lbp);
646 xfs_dir2_data_check(dp, dbp); 653 xfs_dir3_data_check(dp, dbp);
647 return 0; 654 return 0;
648} 655}
649 656
@@ -967,7 +974,7 @@ xfs_dir2_leaf_readbuf(
967 * Read the directory block starting at the first mapping. 974 * Read the directory block starting at the first mapping.
968 */ 975 */
969 mip->curdb = xfs_dir2_da_to_db(mp, map->br_startoff); 976 mip->curdb = xfs_dir2_da_to_db(mp, map->br_startoff);
970 error = xfs_dir2_data_read(NULL, dp, map->br_startoff, 977 error = xfs_dir3_data_read(NULL, dp, map->br_startoff,
971 map->br_blockcount >= mp->m_dirblkfsbs ? 978 map->br_blockcount >= mp->m_dirblkfsbs ?
972 XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, &bp); 979 XFS_FSB_TO_DADDR(mp, map->br_startblock) : -1, &bp);
973 980
@@ -996,7 +1003,7 @@ xfs_dir2_leaf_readbuf(
996 */ 1003 */
997 if (i > mip->ra_current && 1004 if (i > mip->ra_current &&
998 map[mip->ra_index].br_blockcount >= mp->m_dirblkfsbs) { 1005 map[mip->ra_index].br_blockcount >= mp->m_dirblkfsbs) {
999 xfs_dir2_data_readahead(NULL, dp, 1006 xfs_dir3_data_readahead(NULL, dp,
1000 map[mip->ra_index].br_startoff + mip->ra_offset, 1007 map[mip->ra_index].br_startoff + mip->ra_offset,
1001 XFS_FSB_TO_DADDR(mp, 1008 XFS_FSB_TO_DADDR(mp,
1002 map[mip->ra_index].br_startblock + 1009 map[mip->ra_index].br_startblock +
@@ -1009,7 +1016,7 @@ xfs_dir2_leaf_readbuf(
1009 * use our mapping, but this is a very rare case. 1016 * use our mapping, but this is a very rare case.
1010 */ 1017 */
1011 else if (i > mip->ra_current) { 1018 else if (i > mip->ra_current) {
1012 xfs_dir2_data_readahead(NULL, dp, 1019 xfs_dir3_data_readahead(NULL, dp,
1013 map[mip->ra_index].br_startoff + 1020 map[mip->ra_index].br_startoff +
1014 mip->ra_offset, -1); 1021 mip->ra_offset, -1);
1015 mip->ra_current = i; 1022 mip->ra_current = i;
@@ -1135,17 +1142,17 @@ xfs_dir2_leaf_getdents(
1135 ASSERT(xfs_dir2_byte_to_db(mp, curoff) == 1142 ASSERT(xfs_dir2_byte_to_db(mp, curoff) ==
1136 map_info->curdb); 1143 map_info->curdb);
1137 hdr = bp->b_addr; 1144 hdr = bp->b_addr;
1138 xfs_dir2_data_check(dp, bp); 1145 xfs_dir3_data_check(dp, bp);
1139 /* 1146 /*
1140 * Find our position in the block. 1147 * Find our position in the block.
1141 */ 1148 */
1142 ptr = (char *)(hdr + 1); 1149 ptr = (char *)xfs_dir3_data_entry_p(hdr);
1143 byteoff = xfs_dir2_byte_to_off(mp, curoff); 1150 byteoff = xfs_dir2_byte_to_off(mp, curoff);
1144 /* 1151 /*
1145 * Skip past the header. 1152 * Skip past the header.
1146 */ 1153 */
1147 if (byteoff == 0) 1154 if (byteoff == 0)
1148 curoff += (uint)sizeof(*hdr); 1155 curoff += xfs_dir3_data_entry_offset(hdr);
1149 /* 1156 /*
1150 * Skip past entries until we reach our offset. 1157 * Skip past entries until we reach our offset.
1151 */ 1158 */
@@ -1481,7 +1488,7 @@ xfs_dir2_leaf_lookup_int(
1481 if (newdb != curdb) { 1488 if (newdb != curdb) {
1482 if (dbp) 1489 if (dbp)
1483 xfs_trans_brelse(tp, dbp); 1490 xfs_trans_brelse(tp, dbp);
1484 error = xfs_dir2_data_read(tp, dp, 1491 error = xfs_dir3_data_read(tp, dp,
1485 xfs_dir2_db_to_da(mp, newdb), 1492 xfs_dir2_db_to_da(mp, newdb),
1486 -1, &dbp); 1493 -1, &dbp);
1487 if (error) { 1494 if (error) {
@@ -1522,7 +1529,7 @@ xfs_dir2_leaf_lookup_int(
1522 ASSERT(cidb != -1); 1529 ASSERT(cidb != -1);
1523 if (cidb != curdb) { 1530 if (cidb != curdb) {
1524 xfs_trans_brelse(tp, dbp); 1531 xfs_trans_brelse(tp, dbp);
1525 error = xfs_dir2_data_read(tp, dp, 1532 error = xfs_dir3_data_read(tp, dp,
1526 xfs_dir2_db_to_da(mp, cidb), 1533 xfs_dir2_db_to_da(mp, cidb),
1527 -1, &dbp); 1534 -1, &dbp);
1528 if (error) { 1535 if (error) {
@@ -1568,6 +1575,7 @@ xfs_dir2_leaf_removename(
1568 int needscan; /* need to rescan data frees */ 1575 int needscan; /* need to rescan data frees */
1569 xfs_dir2_data_off_t oldbest; /* old value of best free */ 1576 xfs_dir2_data_off_t oldbest; /* old value of best free */
1570 xfs_trans_t *tp; /* transaction pointer */ 1577 xfs_trans_t *tp; /* transaction pointer */
1578 struct xfs_dir2_data_free *bf; /* bestfree table */
1571 1579
1572 trace_xfs_dir2_leaf_removename(args); 1580 trace_xfs_dir2_leaf_removename(args);
1573 1581
@@ -1582,7 +1590,8 @@ xfs_dir2_leaf_removename(
1582 mp = dp->i_mount; 1590 mp = dp->i_mount;
1583 leaf = lbp->b_addr; 1591 leaf = lbp->b_addr;
1584 hdr = dbp->b_addr; 1592 hdr = dbp->b_addr;
1585 xfs_dir2_data_check(dp, dbp); 1593 bf = xfs_dir3_data_bestfree_p(hdr);
1594 xfs_dir3_data_check(dp, dbp);
1586 /* 1595 /*
1587 * Point to the leaf entry, use that to point to the data entry. 1596 * Point to the leaf entry, use that to point to the data entry.
1588 */ 1597 */
@@ -1591,7 +1600,7 @@ xfs_dir2_leaf_removename(
1591 dep = (xfs_dir2_data_entry_t *) 1600 dep = (xfs_dir2_data_entry_t *)
1592 ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); 1601 ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address)));
1593 needscan = needlog = 0; 1602 needscan = needlog = 0;
1594 oldbest = be16_to_cpu(hdr->bestfree[0].length); 1603 oldbest = be16_to_cpu(bf[0].length);
1595 ltp = xfs_dir2_leaf_tail_p(mp, leaf); 1604 ltp = xfs_dir2_leaf_tail_p(mp, leaf);
1596 bestsp = xfs_dir2_leaf_bests_p(ltp); 1605 bestsp = xfs_dir2_leaf_bests_p(ltp);
1597 ASSERT(be16_to_cpu(bestsp[db]) == oldbest); 1606 ASSERT(be16_to_cpu(bestsp[db]) == oldbest);
@@ -1620,16 +1629,16 @@ xfs_dir2_leaf_removename(
1620 * If the longest freespace in the data block has changed, 1629 * If the longest freespace in the data block has changed,
1621 * put the new value in the bests table and log that. 1630 * put the new value in the bests table and log that.
1622 */ 1631 */
1623 if (be16_to_cpu(hdr->bestfree[0].length) != oldbest) { 1632 if (be16_to_cpu(bf[0].length) != oldbest) {
1624 bestsp[db] = hdr->bestfree[0].length; 1633 bestsp[db] = bf[0].length;
1625 xfs_dir2_leaf_log_bests(tp, lbp, db, db); 1634 xfs_dir2_leaf_log_bests(tp, lbp, db, db);
1626 } 1635 }
1627 xfs_dir2_data_check(dp, dbp); 1636 xfs_dir3_data_check(dp, dbp);
1628 /* 1637 /*
1629 * If the data block is now empty then get rid of the data block. 1638 * If the data block is now empty then get rid of the data block.
1630 */ 1639 */
1631 if (be16_to_cpu(hdr->bestfree[0].length) == 1640 if (be16_to_cpu(bf[0].length) ==
1632 mp->m_dirblksize - (uint)sizeof(*hdr)) { 1641 mp->m_dirblksize - xfs_dir3_data_entry_offset(hdr)) {
1633 ASSERT(db != mp->m_dirdatablk); 1642 ASSERT(db != mp->m_dirdatablk);
1634 if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { 1643 if ((error = xfs_dir2_shrink_inode(args, db, dbp))) {
1635 /* 1644 /*
@@ -1809,7 +1818,7 @@ xfs_dir2_leaf_trim_data(
1809 /* 1818 /*
1810 * Read the offending data block. We need its buffer. 1819 * Read the offending data block. We need its buffer.
1811 */ 1820 */
1812 error = xfs_dir2_data_read(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp); 1821 error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(mp, db), -1, &dbp);
1813 if (error) 1822 if (error)
1814 return error; 1823 return error;
1815 1824
@@ -1819,10 +1828,12 @@ xfs_dir2_leaf_trim_data(
1819#ifdef DEBUG 1828#ifdef DEBUG
1820{ 1829{
1821 struct xfs_dir2_data_hdr *hdr = dbp->b_addr; 1830 struct xfs_dir2_data_hdr *hdr = dbp->b_addr;
1831 struct xfs_dir2_data_free *bf = xfs_dir3_data_bestfree_p(hdr);
1822 1832
1823 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC)); 1833 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
1824 ASSERT(be16_to_cpu(hdr->bestfree[0].length) == 1834 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
1825 mp->m_dirblksize - (uint)sizeof(*hdr)); 1835 ASSERT(be16_to_cpu(bf[0].length) ==
1836 mp->m_dirblksize - xfs_dir3_data_entry_offset(hdr));
1826 ASSERT(db == be32_to_cpu(ltp->bestcount) - 1); 1837 ASSERT(db == be32_to_cpu(ltp->bestcount) - 1);
1827} 1838}
1828#endif 1839#endif
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index 0fe39b9fde7e..abf617d5060b 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -753,13 +753,13 @@ xfs_dir2_leafn_lookup_for_entry(
753 ASSERT(state->extravalid); 753 ASSERT(state->extravalid);
754 curbp = state->extrablk.bp; 754 curbp = state->extrablk.bp;
755 } else { 755 } else {
756 error = xfs_dir2_data_read(tp, dp, 756 error = xfs_dir3_data_read(tp, dp,
757 xfs_dir2_db_to_da(mp, newdb), 757 xfs_dir2_db_to_da(mp, newdb),
758 -1, &curbp); 758 -1, &curbp);
759 if (error) 759 if (error)
760 return error; 760 return error;
761 } 761 }
762 xfs_dir2_data_check(dp, curbp); 762 xfs_dir3_data_check(dp, curbp);
763 curdb = newdb; 763 curdb = newdb;
764 } 764 }
765 /* 765 /*
@@ -787,7 +787,7 @@ xfs_dir2_leafn_lookup_for_entry(
787 state->extrablk.index = (int)((char *)dep - 787 state->extrablk.index = (int)((char *)dep -
788 (char *)curbp->b_addr); 788 (char *)curbp->b_addr);
789 state->extrablk.magic = XFS_DIR2_DATA_MAGIC; 789 state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
790 curbp->b_ops = &xfs_dir2_data_buf_ops; 790 curbp->b_ops = &xfs_dir3_data_buf_ops;
791 if (cmp == XFS_CMP_EXACT) 791 if (cmp == XFS_CMP_EXACT)
792 return XFS_ERROR(EEXIST); 792 return XFS_ERROR(EEXIST);
793 } 793 }
@@ -802,7 +802,7 @@ xfs_dir2_leafn_lookup_for_entry(
802 state->extrablk.index = -1; 802 state->extrablk.index = -1;
803 state->extrablk.blkno = curdb; 803 state->extrablk.blkno = curdb;
804 state->extrablk.magic = XFS_DIR2_DATA_MAGIC; 804 state->extrablk.magic = XFS_DIR2_DATA_MAGIC;
805 curbp->b_ops = &xfs_dir2_data_buf_ops; 805 curbp->b_ops = &xfs_dir3_data_buf_ops;
806 } else { 806 } else {
807 /* If the curbp is not the CI match block, drop it */ 807 /* If the curbp is not the CI match block, drop it */
808 if (state->extrablk.bp != curbp) 808 if (state->extrablk.bp != curbp)
@@ -1152,6 +1152,7 @@ xfs_dir2_leafn_remove(
1152 int needlog; /* need to log data header */ 1152 int needlog; /* need to log data header */
1153 int needscan; /* need to rescan data frees */ 1153 int needscan; /* need to rescan data frees */
1154 xfs_trans_t *tp; /* transaction pointer */ 1154 xfs_trans_t *tp; /* transaction pointer */
1155 struct xfs_dir2_data_free *bf; /* bestfree table */
1155 1156
1156 trace_xfs_dir2_leafn_remove(args, index); 1157 trace_xfs_dir2_leafn_remove(args, index);
1157 1158
@@ -1186,7 +1187,8 @@ xfs_dir2_leafn_remove(
1186 dbp = dblk->bp; 1187 dbp = dblk->bp;
1187 hdr = dbp->b_addr; 1188 hdr = dbp->b_addr;
1188 dep = (xfs_dir2_data_entry_t *)((char *)hdr + off); 1189 dep = (xfs_dir2_data_entry_t *)((char *)hdr + off);
1189 longest = be16_to_cpu(hdr->bestfree[0].length); 1190 bf = xfs_dir3_data_bestfree_p(hdr);
1191 longest = be16_to_cpu(bf[0].length);
1190 needlog = needscan = 0; 1192 needlog = needscan = 0;
1191 xfs_dir2_data_make_free(tp, dbp, off, 1193 xfs_dir2_data_make_free(tp, dbp, off,
1192 xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); 1194 xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan);
@@ -1198,12 +1200,12 @@ xfs_dir2_leafn_remove(
1198 xfs_dir2_data_freescan(mp, hdr, &needlog); 1200 xfs_dir2_data_freescan(mp, hdr, &needlog);
1199 if (needlog) 1201 if (needlog)
1200 xfs_dir2_data_log_header(tp, dbp); 1202 xfs_dir2_data_log_header(tp, dbp);
1201 xfs_dir2_data_check(dp, dbp); 1203 xfs_dir3_data_check(dp, dbp);
1202 /* 1204 /*
1203 * If the longest data block freespace changes, need to update 1205 * If the longest data block freespace changes, need to update
1204 * the corresponding freeblock entry. 1206 * the corresponding freeblock entry.
1205 */ 1207 */
1206 if (longest < be16_to_cpu(hdr->bestfree[0].length)) { 1208 if (longest < be16_to_cpu(bf[0].length)) {
1207 int error; /* error return value */ 1209 int error; /* error return value */
1208 struct xfs_buf *fbp; /* freeblock buffer */ 1210 struct xfs_buf *fbp; /* freeblock buffer */
1209 xfs_dir2_db_t fdb; /* freeblock block number */ 1211 xfs_dir2_db_t fdb; /* freeblock block number */
@@ -1232,12 +1234,13 @@ xfs_dir2_leafn_remove(
1232 * Calculate which entry we need to fix. 1234 * Calculate which entry we need to fix.
1233 */ 1235 */
1234 findex = xfs_dir2_db_to_fdindex(mp, db); 1236 findex = xfs_dir2_db_to_fdindex(mp, db);
1235 longest = be16_to_cpu(hdr->bestfree[0].length); 1237 longest = be16_to_cpu(bf[0].length);
1236 /* 1238 /*
1237 * If the data block is now empty we can get rid of it 1239 * If the data block is now empty we can get rid of it
1238 * (usually). 1240 * (usually).
1239 */ 1241 */
1240 if (longest == mp->m_dirblksize - (uint)sizeof(*hdr)) { 1242 if (longest == mp->m_dirblksize -
1243 xfs_dir3_data_entry_offset(hdr)) {
1241 /* 1244 /*
1242 * Try to punch out the data block. 1245 * Try to punch out the data block.
1243 */ 1246 */
@@ -1611,6 +1614,7 @@ xfs_dir2_node_addname_int(
1611 xfs_trans_t *tp; /* transaction pointer */ 1614 xfs_trans_t *tp; /* transaction pointer */
1612 __be16 *bests; 1615 __be16 *bests;
1613 struct xfs_dir3_icfree_hdr freehdr; 1616 struct xfs_dir3_icfree_hdr freehdr;
1617 struct xfs_dir2_data_free *bf;
1614 1618
1615 dp = args->dp; 1619 dp = args->dp;
1616 mp = dp->i_mount; 1620 mp = dp->i_mount;
@@ -1868,7 +1872,8 @@ xfs_dir2_node_addname_int(
1868 * change again. 1872 * change again.
1869 */ 1873 */
1870 hdr = dbp->b_addr; 1874 hdr = dbp->b_addr;
1871 bests[findex] = hdr->bestfree[0].length; 1875 bf = xfs_dir3_data_bestfree_p(hdr);
1876 bests[findex] = bf[0].length;
1872 logfree = 1; 1877 logfree = 1;
1873 } 1878 }
1874 /* 1879 /*
@@ -1884,19 +1889,20 @@ xfs_dir2_node_addname_int(
1884 /* 1889 /*
1885 * Read the data block in. 1890 * Read the data block in.
1886 */ 1891 */
1887 error = xfs_dir2_data_read(tp, dp, xfs_dir2_db_to_da(mp, dbno), 1892 error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(mp, dbno),
1888 -1, &dbp); 1893 -1, &dbp);
1889 if (error) 1894 if (error)
1890 return error; 1895 return error;
1891 hdr = dbp->b_addr; 1896 hdr = dbp->b_addr;
1897 bf = xfs_dir3_data_bestfree_p(hdr);
1892 logfree = 0; 1898 logfree = 0;
1893 } 1899 }
1894 ASSERT(be16_to_cpu(hdr->bestfree[0].length) >= length); 1900 ASSERT(be16_to_cpu(bf[0].length) >= length);
1895 /* 1901 /*
1896 * Point to the existing unused space. 1902 * Point to the existing unused space.
1897 */ 1903 */
1898 dup = (xfs_dir2_data_unused_t *) 1904 dup = (xfs_dir2_data_unused_t *)
1899 ((char *)hdr + be16_to_cpu(hdr->bestfree[0].offset)); 1905 ((char *)hdr + be16_to_cpu(bf[0].offset));
1900 needscan = needlog = 0; 1906 needscan = needlog = 0;
1901 /* 1907 /*
1902 * Mark the first part of the unused space, inuse for us. 1908 * Mark the first part of the unused space, inuse for us.
@@ -1928,8 +1934,8 @@ xfs_dir2_node_addname_int(
1928 * If the freespace entry is now wrong, update it. 1934 * If the freespace entry is now wrong, update it.
1929 */ 1935 */
1930 bests = xfs_dir3_free_bests_p(mp, free); /* gcc is so stupid */ 1936 bests = xfs_dir3_free_bests_p(mp, free); /* gcc is so stupid */
1931 if (be16_to_cpu(bests[findex]) != be16_to_cpu(hdr->bestfree[0].length)) { 1937 if (be16_to_cpu(bests[findex]) != be16_to_cpu(bf[0].length)) {
1932 bests[findex] = hdr->bestfree[0].length; 1938 bests[findex] = bf[0].length;
1933 logfree = 1; 1939 logfree = 1;
1934 } 1940 }
1935 /* 1941 /*
@@ -2119,7 +2125,8 @@ xfs_dir2_node_replace(
2119 * Point to the data entry. 2125 * Point to the data entry.
2120 */ 2126 */
2121 hdr = state->extrablk.bp->b_addr; 2127 hdr = state->extrablk.bp->b_addr;
2122 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC)); 2128 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
2129 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
2123 dep = (xfs_dir2_data_entry_t *) 2130 dep = (xfs_dir2_data_entry_t *)
2124 ((char *)hdr + 2131 ((char *)hdr +
2125 xfs_dir2_dataptr_to_off(state->mp, be32_to_cpu(lep->address))); 2132 xfs_dir2_dataptr_to_off(state->mp, be32_to_cpu(lep->address)));
diff --git a/fs/xfs/xfs_dir2_priv.h b/fs/xfs/xfs_dir2_priv.h
index e6f2e0a7bb65..910e64413316 100644
--- a/fs/xfs/xfs_dir2_priv.h
+++ b/fs/xfs/xfs_dir2_priv.h
@@ -43,17 +43,17 @@ extern int xfs_dir2_leaf_to_block(struct xfs_da_args *args,
43 43
44/* xfs_dir2_data.c */ 44/* xfs_dir2_data.c */
45#ifdef DEBUG 45#ifdef DEBUG
46#define xfs_dir2_data_check(dp,bp) __xfs_dir2_data_check(dp, bp); 46#define xfs_dir3_data_check(dp,bp) __xfs_dir3_data_check(dp, bp);
47#else 47#else
48#define xfs_dir2_data_check(dp,bp) 48#define xfs_dir3_data_check(dp,bp)
49#endif 49#endif
50 50
51extern const struct xfs_buf_ops xfs_dir2_data_buf_ops; 51extern const struct xfs_buf_ops xfs_dir3_data_buf_ops;
52 52
53extern int __xfs_dir2_data_check(struct xfs_inode *dp, struct xfs_buf *bp); 53extern int __xfs_dir3_data_check(struct xfs_inode *dp, struct xfs_buf *bp);
54extern int xfs_dir2_data_read(struct xfs_trans *tp, struct xfs_inode *dp, 54extern int xfs_dir3_data_read(struct xfs_trans *tp, struct xfs_inode *dp,
55 xfs_dablk_t bno, xfs_daddr_t mapped_bno, struct xfs_buf **bpp); 55 xfs_dablk_t bno, xfs_daddr_t mapped_bno, struct xfs_buf **bpp);
56extern int xfs_dir2_data_readahead(struct xfs_trans *tp, struct xfs_inode *dp, 56extern int xfs_dir3_data_readahead(struct xfs_trans *tp, struct xfs_inode *dp,
57 xfs_dablk_t bno, xfs_daddr_t mapped_bno); 57 xfs_dablk_t bno, xfs_daddr_t mapped_bno);
58 58
59extern struct xfs_dir2_data_free * 59extern struct xfs_dir2_data_free *
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index f03bf1a456fb..cf6eacd4169a 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -893,7 +893,7 @@ xfs_dir_open(
893 */ 893 */
894 mode = xfs_ilock_map_shared(ip); 894 mode = xfs_ilock_map_shared(ip);
895 if (ip->i_d.di_nextents > 0) 895 if (ip->i_d.di_nextents > 0)
896 xfs_dir2_data_readahead(NULL, ip, 0, -1); 896 xfs_dir3_data_readahead(NULL, ip, 0, -1);
897 xfs_iunlock(ip, mode); 897 xfs_iunlock(ip, mode);
898 return 0; 898 return 0;
899} 899}