GNU Linux-libre 6.9-gnu
[releases.git] / fs / xfs / libxfs / xfs_dir2_data.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
4  * Copyright (c) 2013 Red Hat, Inc.
5  * All Rights Reserved.
6  */
7 #include "xfs.h"
8 #include "xfs_fs.h"
9 #include "xfs_shared.h"
10 #include "xfs_format.h"
11 #include "xfs_log_format.h"
12 #include "xfs_trans_resv.h"
13 #include "xfs_mount.h"
14 #include "xfs_inode.h"
15 #include "xfs_dir2.h"
16 #include "xfs_dir2_priv.h"
17 #include "xfs_error.h"
18 #include "xfs_trans.h"
19 #include "xfs_buf_item.h"
20 #include "xfs_log.h"
21 #include "xfs_health.h"
22
23 static xfs_failaddr_t xfs_dir2_data_freefind_verify(
24                 struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_free *bf,
25                 struct xfs_dir2_data_unused *dup,
26                 struct xfs_dir2_data_free **bf_ent);
27
28 struct xfs_dir2_data_free *
29 xfs_dir2_data_bestfree_p(
30         struct xfs_mount                *mp,
31         struct xfs_dir2_data_hdr        *hdr)
32 {
33         if (xfs_has_crc(mp))
34                 return ((struct xfs_dir3_data_hdr *)hdr)->best_free;
35         return hdr->bestfree;
36 }
37
38 /*
39  * Pointer to an entry's tag word.
40  */
41 __be16 *
42 xfs_dir2_data_entry_tag_p(
43         struct xfs_mount                *mp,
44         struct xfs_dir2_data_entry      *dep)
45 {
46         return (__be16 *)((char *)dep +
47                 xfs_dir2_data_entsize(mp, dep->namelen) - sizeof(__be16));
48 }
49
50 uint8_t
51 xfs_dir2_data_get_ftype(
52         struct xfs_mount                *mp,
53         struct xfs_dir2_data_entry      *dep)
54 {
55         if (xfs_has_ftype(mp)) {
56                 uint8_t                 ftype = dep->name[dep->namelen];
57
58                 if (likely(ftype < XFS_DIR3_FT_MAX))
59                         return ftype;
60         }
61
62         return XFS_DIR3_FT_UNKNOWN;
63 }
64
65 void
66 xfs_dir2_data_put_ftype(
67         struct xfs_mount                *mp,
68         struct xfs_dir2_data_entry      *dep,
69         uint8_t                         ftype)
70 {
71         ASSERT(ftype < XFS_DIR3_FT_MAX);
72         ASSERT(dep->namelen != 0);
73
74         if (xfs_has_ftype(mp))
75                 dep->name[dep->namelen] = ftype;
76 }
77
78 /*
79  * The number of leaf entries is limited by the size of the block and the amount
80  * of space used by the data entries.  We don't know how much space is used by
81  * the data entries yet, so just ensure that the count falls somewhere inside
82  * the block right now.
83  */
84 static inline unsigned int
85 xfs_dir2_data_max_leaf_entries(
86         struct xfs_da_geometry          *geo)
87 {
88         return (geo->blksize - sizeof(struct xfs_dir2_block_tail) -
89                 geo->data_entry_offset) /
90                         sizeof(struct xfs_dir2_leaf_entry);
91 }
92
93 /*
94  * Check the consistency of the data block.
95  * The input can also be a block-format directory.
96  * Return NULL if the buffer is good, otherwise the address of the error.
97  */
98 xfs_failaddr_t
99 __xfs_dir3_data_check(
100         struct xfs_inode        *dp,            /* incore inode pointer */
101         struct xfs_buf          *bp)            /* data block's buffer */
102 {
103         xfs_dir2_dataptr_t      addr;           /* addr for leaf lookup */
104         xfs_dir2_data_free_t    *bf;            /* bestfree table */
105         xfs_dir2_block_tail_t   *btp=NULL;      /* block tail */
106         int                     count;          /* count of entries found */
107         xfs_dir2_data_hdr_t     *hdr;           /* data block header */
108         xfs_dir2_data_free_t    *dfp;           /* bestfree entry */
109         int                     freeseen;       /* mask of bestfrees seen */
110         xfs_dahash_t            hash;           /* hash of current name */
111         int                     i;              /* leaf index */
112         int                     lastfree;       /* last entry was unused */
113         xfs_dir2_leaf_entry_t   *lep=NULL;      /* block leaf entries */
114         struct xfs_mount        *mp = bp->b_mount;
115         int                     stale;          /* count of stale leaves */
116         struct xfs_name         name;
117         unsigned int            offset;
118         unsigned int            end;
119         struct xfs_da_geometry  *geo = mp->m_dir_geo;
120
121         /*
122          * If this isn't a directory, something is seriously wrong.  Bail out.
123          */
124         if (dp && !S_ISDIR(VFS_I(dp)->i_mode))
125                 return __this_address;
126
127         hdr = bp->b_addr;
128         offset = geo->data_entry_offset;
129
130         switch (hdr->magic) {
131         case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
132         case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
133                 btp = xfs_dir2_block_tail_p(geo, hdr);
134                 lep = xfs_dir2_block_leaf_p(btp);
135
136                 if (be32_to_cpu(btp->count) >=
137                     xfs_dir2_data_max_leaf_entries(geo))
138                         return __this_address;
139                 break;
140         case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
141         case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
142                 break;
143         default:
144                 return __this_address;
145         }
146         end = xfs_dir3_data_end_offset(geo, hdr);
147         if (!end)
148                 return __this_address;
149
150         /*
151          * Account for zero bestfree entries.
152          */
153         bf = xfs_dir2_data_bestfree_p(mp, hdr);
154         count = lastfree = freeseen = 0;
155         if (!bf[0].length) {
156                 if (bf[0].offset)
157                         return __this_address;
158                 freeseen |= 1 << 0;
159         }
160         if (!bf[1].length) {
161                 if (bf[1].offset)
162                         return __this_address;
163                 freeseen |= 1 << 1;
164         }
165         if (!bf[2].length) {
166                 if (bf[2].offset)
167                         return __this_address;
168                 freeseen |= 1 << 2;
169         }
170
171         if (be16_to_cpu(bf[0].length) < be16_to_cpu(bf[1].length))
172                 return __this_address;
173         if (be16_to_cpu(bf[1].length) < be16_to_cpu(bf[2].length))
174                 return __this_address;
175         /*
176          * Loop over the data/unused entries.
177          */
178         while (offset < end) {
179                 struct xfs_dir2_data_unused     *dup = bp->b_addr + offset;
180                 struct xfs_dir2_data_entry      *dep = bp->b_addr + offset;
181
182                 /*
183                  * If it's unused, look for the space in the bestfree table.
184                  * If we find it, account for that, else make sure it
185                  * doesn't need to be there.
186                  */
187                 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
188                         xfs_failaddr_t  fa;
189
190                         if (lastfree != 0)
191                                 return __this_address;
192                         if (offset + be16_to_cpu(dup->length) > end)
193                                 return __this_address;
194                         if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) !=
195                             offset)
196                                 return __this_address;
197                         fa = xfs_dir2_data_freefind_verify(hdr, bf, dup, &dfp);
198                         if (fa)
199                                 return fa;
200                         if (dfp) {
201                                 i = (int)(dfp - bf);
202                                 if ((freeseen & (1 << i)) != 0)
203                                         return __this_address;
204                                 freeseen |= 1 << i;
205                         } else {
206                                 if (be16_to_cpu(dup->length) >
207                                     be16_to_cpu(bf[2].length))
208                                         return __this_address;
209                         }
210                         offset += be16_to_cpu(dup->length);
211                         lastfree = 1;
212                         continue;
213                 }
214                 /*
215                  * It's a real entry.  Validate the fields.
216                  * If this is a block directory then make sure it's
217                  * in the leaf section of the block.
218                  * The linear search is crude but this is DEBUG code.
219                  */
220                 if (dep->namelen == 0)
221                         return __this_address;
222                 if (!xfs_verify_dir_ino(mp, be64_to_cpu(dep->inumber)))
223                         return __this_address;
224                 if (offset + xfs_dir2_data_entsize(mp, dep->namelen) > end)
225                         return __this_address;
226                 if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)) != offset)
227                         return __this_address;
228                 if (xfs_dir2_data_get_ftype(mp, dep) >= XFS_DIR3_FT_MAX)
229                         return __this_address;
230                 count++;
231                 lastfree = 0;
232                 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
233                     hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
234                         addr = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
235                                                 (xfs_dir2_data_aoff_t)
236                                                 ((char *)dep - (char *)hdr));
237                         name.name = dep->name;
238                         name.len = dep->namelen;
239                         hash = xfs_dir2_hashname(mp, &name);
240                         for (i = 0; i < be32_to_cpu(btp->count); i++) {
241                                 if (be32_to_cpu(lep[i].address) == addr &&
242                                     be32_to_cpu(lep[i].hashval) == hash)
243                                         break;
244                         }
245                         if (i >= be32_to_cpu(btp->count))
246                                 return __this_address;
247                 }
248                 offset += xfs_dir2_data_entsize(mp, dep->namelen);
249         }
250         /*
251          * Need to have seen all the entries and all the bestfree slots.
252          */
253         if (freeseen != 7)
254                 return __this_address;
255         if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
256             hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
257                 for (i = stale = 0; i < be32_to_cpu(btp->count); i++) {
258                         if (lep[i].address ==
259                             cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
260                                 stale++;
261                         if (i > 0 && be32_to_cpu(lep[i].hashval) <
262                                      be32_to_cpu(lep[i - 1].hashval))
263                                 return __this_address;
264                 }
265                 if (count != be32_to_cpu(btp->count) - be32_to_cpu(btp->stale))
266                         return __this_address;
267                 if (stale != be32_to_cpu(btp->stale))
268                         return __this_address;
269         }
270         return NULL;
271 }
272
273 #ifdef DEBUG
274 void
275 xfs_dir3_data_check(
276         struct xfs_inode        *dp,
277         struct xfs_buf          *bp)
278 {
279         xfs_failaddr_t          fa;
280
281         fa = __xfs_dir3_data_check(dp, bp);
282         if (!fa)
283                 return;
284         xfs_corruption_error(__func__, XFS_ERRLEVEL_LOW, dp->i_mount,
285                         bp->b_addr, BBTOB(bp->b_length), __FILE__, __LINE__,
286                         fa);
287         ASSERT(0);
288 }
289 #endif
290
291 static xfs_failaddr_t
292 xfs_dir3_data_verify(
293         struct xfs_buf          *bp)
294 {
295         struct xfs_mount        *mp = bp->b_mount;
296         struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
297
298         if (!xfs_verify_magic(bp, hdr3->magic))
299                 return __this_address;
300
301         if (xfs_has_crc(mp)) {
302                 if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid))
303                         return __this_address;
304                 if (be64_to_cpu(hdr3->blkno) != xfs_buf_daddr(bp))
305                         return __this_address;
306                 if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn)))
307                         return __this_address;
308         }
309         return __xfs_dir3_data_check(NULL, bp);
310 }
311
312 /*
313  * Readahead of the first block of the directory when it is opened is completely
314  * oblivious to the format of the directory. Hence we can either get a block
315  * format buffer or a data format buffer on readahead.
316  */
317 static void
318 xfs_dir3_data_reada_verify(
319         struct xfs_buf          *bp)
320 {
321         struct xfs_dir2_data_hdr *hdr = bp->b_addr;
322
323         switch (hdr->magic) {
324         case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
325         case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
326                 bp->b_ops = &xfs_dir3_block_buf_ops;
327                 bp->b_ops->verify_read(bp);
328                 return;
329         case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
330         case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
331                 bp->b_ops = &xfs_dir3_data_buf_ops;
332                 bp->b_ops->verify_read(bp);
333                 return;
334         default:
335                 xfs_verifier_error(bp, -EFSCORRUPTED, __this_address);
336                 break;
337         }
338 }
339
340 static void
341 xfs_dir3_data_read_verify(
342         struct xfs_buf  *bp)
343 {
344         struct xfs_mount        *mp = bp->b_mount;
345         xfs_failaddr_t          fa;
346
347         if (xfs_has_crc(mp) &&
348             !xfs_buf_verify_cksum(bp, XFS_DIR3_DATA_CRC_OFF))
349                 xfs_verifier_error(bp, -EFSBADCRC, __this_address);
350         else {
351                 fa = xfs_dir3_data_verify(bp);
352                 if (fa)
353                         xfs_verifier_error(bp, -EFSCORRUPTED, fa);
354         }
355 }
356
357 static void
358 xfs_dir3_data_write_verify(
359         struct xfs_buf  *bp)
360 {
361         struct xfs_mount        *mp = bp->b_mount;
362         struct xfs_buf_log_item *bip = bp->b_log_item;
363         struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
364         xfs_failaddr_t          fa;
365
366         fa = xfs_dir3_data_verify(bp);
367         if (fa) {
368                 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
369                 return;
370         }
371
372         if (!xfs_has_crc(mp))
373                 return;
374
375         if (bip)
376                 hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
377
378         xfs_buf_update_cksum(bp, XFS_DIR3_DATA_CRC_OFF);
379 }
380
381 const struct xfs_buf_ops xfs_dir3_data_buf_ops = {
382         .name = "xfs_dir3_data",
383         .magic = { cpu_to_be32(XFS_DIR2_DATA_MAGIC),
384                    cpu_to_be32(XFS_DIR3_DATA_MAGIC) },
385         .verify_read = xfs_dir3_data_read_verify,
386         .verify_write = xfs_dir3_data_write_verify,
387         .verify_struct = xfs_dir3_data_verify,
388 };
389
390 static const struct xfs_buf_ops xfs_dir3_data_reada_buf_ops = {
391         .name = "xfs_dir3_data_reada",
392         .magic = { cpu_to_be32(XFS_DIR2_DATA_MAGIC),
393                    cpu_to_be32(XFS_DIR3_DATA_MAGIC) },
394         .verify_read = xfs_dir3_data_reada_verify,
395         .verify_write = xfs_dir3_data_write_verify,
396 };
397
398 static xfs_failaddr_t
399 xfs_dir3_data_header_check(
400         struct xfs_inode        *dp,
401         struct xfs_buf          *bp)
402 {
403         struct xfs_mount        *mp = dp->i_mount;
404
405         if (xfs_has_crc(mp)) {
406                 struct xfs_dir3_data_hdr *hdr3 = bp->b_addr;
407
408                 if (be64_to_cpu(hdr3->hdr.owner) != dp->i_ino)
409                         return __this_address;
410         }
411
412         return NULL;
413 }
414
415 int
416 xfs_dir3_data_read(
417         struct xfs_trans        *tp,
418         struct xfs_inode        *dp,
419         xfs_dablk_t             bno,
420         unsigned int            flags,
421         struct xfs_buf          **bpp)
422 {
423         xfs_failaddr_t          fa;
424         int                     err;
425
426         err = xfs_da_read_buf(tp, dp, bno, flags, bpp, XFS_DATA_FORK,
427                         &xfs_dir3_data_buf_ops);
428         if (err || !*bpp)
429                 return err;
430
431         /* Check things that we can't do in the verifier. */
432         fa = xfs_dir3_data_header_check(dp, *bpp);
433         if (fa) {
434                 __xfs_buf_mark_corrupt(*bpp, fa);
435                 xfs_trans_brelse(tp, *bpp);
436                 *bpp = NULL;
437                 xfs_dirattr_mark_sick(dp, XFS_DATA_FORK);
438                 return -EFSCORRUPTED;
439         }
440
441         xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_DATA_BUF);
442         return err;
443 }
444
445 int
446 xfs_dir3_data_readahead(
447         struct xfs_inode        *dp,
448         xfs_dablk_t             bno,
449         unsigned int            flags)
450 {
451         return xfs_da_reada_buf(dp, bno, flags, XFS_DATA_FORK,
452                                 &xfs_dir3_data_reada_buf_ops);
453 }
454
455 /*
456  * Find the bestfree entry that exactly coincides with unused directory space
457  * or a verifier error because the bestfree data are bad.
458  */
459 static xfs_failaddr_t
460 xfs_dir2_data_freefind_verify(
461         struct xfs_dir2_data_hdr        *hdr,
462         struct xfs_dir2_data_free       *bf,
463         struct xfs_dir2_data_unused     *dup,
464         struct xfs_dir2_data_free       **bf_ent)
465 {
466         struct xfs_dir2_data_free       *dfp;
467         xfs_dir2_data_aoff_t            off;
468         bool                            matched = false;
469         bool                            seenzero = false;
470
471         *bf_ent = NULL;
472         off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr);
473
474         /*
475          * Validate some consistency in the bestfree table.
476          * Check order, non-overlapping entries, and if we find the
477          * one we're looking for it has to be exact.
478          */
479         for (dfp = &bf[0]; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) {
480                 if (!dfp->offset) {
481                         if (dfp->length)
482                                 return __this_address;
483                         seenzero = true;
484                         continue;
485                 }
486                 if (seenzero)
487                         return __this_address;
488                 if (be16_to_cpu(dfp->offset) == off) {
489                         matched = true;
490                         if (dfp->length != dup->length)
491                                 return __this_address;
492                 } else if (be16_to_cpu(dfp->offset) > off) {
493                         if (off + be16_to_cpu(dup->length) >
494                                         be16_to_cpu(dfp->offset))
495                                 return __this_address;
496                 } else {
497                         if (be16_to_cpu(dfp->offset) +
498                                         be16_to_cpu(dfp->length) > off)
499                                 return __this_address;
500                 }
501                 if (!matched &&
502                     be16_to_cpu(dfp->length) < be16_to_cpu(dup->length))
503                         return __this_address;
504                 if (dfp > &bf[0] &&
505                     be16_to_cpu(dfp[-1].length) < be16_to_cpu(dfp[0].length))
506                         return __this_address;
507         }
508
509         /* Looks ok so far; now try to match up with a bestfree entry. */
510         *bf_ent = xfs_dir2_data_freefind(hdr, bf, dup);
511         return NULL;
512 }
513
514 /*
515  * Given a data block and an unused entry from that block,
516  * return the bestfree entry if any that corresponds to it.
517  */
518 xfs_dir2_data_free_t *
519 xfs_dir2_data_freefind(
520         struct xfs_dir2_data_hdr *hdr,          /* data block header */
521         struct xfs_dir2_data_free *bf,          /* bestfree table pointer */
522         struct xfs_dir2_data_unused *dup)       /* unused space */
523 {
524         xfs_dir2_data_free_t    *dfp;           /* bestfree entry */
525         xfs_dir2_data_aoff_t    off;            /* offset value needed */
526
527         off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr);
528
529         /*
530          * If this is smaller than the smallest bestfree entry,
531          * it can't be there since they're sorted.
532          */
533         if (be16_to_cpu(dup->length) <
534             be16_to_cpu(bf[XFS_DIR2_DATA_FD_COUNT - 1].length))
535                 return NULL;
536         /*
537          * Look at the three bestfree entries for our guy.
538          */
539         for (dfp = &bf[0]; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) {
540                 if (!dfp->offset)
541                         return NULL;
542                 if (be16_to_cpu(dfp->offset) == off)
543                         return dfp;
544         }
545         /*
546          * Didn't find it.  This only happens if there are duplicate lengths.
547          */
548         return NULL;
549 }
550
551 /*
552  * Insert an unused-space entry into the bestfree table.
553  */
554 xfs_dir2_data_free_t *                          /* entry inserted */
555 xfs_dir2_data_freeinsert(
556         struct xfs_dir2_data_hdr *hdr,          /* data block pointer */
557         struct xfs_dir2_data_free *dfp,         /* bestfree table pointer */
558         struct xfs_dir2_data_unused *dup,       /* unused space */
559         int                     *loghead)       /* log the data header (out) */
560 {
561         xfs_dir2_data_free_t    new;            /* new bestfree entry */
562
563         ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
564                hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
565                hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
566                hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
567
568         new.length = dup->length;
569         new.offset = cpu_to_be16((char *)dup - (char *)hdr);
570
571         /*
572          * Insert at position 0, 1, or 2; or not at all.
573          */
574         if (be16_to_cpu(new.length) > be16_to_cpu(dfp[0].length)) {
575                 dfp[2] = dfp[1];
576                 dfp[1] = dfp[0];
577                 dfp[0] = new;
578                 *loghead = 1;
579                 return &dfp[0];
580         }
581         if (be16_to_cpu(new.length) > be16_to_cpu(dfp[1].length)) {
582                 dfp[2] = dfp[1];
583                 dfp[1] = new;
584                 *loghead = 1;
585                 return &dfp[1];
586         }
587         if (be16_to_cpu(new.length) > be16_to_cpu(dfp[2].length)) {
588                 dfp[2] = new;
589                 *loghead = 1;
590                 return &dfp[2];
591         }
592         return NULL;
593 }
594
595 /*
596  * Remove a bestfree entry from the table.
597  */
598 STATIC void
599 xfs_dir2_data_freeremove(
600         struct xfs_dir2_data_hdr *hdr,          /* data block header */
601         struct xfs_dir2_data_free *bf,          /* bestfree table pointer */
602         struct xfs_dir2_data_free *dfp,         /* bestfree entry pointer */
603         int                     *loghead)       /* out: log data header */
604 {
605
606         ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
607                hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
608                hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
609                hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
610
611         /*
612          * It's the first entry, slide the next 2 up.
613          */
614         if (dfp == &bf[0]) {
615                 bf[0] = bf[1];
616                 bf[1] = bf[2];
617         }
618         /*
619          * It's the second entry, slide the 3rd entry up.
620          */
621         else if (dfp == &bf[1])
622                 bf[1] = bf[2];
623         /*
624          * Must be the last entry.
625          */
626         else
627                 ASSERT(dfp == &bf[2]);
628         /*
629          * Clear the 3rd entry, must be zero now.
630          */
631         bf[2].length = 0;
632         bf[2].offset = 0;
633         *loghead = 1;
634 }
635
636 /*
637  * Given a data block, reconstruct its bestfree map.
638  */
639 void
640 xfs_dir2_data_freescan(
641         struct xfs_mount                *mp,
642         struct xfs_dir2_data_hdr        *hdr,
643         int                             *loghead)
644 {
645         struct xfs_da_geometry          *geo = mp->m_dir_geo;
646         struct xfs_dir2_data_free       *bf = xfs_dir2_data_bestfree_p(mp, hdr);
647         void                            *addr = hdr;
648         unsigned int                    offset = geo->data_entry_offset;
649         unsigned int                    end;
650
651         ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
652                hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
653                hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
654                hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
655
656         /*
657          * Start by clearing the table.
658          */
659         memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT);
660         *loghead = 1;
661
662         end = xfs_dir3_data_end_offset(geo, addr);
663         while (offset < end) {
664                 struct xfs_dir2_data_unused     *dup = addr + offset;
665                 struct xfs_dir2_data_entry      *dep = addr + offset;
666
667                 /*
668                  * If it's a free entry, insert it.
669                  */
670                 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
671                         ASSERT(offset ==
672                                be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)));
673                         xfs_dir2_data_freeinsert(hdr, bf, dup, loghead);
674                         offset += be16_to_cpu(dup->length);
675                         continue;
676                 }
677
678                 /*
679                  * For active entries, check their tags and skip them.
680                  */
681                 ASSERT(offset ==
682                        be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)));
683                 offset += xfs_dir2_data_entsize(mp, dep->namelen);
684         }
685 }
686
687 /*
688  * Initialize a data block at the given block number in the directory.
689  * Give back the buffer for the created block.
690  */
691 int                                             /* error */
692 xfs_dir3_data_init(
693         struct xfs_da_args              *args,  /* directory operation args */
694         xfs_dir2_db_t                   blkno,  /* logical dir block number */
695         struct xfs_buf                  **bpp)  /* output block buffer */
696 {
697         struct xfs_trans                *tp = args->trans;
698         struct xfs_inode                *dp = args->dp;
699         struct xfs_mount                *mp = dp->i_mount;
700         struct xfs_da_geometry          *geo = args->geo;
701         struct xfs_buf                  *bp;
702         struct xfs_dir2_data_hdr        *hdr;
703         struct xfs_dir2_data_unused     *dup;
704         struct xfs_dir2_data_free       *bf;
705         int                             error;
706         int                             i;
707
708         /*
709          * Get the buffer set up for the block.
710          */
711         error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, blkno),
712                                &bp, XFS_DATA_FORK);
713         if (error)
714                 return error;
715         bp->b_ops = &xfs_dir3_data_buf_ops;
716         xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_DATA_BUF);
717
718         /*
719          * Initialize the header.
720          */
721         hdr = bp->b_addr;
722         if (xfs_has_crc(mp)) {
723                 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
724
725                 memset(hdr3, 0, sizeof(*hdr3));
726                 hdr3->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC);
727                 hdr3->blkno = cpu_to_be64(xfs_buf_daddr(bp));
728                 hdr3->owner = cpu_to_be64(dp->i_ino);
729                 uuid_copy(&hdr3->uuid, &mp->m_sb.sb_meta_uuid);
730
731         } else
732                 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
733
734         bf = xfs_dir2_data_bestfree_p(mp, hdr);
735         bf[0].offset = cpu_to_be16(geo->data_entry_offset);
736         bf[0].length = cpu_to_be16(geo->blksize - geo->data_entry_offset);
737         for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
738                 bf[i].length = 0;
739                 bf[i].offset = 0;
740         }
741
742         /*
743          * Set up an unused entry for the block's body.
744          */
745         dup = bp->b_addr + geo->data_entry_offset;
746         dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
747         dup->length = bf[0].length;
748         *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr);
749
750         /*
751          * Log it and return it.
752          */
753         xfs_dir2_data_log_header(args, bp);
754         xfs_dir2_data_log_unused(args, bp, dup);
755         *bpp = bp;
756         return 0;
757 }
758
759 /*
760  * Log an active data entry from the block.
761  */
762 void
763 xfs_dir2_data_log_entry(
764         struct xfs_da_args      *args,
765         struct xfs_buf          *bp,
766         xfs_dir2_data_entry_t   *dep)           /* data entry pointer */
767 {
768         struct xfs_mount        *mp = bp->b_mount;
769         struct xfs_dir2_data_hdr *hdr = bp->b_addr;
770
771         ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
772                hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
773                hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
774                hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
775
776         xfs_trans_log_buf(args->trans, bp, (uint)((char *)dep - (char *)hdr),
777                 (uint)((char *)(xfs_dir2_data_entry_tag_p(mp, dep) + 1) -
778                        (char *)hdr - 1));
779 }
780
781 /*
782  * Log a data block header.
783  */
784 void
785 xfs_dir2_data_log_header(
786         struct xfs_da_args      *args,
787         struct xfs_buf          *bp)
788 {
789 #ifdef DEBUG
790         struct xfs_dir2_data_hdr *hdr = bp->b_addr;
791
792         ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
793                hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
794                hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
795                hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
796 #endif
797
798         xfs_trans_log_buf(args->trans, bp, 0, args->geo->data_entry_offset - 1);
799 }
800
801 /*
802  * Log a data unused entry.
803  */
804 void
805 xfs_dir2_data_log_unused(
806         struct xfs_da_args      *args,
807         struct xfs_buf          *bp,
808         xfs_dir2_data_unused_t  *dup)           /* data unused pointer */
809 {
810         xfs_dir2_data_hdr_t     *hdr = bp->b_addr;
811
812         ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
813                hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
814                hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
815                hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
816
817         /*
818          * Log the first part of the unused entry.
819          */
820         xfs_trans_log_buf(args->trans, bp, (uint)((char *)dup - (char *)hdr),
821                 (uint)((char *)&dup->length + sizeof(dup->length) -
822                        1 - (char *)hdr));
823         /*
824          * Log the end (tag) of the unused entry.
825          */
826         xfs_trans_log_buf(args->trans, bp,
827                 (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr),
828                 (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr +
829                        sizeof(xfs_dir2_data_off_t) - 1));
830 }
831
832 /*
833  * Make a byte range in the data block unused.
834  * Its current contents are unimportant.
835  */
836 void
837 xfs_dir2_data_make_free(
838         struct xfs_da_args      *args,
839         struct xfs_buf          *bp,
840         xfs_dir2_data_aoff_t    offset,         /* starting byte offset */
841         xfs_dir2_data_aoff_t    len,            /* length in bytes */
842         int                     *needlogp,      /* out: log header */
843         int                     *needscanp)     /* out: regen bestfree */
844 {
845         xfs_dir2_data_hdr_t     *hdr;           /* data block pointer */
846         xfs_dir2_data_free_t    *dfp;           /* bestfree pointer */
847         int                     needscan;       /* need to regen bestfree */
848         xfs_dir2_data_unused_t  *newdup;        /* new unused entry */
849         xfs_dir2_data_unused_t  *postdup;       /* unused entry after us */
850         xfs_dir2_data_unused_t  *prevdup;       /* unused entry before us */
851         unsigned int            end;
852         struct xfs_dir2_data_free *bf;
853
854         hdr = bp->b_addr;
855
856         /*
857          * Figure out where the end of the data area is.
858          */
859         end = xfs_dir3_data_end_offset(args->geo, hdr);
860         ASSERT(end != 0);
861
862         /*
863          * If this isn't the start of the block, then back up to
864          * the previous entry and see if it's free.
865          */
866         if (offset > args->geo->data_entry_offset) {
867                 __be16                  *tagp;  /* tag just before us */
868
869                 tagp = (__be16 *)((char *)hdr + offset) - 1;
870                 prevdup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp));
871                 if (be16_to_cpu(prevdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
872                         prevdup = NULL;
873         } else
874                 prevdup = NULL;
875         /*
876          * If this isn't the end of the block, see if the entry after
877          * us is free.
878          */
879         if (offset + len < end) {
880                 postdup =
881                         (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
882                 if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
883                         postdup = NULL;
884         } else
885                 postdup = NULL;
886         ASSERT(*needscanp == 0);
887         needscan = 0;
888         /*
889          * Previous and following entries are both free,
890          * merge everything into a single free entry.
891          */
892         bf = xfs_dir2_data_bestfree_p(args->dp->i_mount, hdr);
893         if (prevdup && postdup) {
894                 xfs_dir2_data_free_t    *dfp2;  /* another bestfree pointer */
895
896                 /*
897                  * See if prevdup and/or postdup are in bestfree table.
898                  */
899                 dfp = xfs_dir2_data_freefind(hdr, bf, prevdup);
900                 dfp2 = xfs_dir2_data_freefind(hdr, bf, postdup);
901                 /*
902                  * We need a rescan unless there are exactly 2 free entries
903                  * namely our two.  Then we know what's happening, otherwise
904                  * since the third bestfree is there, there might be more
905                  * entries.
906                  */
907                 needscan = (bf[2].length != 0);
908                 /*
909                  * Fix up the new big freespace.
910                  */
911                 be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length));
912                 *xfs_dir2_data_unused_tag_p(prevdup) =
913                         cpu_to_be16((char *)prevdup - (char *)hdr);
914                 xfs_dir2_data_log_unused(args, bp, prevdup);
915                 if (!needscan) {
916                         /*
917                          * Has to be the case that entries 0 and 1 are
918                          * dfp and dfp2 (don't know which is which), and
919                          * entry 2 is empty.
920                          * Remove entry 1 first then entry 0.
921                          */
922                         ASSERT(dfp && dfp2);
923                         if (dfp == &bf[1]) {
924                                 dfp = &bf[0];
925                                 ASSERT(dfp2 == dfp);
926                                 dfp2 = &bf[1];
927                         }
928                         xfs_dir2_data_freeremove(hdr, bf, dfp2, needlogp);
929                         xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
930                         /*
931                          * Now insert the new entry.
932                          */
933                         dfp = xfs_dir2_data_freeinsert(hdr, bf, prevdup,
934                                                        needlogp);
935                         ASSERT(dfp == &bf[0]);
936                         ASSERT(dfp->length == prevdup->length);
937                         ASSERT(!dfp[1].length);
938                         ASSERT(!dfp[2].length);
939                 }
940         }
941         /*
942          * The entry before us is free, merge with it.
943          */
944         else if (prevdup) {
945                 dfp = xfs_dir2_data_freefind(hdr, bf, prevdup);
946                 be16_add_cpu(&prevdup->length, len);
947                 *xfs_dir2_data_unused_tag_p(prevdup) =
948                         cpu_to_be16((char *)prevdup - (char *)hdr);
949                 xfs_dir2_data_log_unused(args, bp, prevdup);
950                 /*
951                  * If the previous entry was in the table, the new entry
952                  * is longer, so it will be in the table too.  Remove
953                  * the old one and add the new one.
954                  */
955                 if (dfp) {
956                         xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
957                         xfs_dir2_data_freeinsert(hdr, bf, prevdup, needlogp);
958                 }
959                 /*
960                  * Otherwise we need a scan if the new entry is big enough.
961                  */
962                 else {
963                         needscan = be16_to_cpu(prevdup->length) >
964                                    be16_to_cpu(bf[2].length);
965                 }
966         }
967         /*
968          * The following entry is free, merge with it.
969          */
970         else if (postdup) {
971                 dfp = xfs_dir2_data_freefind(hdr, bf, postdup);
972                 newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset);
973                 newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
974                 newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length));
975                 *xfs_dir2_data_unused_tag_p(newdup) =
976                         cpu_to_be16((char *)newdup - (char *)hdr);
977                 xfs_dir2_data_log_unused(args, bp, newdup);
978                 /*
979                  * If the following entry was in the table, the new entry
980                  * is longer, so it will be in the table too.  Remove
981                  * the old one and add the new one.
982                  */
983                 if (dfp) {
984                         xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
985                         xfs_dir2_data_freeinsert(hdr, bf, newdup, needlogp);
986                 }
987                 /*
988                  * Otherwise we need a scan if the new entry is big enough.
989                  */
990                 else {
991                         needscan = be16_to_cpu(newdup->length) >
992                                    be16_to_cpu(bf[2].length);
993                 }
994         }
995         /*
996          * Neither neighbor is free.  Make a new entry.
997          */
998         else {
999                 newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset);
1000                 newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
1001                 newdup->length = cpu_to_be16(len);
1002                 *xfs_dir2_data_unused_tag_p(newdup) =
1003                         cpu_to_be16((char *)newdup - (char *)hdr);
1004                 xfs_dir2_data_log_unused(args, bp, newdup);
1005                 xfs_dir2_data_freeinsert(hdr, bf, newdup, needlogp);
1006         }
1007         *needscanp = needscan;
1008 }
1009
1010 /* Check our free data for obvious signs of corruption. */
1011 static inline xfs_failaddr_t
1012 xfs_dir2_data_check_free(
1013         struct xfs_dir2_data_hdr        *hdr,
1014         struct xfs_dir2_data_unused     *dup,
1015         xfs_dir2_data_aoff_t            offset,
1016         xfs_dir2_data_aoff_t            len)
1017 {
1018         if (hdr->magic != cpu_to_be32(XFS_DIR2_DATA_MAGIC) &&
1019             hdr->magic != cpu_to_be32(XFS_DIR3_DATA_MAGIC) &&
1020             hdr->magic != cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) &&
1021             hdr->magic != cpu_to_be32(XFS_DIR3_BLOCK_MAGIC))
1022                 return __this_address;
1023         if (be16_to_cpu(dup->freetag) != XFS_DIR2_DATA_FREE_TAG)
1024                 return __this_address;
1025         if (offset < (char *)dup - (char *)hdr)
1026                 return __this_address;
1027         if (offset + len > (char *)dup + be16_to_cpu(dup->length) - (char *)hdr)
1028                 return __this_address;
1029         if ((char *)dup - (char *)hdr !=
1030                         be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)))
1031                 return __this_address;
1032         return NULL;
1033 }
1034
1035 /* Sanity-check a new bestfree entry. */
1036 static inline xfs_failaddr_t
1037 xfs_dir2_data_check_new_free(
1038         struct xfs_dir2_data_hdr        *hdr,
1039         struct xfs_dir2_data_free       *dfp,
1040         struct xfs_dir2_data_unused     *newdup)
1041 {
1042         if (dfp == NULL)
1043                 return __this_address;
1044         if (dfp->length != newdup->length)
1045                 return __this_address;
1046         if (be16_to_cpu(dfp->offset) != (char *)newdup - (char *)hdr)
1047                 return __this_address;
1048         return NULL;
1049 }
1050
1051 /*
1052  * Take a byte range out of an existing unused space and make it un-free.
1053  */
1054 int
1055 xfs_dir2_data_use_free(
1056         struct xfs_da_args      *args,
1057         struct xfs_buf          *bp,
1058         xfs_dir2_data_unused_t  *dup,           /* unused entry */
1059         xfs_dir2_data_aoff_t    offset,         /* starting offset to use */
1060         xfs_dir2_data_aoff_t    len,            /* length to use */
1061         int                     *needlogp,      /* out: need to log header */
1062         int                     *needscanp)     /* out: need regen bestfree */
1063 {
1064         xfs_dir2_data_hdr_t     *hdr;           /* data block header */
1065         xfs_dir2_data_free_t    *dfp;           /* bestfree pointer */
1066         xfs_dir2_data_unused_t  *newdup;        /* new unused entry */
1067         xfs_dir2_data_unused_t  *newdup2;       /* another new unused entry */
1068         struct xfs_dir2_data_free *bf;
1069         xfs_failaddr_t          fa;
1070         int                     matchback;      /* matches end of freespace */
1071         int                     matchfront;     /* matches start of freespace */
1072         int                     needscan;       /* need to regen bestfree */
1073         int                     oldlen;         /* old unused entry's length */
1074
1075         hdr = bp->b_addr;
1076         fa = xfs_dir2_data_check_free(hdr, dup, offset, len);
1077         if (fa)
1078                 goto corrupt;
1079         /*
1080          * Look up the entry in the bestfree table.
1081          */
1082         oldlen = be16_to_cpu(dup->length);
1083         bf = xfs_dir2_data_bestfree_p(args->dp->i_mount, hdr);
1084         dfp = xfs_dir2_data_freefind(hdr, bf, dup);
1085         ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length));
1086         /*
1087          * Check for alignment with front and back of the entry.
1088          */
1089         matchfront = (char *)dup - (char *)hdr == offset;
1090         matchback = (char *)dup + oldlen - (char *)hdr == offset + len;
1091         ASSERT(*needscanp == 0);
1092         needscan = 0;
1093         /*
1094          * If we matched it exactly we just need to get rid of it from
1095          * the bestfree table.
1096          */
1097         if (matchfront && matchback) {
1098                 if (dfp) {
1099                         needscan = (bf[2].offset != 0);
1100                         if (!needscan)
1101                                 xfs_dir2_data_freeremove(hdr, bf, dfp,
1102                                                          needlogp);
1103                 }
1104         }
1105         /*
1106          * We match the first part of the entry.
1107          * Make a new entry with the remaining freespace.
1108          */
1109         else if (matchfront) {
1110                 newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
1111                 newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
1112                 newdup->length = cpu_to_be16(oldlen - len);
1113                 *xfs_dir2_data_unused_tag_p(newdup) =
1114                         cpu_to_be16((char *)newdup - (char *)hdr);
1115                 xfs_dir2_data_log_unused(args, bp, newdup);
1116                 /*
1117                  * If it was in the table, remove it and add the new one.
1118                  */
1119                 if (dfp) {
1120                         xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
1121                         dfp = xfs_dir2_data_freeinsert(hdr, bf, newdup,
1122                                                        needlogp);
1123                         fa = xfs_dir2_data_check_new_free(hdr, dfp, newdup);
1124                         if (fa)
1125                                 goto corrupt;
1126                         /*
1127                          * If we got inserted at the last slot,
1128                          * that means we don't know if there was a better
1129                          * choice for the last slot, or not.  Rescan.
1130                          */
1131                         needscan = dfp == &bf[2];
1132                 }
1133         }
1134         /*
1135          * We match the last part of the entry.
1136          * Trim the allocated space off the tail of the entry.
1137          */
1138         else if (matchback) {
1139                 newdup = dup;
1140                 newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup);
1141                 *xfs_dir2_data_unused_tag_p(newdup) =
1142                         cpu_to_be16((char *)newdup - (char *)hdr);
1143                 xfs_dir2_data_log_unused(args, bp, newdup);
1144                 /*
1145                  * If it was in the table, remove it and add the new one.
1146                  */
1147                 if (dfp) {
1148                         xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
1149                         dfp = xfs_dir2_data_freeinsert(hdr, bf, newdup,
1150                                                        needlogp);
1151                         fa = xfs_dir2_data_check_new_free(hdr, dfp, newdup);
1152                         if (fa)
1153                                 goto corrupt;
1154                         /*
1155                          * If we got inserted at the last slot,
1156                          * that means we don't know if there was a better
1157                          * choice for the last slot, or not.  Rescan.
1158                          */
1159                         needscan = dfp == &bf[2];
1160                 }
1161         }
1162         /*
1163          * Poking out the middle of an entry.
1164          * Make two new entries.
1165          */
1166         else {
1167                 newdup = dup;
1168                 newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup);
1169                 *xfs_dir2_data_unused_tag_p(newdup) =
1170                         cpu_to_be16((char *)newdup - (char *)hdr);
1171                 xfs_dir2_data_log_unused(args, bp, newdup);
1172                 newdup2 = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
1173                 newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
1174                 newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length));
1175                 *xfs_dir2_data_unused_tag_p(newdup2) =
1176                         cpu_to_be16((char *)newdup2 - (char *)hdr);
1177                 xfs_dir2_data_log_unused(args, bp, newdup2);
1178                 /*
1179                  * If the old entry was in the table, we need to scan
1180                  * if the 3rd entry was valid, since these entries
1181                  * are smaller than the old one.
1182                  * If we don't need to scan that means there were 1 or 2
1183                  * entries in the table, and removing the old and adding
1184                  * the 2 new will work.
1185                  */
1186                 if (dfp) {
1187                         needscan = (bf[2].length != 0);
1188                         if (!needscan) {
1189                                 xfs_dir2_data_freeremove(hdr, bf, dfp,
1190                                                          needlogp);
1191                                 xfs_dir2_data_freeinsert(hdr, bf, newdup,
1192                                                          needlogp);
1193                                 xfs_dir2_data_freeinsert(hdr, bf, newdup2,
1194                                                          needlogp);
1195                         }
1196                 }
1197         }
1198         *needscanp = needscan;
1199         return 0;
1200 corrupt:
1201         xfs_corruption_error(__func__, XFS_ERRLEVEL_LOW, args->dp->i_mount,
1202                         hdr, sizeof(*hdr), __FILE__, __LINE__, fa);
1203         xfs_da_mark_sick(args);
1204         return -EFSCORRUPTED;
1205 }
1206
1207 /* Find the end of the entry data in a data/block format dir block. */
1208 unsigned int
1209 xfs_dir3_data_end_offset(
1210         struct xfs_da_geometry          *geo,
1211         struct xfs_dir2_data_hdr        *hdr)
1212 {
1213         void                            *p;
1214
1215         switch (hdr->magic) {
1216         case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
1217         case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
1218                 p = xfs_dir2_block_leaf_p(xfs_dir2_block_tail_p(geo, hdr));
1219                 return p - (void *)hdr;
1220         case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
1221         case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
1222                 return geo->blksize;
1223         default:
1224                 return 0;
1225         }
1226 }