hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/fs/xfs/libxfs/xfs_dir2_data.c
....@@ -6,25 +6,88 @@
66 */
77 #include "xfs.h"
88 #include "xfs_fs.h"
9
+#include "xfs_shared.h"
910 #include "xfs_format.h"
1011 #include "xfs_log_format.h"
1112 #include "xfs_trans_resv.h"
1213 #include "xfs_mount.h"
13
-#include "xfs_da_format.h"
14
-#include "xfs_da_btree.h"
1514 #include "xfs_inode.h"
1615 #include "xfs_dir2.h"
1716 #include "xfs_dir2_priv.h"
1817 #include "xfs_error.h"
1918 #include "xfs_trans.h"
2019 #include "xfs_buf_item.h"
21
-#include "xfs_cksum.h"
2220 #include "xfs_log.h"
2321
2422 static xfs_failaddr_t xfs_dir2_data_freefind_verify(
2523 struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_free *bf,
2624 struct xfs_dir2_data_unused *dup,
2725 struct xfs_dir2_data_free **bf_ent);
26
+
27
+struct xfs_dir2_data_free *
28
+xfs_dir2_data_bestfree_p(
29
+ struct xfs_mount *mp,
30
+ struct xfs_dir2_data_hdr *hdr)
31
+{
32
+ if (xfs_sb_version_hascrc(&mp->m_sb))
33
+ return ((struct xfs_dir3_data_hdr *)hdr)->best_free;
34
+ return hdr->bestfree;
35
+}
36
+
37
+/*
38
+ * Pointer to an entry's tag word.
39
+ */
40
+__be16 *
41
+xfs_dir2_data_entry_tag_p(
42
+ struct xfs_mount *mp,
43
+ struct xfs_dir2_data_entry *dep)
44
+{
45
+ return (__be16 *)((char *)dep +
46
+ xfs_dir2_data_entsize(mp, dep->namelen) - sizeof(__be16));
47
+}
48
+
49
+uint8_t
50
+xfs_dir2_data_get_ftype(
51
+ struct xfs_mount *mp,
52
+ struct xfs_dir2_data_entry *dep)
53
+{
54
+ if (xfs_sb_version_hasftype(&mp->m_sb)) {
55
+ uint8_t ftype = dep->name[dep->namelen];
56
+
57
+ if (likely(ftype < XFS_DIR3_FT_MAX))
58
+ return ftype;
59
+ }
60
+
61
+ return XFS_DIR3_FT_UNKNOWN;
62
+}
63
+
64
+void
65
+xfs_dir2_data_put_ftype(
66
+ struct xfs_mount *mp,
67
+ struct xfs_dir2_data_entry *dep,
68
+ uint8_t ftype)
69
+{
70
+ ASSERT(ftype < XFS_DIR3_FT_MAX);
71
+ ASSERT(dep->namelen != 0);
72
+
73
+ if (xfs_sb_version_hasftype(&mp->m_sb))
74
+ dep->name[dep->namelen] = ftype;
75
+}
76
+
77
+/*
78
+ * The number of leaf entries is limited by the size of the block and the amount
79
+ * of space used by the data entries. We don't know how much space is used by
80
+ * the data entries yet, so just ensure that the count falls somewhere inside
81
+ * the block right now.
82
+ */
83
+static inline unsigned int
84
+xfs_dir2_data_max_leaf_entries(
85
+ struct xfs_da_geometry *geo)
86
+{
87
+ return (geo->blksize - sizeof(struct xfs_dir2_block_tail) -
88
+ geo->data_entry_offset) /
89
+ sizeof(struct xfs_dir2_leaf_entry);
90
+}
2891
2992 /*
3093 * Check the consistency of the data block.
....@@ -41,41 +104,27 @@
41104 xfs_dir2_block_tail_t *btp=NULL; /* block tail */
42105 int count; /* count of entries found */
43106 xfs_dir2_data_hdr_t *hdr; /* data block header */
44
- xfs_dir2_data_entry_t *dep; /* data entry */
45107 xfs_dir2_data_free_t *dfp; /* bestfree entry */
46
- xfs_dir2_data_unused_t *dup; /* unused entry */
47
- char *endp; /* end of useful data */
48108 int freeseen; /* mask of bestfrees seen */
49109 xfs_dahash_t hash; /* hash of current name */
50110 int i; /* leaf index */
51111 int lastfree; /* last entry was unused */
52112 xfs_dir2_leaf_entry_t *lep=NULL; /* block leaf entries */
53
- xfs_mount_t *mp; /* filesystem mount point */
54
- char *p; /* current data position */
113
+ struct xfs_mount *mp = bp->b_mount;
55114 int stale; /* count of stale leaves */
56115 struct xfs_name name;
57
- const struct xfs_dir_ops *ops;
58
- struct xfs_da_geometry *geo;
59
-
60
- mp = bp->b_target->bt_mount;
61
- geo = mp->m_dir_geo;
116
+ unsigned int offset;
117
+ unsigned int end;
118
+ struct xfs_da_geometry *geo = mp->m_dir_geo;
62119
63120 /*
64
- * We can be passed a null dp here from a verifier, so we need to go the
65
- * hard way to get them.
121
+ * If this isn't a directory, something is seriously wrong. Bail out.
66122 */
67
- ops = xfs_dir_get_ops(mp, dp);
68
-
69
- /*
70
- * If this isn't a directory, or we don't get handed the dir ops,
71
- * something is seriously wrong. Bail out.
72
- */
73
- if ((dp && !S_ISDIR(VFS_I(dp)->i_mode)) ||
74
- ops != xfs_dir_get_ops(mp, NULL))
123
+ if (dp && !S_ISDIR(VFS_I(dp)->i_mode))
75124 return __this_address;
76125
77126 hdr = bp->b_addr;
78
- p = (char *)ops->data_entry_p(hdr);
127
+ offset = geo->data_entry_offset;
79128
80129 switch (hdr->magic) {
81130 case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
....@@ -83,15 +132,8 @@
83132 btp = xfs_dir2_block_tail_p(geo, hdr);
84133 lep = xfs_dir2_block_leaf_p(btp);
85134
86
- /*
87
- * The number of leaf entries is limited by the size of the
88
- * block and the amount of space used by the data entries.
89
- * We don't know how much space is used by the data entries yet,
90
- * so just ensure that the count falls somewhere inside the
91
- * block right now.
92
- */
93135 if (be32_to_cpu(btp->count) >=
94
- ((char *)btp - p) / sizeof(struct xfs_dir2_leaf_entry))
136
+ xfs_dir2_data_max_leaf_entries(geo))
95137 return __this_address;
96138 break;
97139 case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
....@@ -100,14 +142,14 @@
100142 default:
101143 return __this_address;
102144 }
103
- endp = xfs_dir3_data_endp(geo, hdr);
104
- if (!endp)
145
+ end = xfs_dir3_data_end_offset(geo, hdr);
146
+ if (!end)
105147 return __this_address;
106148
107149 /*
108150 * Account for zero bestfree entries.
109151 */
110
- bf = ops->data_bestfree_p(hdr);
152
+ bf = xfs_dir2_data_bestfree_p(mp, hdr);
111153 count = lastfree = freeseen = 0;
112154 if (!bf[0].length) {
113155 if (bf[0].offset)
....@@ -132,8 +174,10 @@
132174 /*
133175 * Loop over the data/unused entries.
134176 */
135
- while (p < endp) {
136
- dup = (xfs_dir2_data_unused_t *)p;
177
+ while (offset < end) {
178
+ struct xfs_dir2_data_unused *dup = bp->b_addr + offset;
179
+ struct xfs_dir2_data_entry *dep = bp->b_addr + offset;
180
+
137181 /*
138182 * If it's unused, look for the space in the bestfree table.
139183 * If we find it, account for that, else make sure it
....@@ -144,10 +188,10 @@
144188
145189 if (lastfree != 0)
146190 return __this_address;
147
- if (endp < p + be16_to_cpu(dup->length))
191
+ if (offset + be16_to_cpu(dup->length) > end)
148192 return __this_address;
149193 if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) !=
150
- (char *)dup - (char *)hdr)
194
+ offset)
151195 return __this_address;
152196 fa = xfs_dir2_data_freefind_verify(hdr, bf, dup, &dfp);
153197 if (fa)
....@@ -162,7 +206,7 @@
162206 be16_to_cpu(bf[2].length))
163207 return __this_address;
164208 }
165
- p += be16_to_cpu(dup->length);
209
+ offset += be16_to_cpu(dup->length);
166210 lastfree = 1;
167211 continue;
168212 }
....@@ -172,17 +216,15 @@
172216 * in the leaf section of the block.
173217 * The linear search is crude but this is DEBUG code.
174218 */
175
- dep = (xfs_dir2_data_entry_t *)p;
176219 if (dep->namelen == 0)
177220 return __this_address;
178221 if (xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)))
179222 return __this_address;
180
- if (endp < p + ops->data_entsize(dep->namelen))
223
+ if (offset + xfs_dir2_data_entsize(mp, dep->namelen) > end)
181224 return __this_address;
182
- if (be16_to_cpu(*ops->data_entry_tag_p(dep)) !=
183
- (char *)dep - (char *)hdr)
225
+ if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)) != offset)
184226 return __this_address;
185
- if (ops->data_get_ftype(dep) >= XFS_DIR3_FT_MAX)
227
+ if (xfs_dir2_data_get_ftype(mp, dep) >= XFS_DIR3_FT_MAX)
186228 return __this_address;
187229 count++;
188230 lastfree = 0;
....@@ -193,7 +235,7 @@
193235 ((char *)dep - (char *)hdr));
194236 name.name = dep->name;
195237 name.len = dep->namelen;
196
- hash = mp->m_dirnameops->hashname(&name);
238
+ hash = xfs_dir2_hashname(mp, &name);
197239 for (i = 0; i < be32_to_cpu(btp->count); i++) {
198240 if (be32_to_cpu(lep[i].address) == addr &&
199241 be32_to_cpu(lep[i].hashval) == hash)
....@@ -202,7 +244,7 @@
202244 if (i >= be32_to_cpu(btp->count))
203245 return __this_address;
204246 }
205
- p += ops->data_entsize(dep->namelen);
247
+ offset += xfs_dir2_data_entsize(mp, dep->namelen);
206248 }
207249 /*
208250 * Need to have seen all the entries and all the bestfree slots.
....@@ -249,20 +291,18 @@
249291 xfs_dir3_data_verify(
250292 struct xfs_buf *bp)
251293 {
252
- struct xfs_mount *mp = bp->b_target->bt_mount;
294
+ struct xfs_mount *mp = bp->b_mount;
253295 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
254296
297
+ if (!xfs_verify_magic(bp, hdr3->magic))
298
+ return __this_address;
299
+
255300 if (xfs_sb_version_hascrc(&mp->m_sb)) {
256
- if (hdr3->magic != cpu_to_be32(XFS_DIR3_DATA_MAGIC))
257
- return __this_address;
258301 if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid))
259302 return __this_address;
260303 if (be64_to_cpu(hdr3->blkno) != bp->b_bn)
261304 return __this_address;
262305 if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn)))
263
- return __this_address;
264
- } else {
265
- if (hdr3->magic != cpu_to_be32(XFS_DIR2_DATA_MAGIC))
266306 return __this_address;
267307 }
268308 return __xfs_dir3_data_check(NULL, bp);
....@@ -300,7 +340,7 @@
300340 xfs_dir3_data_read_verify(
301341 struct xfs_buf *bp)
302342 {
303
- struct xfs_mount *mp = bp->b_target->bt_mount;
343
+ struct xfs_mount *mp = bp->b_mount;
304344 xfs_failaddr_t fa;
305345
306346 if (xfs_sb_version_hascrc(&mp->m_sb) &&
....@@ -317,7 +357,7 @@
317357 xfs_dir3_data_write_verify(
318358 struct xfs_buf *bp)
319359 {
320
- struct xfs_mount *mp = bp->b_target->bt_mount;
360
+ struct xfs_mount *mp = bp->b_mount;
321361 struct xfs_buf_log_item *bip = bp->b_log_item;
322362 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
323363 xfs_failaddr_t fa;
....@@ -339,6 +379,8 @@
339379
340380 const struct xfs_buf_ops xfs_dir3_data_buf_ops = {
341381 .name = "xfs_dir3_data",
382
+ .magic = { cpu_to_be32(XFS_DIR2_DATA_MAGIC),
383
+ cpu_to_be32(XFS_DIR3_DATA_MAGIC) },
342384 .verify_read = xfs_dir3_data_read_verify,
343385 .verify_write = xfs_dir3_data_write_verify,
344386 .verify_struct = xfs_dir3_data_verify,
....@@ -346,25 +388,55 @@
346388
347389 static const struct xfs_buf_ops xfs_dir3_data_reada_buf_ops = {
348390 .name = "xfs_dir3_data_reada",
391
+ .magic = { cpu_to_be32(XFS_DIR2_DATA_MAGIC),
392
+ cpu_to_be32(XFS_DIR3_DATA_MAGIC) },
349393 .verify_read = xfs_dir3_data_reada_verify,
350394 .verify_write = xfs_dir3_data_write_verify,
351395 };
352396
397
+static xfs_failaddr_t
398
+xfs_dir3_data_header_check(
399
+ struct xfs_inode *dp,
400
+ struct xfs_buf *bp)
401
+{
402
+ struct xfs_mount *mp = dp->i_mount;
403
+
404
+ if (xfs_sb_version_hascrc(&mp->m_sb)) {
405
+ struct xfs_dir3_data_hdr *hdr3 = bp->b_addr;
406
+
407
+ if (be64_to_cpu(hdr3->hdr.owner) != dp->i_ino)
408
+ return __this_address;
409
+ }
410
+
411
+ return NULL;
412
+}
353413
354414 int
355415 xfs_dir3_data_read(
356416 struct xfs_trans *tp,
357417 struct xfs_inode *dp,
358418 xfs_dablk_t bno,
359
- xfs_daddr_t mapped_bno,
419
+ unsigned int flags,
360420 struct xfs_buf **bpp)
361421 {
422
+ xfs_failaddr_t fa;
362423 int err;
363424
364
- err = xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp,
365
- XFS_DATA_FORK, &xfs_dir3_data_buf_ops);
366
- if (!err && tp && *bpp)
367
- xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_DATA_BUF);
425
+ err = xfs_da_read_buf(tp, dp, bno, flags, bpp, XFS_DATA_FORK,
426
+ &xfs_dir3_data_buf_ops);
427
+ if (err || !*bpp)
428
+ return err;
429
+
430
+ /* Check things that we can't do in the verifier. */
431
+ fa = xfs_dir3_data_header_check(dp, *bpp);
432
+ if (fa) {
433
+ __xfs_buf_mark_corrupt(*bpp, fa);
434
+ xfs_trans_brelse(tp, *bpp);
435
+ *bpp = NULL;
436
+ return -EFSCORRUPTED;
437
+ }
438
+
439
+ xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_DATA_BUF);
368440 return err;
369441 }
370442
....@@ -372,10 +444,10 @@
372444 xfs_dir3_data_readahead(
373445 struct xfs_inode *dp,
374446 xfs_dablk_t bno,
375
- xfs_daddr_t mapped_bno)
447
+ unsigned int flags)
376448 {
377
- return xfs_da_reada_buf(dp, bno, mapped_bno,
378
- XFS_DATA_FORK, &xfs_dir3_data_reada_buf_ops);
449
+ return xfs_da_reada_buf(dp, bno, flags, XFS_DATA_FORK,
450
+ &xfs_dir3_data_reada_buf_ops);
379451 }
380452
381453 /*
....@@ -563,17 +635,16 @@
563635 * Given a data block, reconstruct its bestfree map.
564636 */
565637 void
566
-xfs_dir2_data_freescan_int(
567
- struct xfs_da_geometry *geo,
568
- const struct xfs_dir_ops *ops,
569
- struct xfs_dir2_data_hdr *hdr,
570
- int *loghead)
638
+xfs_dir2_data_freescan(
639
+ struct xfs_mount *mp,
640
+ struct xfs_dir2_data_hdr *hdr,
641
+ int *loghead)
571642 {
572
- xfs_dir2_data_entry_t *dep; /* active data entry */
573
- xfs_dir2_data_unused_t *dup; /* unused data entry */
574
- struct xfs_dir2_data_free *bf;
575
- char *endp; /* end of block's data */
576
- char *p; /* current entry pointer */
643
+ struct xfs_da_geometry *geo = mp->m_dir_geo;
644
+ struct xfs_dir2_data_free *bf = xfs_dir2_data_bestfree_p(mp, hdr);
645
+ void *addr = hdr;
646
+ unsigned int offset = geo->data_entry_offset;
647
+ unsigned int end;
577648
578649 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
579650 hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
....@@ -583,48 +654,32 @@
583654 /*
584655 * Start by clearing the table.
585656 */
586
- bf = ops->data_bestfree_p(hdr);
587657 memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT);
588658 *loghead = 1;
589
- /*
590
- * Set up pointers.
591
- */
592
- p = (char *)ops->data_entry_p(hdr);
593
- endp = xfs_dir3_data_endp(geo, hdr);
594
- /*
595
- * Loop over the block's entries.
596
- */
597
- while (p < endp) {
598
- dup = (xfs_dir2_data_unused_t *)p;
659
+
660
+ end = xfs_dir3_data_end_offset(geo, addr);
661
+ while (offset < end) {
662
+ struct xfs_dir2_data_unused *dup = addr + offset;
663
+ struct xfs_dir2_data_entry *dep = addr + offset;
664
+
599665 /*
600666 * If it's a free entry, insert it.
601667 */
602668 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
603
- ASSERT((char *)dup - (char *)hdr ==
669
+ ASSERT(offset ==
604670 be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)));
605671 xfs_dir2_data_freeinsert(hdr, bf, dup, loghead);
606
- p += be16_to_cpu(dup->length);
672
+ offset += be16_to_cpu(dup->length);
673
+ continue;
607674 }
675
+
608676 /*
609677 * For active entries, check their tags and skip them.
610678 */
611
- else {
612
- dep = (xfs_dir2_data_entry_t *)p;
613
- ASSERT((char *)dep - (char *)hdr ==
614
- be16_to_cpu(*ops->data_entry_tag_p(dep)));
615
- p += ops->data_entsize(dep->namelen);
616
- }
679
+ ASSERT(offset ==
680
+ be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)));
681
+ offset += xfs_dir2_data_entsize(mp, dep->namelen);
617682 }
618
-}
619
-
620
-void
621
-xfs_dir2_data_freescan(
622
- struct xfs_inode *dp,
623
- struct xfs_dir2_data_hdr *hdr,
624
- int *loghead)
625
-{
626
- return xfs_dir2_data_freescan_int(dp->i_mount->m_dir_geo, dp->d_ops,
627
- hdr, loghead);
628683 }
629684
630685 /*
....@@ -633,29 +688,26 @@
633688 */
634689 int /* error */
635690 xfs_dir3_data_init(
636
- xfs_da_args_t *args, /* directory operation args */
637
- xfs_dir2_db_t blkno, /* logical dir block number */
638
- struct xfs_buf **bpp) /* output block buffer */
691
+ struct xfs_da_args *args, /* directory operation args */
692
+ xfs_dir2_db_t blkno, /* logical dir block number */
693
+ struct xfs_buf **bpp) /* output block buffer */
639694 {
640
- struct xfs_buf *bp; /* block buffer */
641
- xfs_dir2_data_hdr_t *hdr; /* data block header */
642
- xfs_inode_t *dp; /* incore directory inode */
643
- xfs_dir2_data_unused_t *dup; /* unused entry pointer */
644
- struct xfs_dir2_data_free *bf;
645
- int error; /* error return value */
646
- int i; /* bestfree index */
647
- xfs_mount_t *mp; /* filesystem mount point */
648
- xfs_trans_t *tp; /* transaction pointer */
649
- int t; /* temp */
695
+ struct xfs_trans *tp = args->trans;
696
+ struct xfs_inode *dp = args->dp;
697
+ struct xfs_mount *mp = dp->i_mount;
698
+ struct xfs_da_geometry *geo = args->geo;
699
+ struct xfs_buf *bp;
700
+ struct xfs_dir2_data_hdr *hdr;
701
+ struct xfs_dir2_data_unused *dup;
702
+ struct xfs_dir2_data_free *bf;
703
+ int error;
704
+ int i;
650705
651
- dp = args->dp;
652
- mp = dp->i_mount;
653
- tp = args->trans;
654706 /*
655707 * Get the buffer set up for the block.
656708 */
657709 error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, blkno),
658
- -1, &bp, XFS_DATA_FORK);
710
+ &bp, XFS_DATA_FORK);
659711 if (error)
660712 return error;
661713 bp->b_ops = &xfs_dir3_data_buf_ops;
....@@ -677,8 +729,9 @@
677729 } else
678730 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
679731
680
- bf = dp->d_ops->data_bestfree_p(hdr);
681
- bf[0].offset = cpu_to_be16(dp->d_ops->data_entry_offset);
732
+ bf = xfs_dir2_data_bestfree_p(mp, hdr);
733
+ bf[0].offset = cpu_to_be16(geo->data_entry_offset);
734
+ bf[0].length = cpu_to_be16(geo->blksize - geo->data_entry_offset);
682735 for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
683736 bf[i].length = 0;
684737 bf[i].offset = 0;
....@@ -687,13 +740,11 @@
687740 /*
688741 * Set up an unused entry for the block's body.
689742 */
690
- dup = dp->d_ops->data_unused_p(hdr);
743
+ dup = bp->b_addr + geo->data_entry_offset;
691744 dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
692
-
693
- t = args->geo->blksize - (uint)dp->d_ops->data_entry_offset;
694
- bf[0].length = cpu_to_be16(t);
695
- dup->length = cpu_to_be16(t);
745
+ dup->length = bf[0].length;
696746 *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr);
747
+
697748 /*
698749 * Log it and return it.
699750 */
....@@ -712,6 +763,7 @@
712763 struct xfs_buf *bp,
713764 xfs_dir2_data_entry_t *dep) /* data entry pointer */
714765 {
766
+ struct xfs_mount *mp = bp->b_mount;
715767 struct xfs_dir2_data_hdr *hdr = bp->b_addr;
716768
717769 ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
....@@ -720,7 +772,7 @@
720772 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
721773
722774 xfs_trans_log_buf(args->trans, bp, (uint)((char *)dep - (char *)hdr),
723
- (uint)((char *)(args->dp->d_ops->data_entry_tag_p(dep) + 1) -
775
+ (uint)((char *)(xfs_dir2_data_entry_tag_p(mp, dep) + 1) -
724776 (char *)hdr - 1));
725777 }
726778
....@@ -741,8 +793,7 @@
741793 hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
742794 #endif
743795
744
- xfs_trans_log_buf(args->trans, bp, 0,
745
- args->dp->d_ops->data_entry_offset - 1);
796
+ xfs_trans_log_buf(args->trans, bp, 0, args->geo->data_entry_offset - 1);
746797 }
747798
748799 /*
....@@ -791,11 +842,11 @@
791842 {
792843 xfs_dir2_data_hdr_t *hdr; /* data block pointer */
793844 xfs_dir2_data_free_t *dfp; /* bestfree pointer */
794
- char *endptr; /* end of data area */
795845 int needscan; /* need to regen bestfree */
796846 xfs_dir2_data_unused_t *newdup; /* new unused entry */
797847 xfs_dir2_data_unused_t *postdup; /* unused entry after us */
798848 xfs_dir2_data_unused_t *prevdup; /* unused entry before us */
849
+ unsigned int end;
799850 struct xfs_dir2_data_free *bf;
800851
801852 hdr = bp->b_addr;
....@@ -803,14 +854,14 @@
803854 /*
804855 * Figure out where the end of the data area is.
805856 */
806
- endptr = xfs_dir3_data_endp(args->geo, hdr);
807
- ASSERT(endptr != NULL);
857
+ end = xfs_dir3_data_end_offset(args->geo, hdr);
858
+ ASSERT(end != 0);
808859
809860 /*
810861 * If this isn't the start of the block, then back up to
811862 * the previous entry and see if it's free.
812863 */
813
- if (offset > args->dp->d_ops->data_entry_offset) {
864
+ if (offset > args->geo->data_entry_offset) {
814865 __be16 *tagp; /* tag just before us */
815866
816867 tagp = (__be16 *)((char *)hdr + offset) - 1;
....@@ -823,7 +874,7 @@
823874 * If this isn't the end of the block, see if the entry after
824875 * us is free.
825876 */
826
- if ((char *)hdr + offset + len < endptr) {
877
+ if (offset + len < end) {
827878 postdup =
828879 (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
829880 if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
....@@ -836,7 +887,7 @@
836887 * Previous and following entries are both free,
837888 * merge everything into a single free entry.
838889 */
839
- bf = args->dp->d_ops->data_bestfree_p(hdr);
890
+ bf = xfs_dir2_data_bestfree_p(args->dp->i_mount, hdr);
840891 if (prevdup && postdup) {
841892 xfs_dir2_data_free_t *dfp2; /* another bestfree pointer */
842893
....@@ -1027,7 +1078,7 @@
10271078 * Look up the entry in the bestfree table.
10281079 */
10291080 oldlen = be16_to_cpu(dup->length);
1030
- bf = args->dp->d_ops->data_bestfree_p(hdr);
1081
+ bf = xfs_dir2_data_bestfree_p(args->dp->i_mount, hdr);
10311082 dfp = xfs_dir2_data_freefind(hdr, bf, dup);
10321083 ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length));
10331084 /*
....@@ -1151,19 +1202,22 @@
11511202 }
11521203
11531204 /* Find the end of the entry data in a data/block format dir block. */
1154
-void *
1155
-xfs_dir3_data_endp(
1205
+unsigned int
1206
+xfs_dir3_data_end_offset(
11561207 struct xfs_da_geometry *geo,
11571208 struct xfs_dir2_data_hdr *hdr)
11581209 {
1210
+ void *p;
1211
+
11591212 switch (hdr->magic) {
11601213 case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
11611214 case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
1162
- return xfs_dir2_block_leaf_p(xfs_dir2_block_tail_p(geo, hdr));
1215
+ p = xfs_dir2_block_leaf_p(xfs_dir2_block_tail_p(geo, hdr));
1216
+ return p - (void *)hdr;
11631217 case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
11641218 case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
1165
- return (char *)hdr + geo->blksize;
1219
+ return geo->blksize;
11661220 default:
1167
- return NULL;
1221
+ return 0;
11681222 }
11691223 }