]> Git Repo - J-linux.git/blob - fs/xfs/libxfs/xfs_dir2_data.c
Merge patch series "riscv: Extension parsing fixes"
[J-linux.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 xfs_failaddr_t
399 xfs_dir3_data_header_check(
400         struct xfs_buf          *bp,
401         xfs_ino_t               owner)
402 {
403         struct xfs_mount        *mp = bp->b_mount;
404
405         if (xfs_has_crc(mp)) {
406                 struct xfs_dir3_data_hdr *hdr3 = bp->b_addr;
407
408                 if (hdr3->hdr.magic != cpu_to_be32(XFS_DIR3_DATA_MAGIC))
409                         return __this_address;
410
411                 if (be64_to_cpu(hdr3->hdr.owner) != owner)
412                         return __this_address;
413         }
414
415         return NULL;
416 }
417
418 int
419 xfs_dir3_data_read(
420         struct xfs_trans        *tp,
421         struct xfs_inode        *dp,
422         xfs_ino_t               owner,
423         xfs_dablk_t             bno,
424         unsigned int            flags,
425         struct xfs_buf          **bpp)
426 {
427         xfs_failaddr_t          fa;
428         int                     err;
429
430         err = xfs_da_read_buf(tp, dp, bno, flags, bpp, XFS_DATA_FORK,
431                         &xfs_dir3_data_buf_ops);
432         if (err || !*bpp)
433                 return err;
434
435         /* Check things that we can't do in the verifier. */
436         fa = xfs_dir3_data_header_check(*bpp, owner);
437         if (fa) {
438                 __xfs_buf_mark_corrupt(*bpp, fa);
439                 xfs_trans_brelse(tp, *bpp);
440                 *bpp = NULL;
441                 xfs_dirattr_mark_sick(dp, XFS_DATA_FORK);
442                 return -EFSCORRUPTED;
443         }
444
445         xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_DATA_BUF);
446         return err;
447 }
448
449 int
450 xfs_dir3_data_readahead(
451         struct xfs_inode        *dp,
452         xfs_dablk_t             bno,
453         unsigned int            flags)
454 {
455         return xfs_da_reada_buf(dp, bno, flags, XFS_DATA_FORK,
456                                 &xfs_dir3_data_reada_buf_ops);
457 }
458
459 /*
460  * Find the bestfree entry that exactly coincides with unused directory space
461  * or a verifier error because the bestfree data are bad.
462  */
463 static xfs_failaddr_t
464 xfs_dir2_data_freefind_verify(
465         struct xfs_dir2_data_hdr        *hdr,
466         struct xfs_dir2_data_free       *bf,
467         struct xfs_dir2_data_unused     *dup,
468         struct xfs_dir2_data_free       **bf_ent)
469 {
470         struct xfs_dir2_data_free       *dfp;
471         xfs_dir2_data_aoff_t            off;
472         bool                            matched = false;
473         bool                            seenzero = false;
474
475         *bf_ent = NULL;
476         off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr);
477
478         /*
479          * Validate some consistency in the bestfree table.
480          * Check order, non-overlapping entries, and if we find the
481          * one we're looking for it has to be exact.
482          */
483         for (dfp = &bf[0]; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) {
484                 if (!dfp->offset) {
485                         if (dfp->length)
486                                 return __this_address;
487                         seenzero = true;
488                         continue;
489                 }
490                 if (seenzero)
491                         return __this_address;
492                 if (be16_to_cpu(dfp->offset) == off) {
493                         matched = true;
494                         if (dfp->length != dup->length)
495                                 return __this_address;
496                 } else if (be16_to_cpu(dfp->offset) > off) {
497                         if (off + be16_to_cpu(dup->length) >
498                                         be16_to_cpu(dfp->offset))
499                                 return __this_address;
500                 } else {
501                         if (be16_to_cpu(dfp->offset) +
502                                         be16_to_cpu(dfp->length) > off)
503                                 return __this_address;
504                 }
505                 if (!matched &&
506                     be16_to_cpu(dfp->length) < be16_to_cpu(dup->length))
507                         return __this_address;
508                 if (dfp > &bf[0] &&
509                     be16_to_cpu(dfp[-1].length) < be16_to_cpu(dfp[0].length))
510                         return __this_address;
511         }
512
513         /* Looks ok so far; now try to match up with a bestfree entry. */
514         *bf_ent = xfs_dir2_data_freefind(hdr, bf, dup);
515         return NULL;
516 }
517
518 /*
519  * Given a data block and an unused entry from that block,
520  * return the bestfree entry if any that corresponds to it.
521  */
522 xfs_dir2_data_free_t *
523 xfs_dir2_data_freefind(
524         struct xfs_dir2_data_hdr *hdr,          /* data block header */
525         struct xfs_dir2_data_free *bf,          /* bestfree table pointer */
526         struct xfs_dir2_data_unused *dup)       /* unused space */
527 {
528         xfs_dir2_data_free_t    *dfp;           /* bestfree entry */
529         xfs_dir2_data_aoff_t    off;            /* offset value needed */
530
531         off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr);
532
533         /*
534          * If this is smaller than the smallest bestfree entry,
535          * it can't be there since they're sorted.
536          */
537         if (be16_to_cpu(dup->length) <
538             be16_to_cpu(bf[XFS_DIR2_DATA_FD_COUNT - 1].length))
539                 return NULL;
540         /*
541          * Look at the three bestfree entries for our guy.
542          */
543         for (dfp = &bf[0]; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) {
544                 if (!dfp->offset)
545                         return NULL;
546                 if (be16_to_cpu(dfp->offset) == off)
547                         return dfp;
548         }
549         /*
550          * Didn't find it.  This only happens if there are duplicate lengths.
551          */
552         return NULL;
553 }
554
555 /*
556  * Insert an unused-space entry into the bestfree table.
557  */
558 xfs_dir2_data_free_t *                          /* entry inserted */
559 xfs_dir2_data_freeinsert(
560         struct xfs_dir2_data_hdr *hdr,          /* data block pointer */
561         struct xfs_dir2_data_free *dfp,         /* bestfree table pointer */
562         struct xfs_dir2_data_unused *dup,       /* unused space */
563         int                     *loghead)       /* log the data header (out) */
564 {
565         xfs_dir2_data_free_t    new;            /* new bestfree entry */
566
567         ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
568                hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
569                hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
570                hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
571
572         new.length = dup->length;
573         new.offset = cpu_to_be16((char *)dup - (char *)hdr);
574
575         /*
576          * Insert at position 0, 1, or 2; or not at all.
577          */
578         if (be16_to_cpu(new.length) > be16_to_cpu(dfp[0].length)) {
579                 dfp[2] = dfp[1];
580                 dfp[1] = dfp[0];
581                 dfp[0] = new;
582                 *loghead = 1;
583                 return &dfp[0];
584         }
585         if (be16_to_cpu(new.length) > be16_to_cpu(dfp[1].length)) {
586                 dfp[2] = dfp[1];
587                 dfp[1] = new;
588                 *loghead = 1;
589                 return &dfp[1];
590         }
591         if (be16_to_cpu(new.length) > be16_to_cpu(dfp[2].length)) {
592                 dfp[2] = new;
593                 *loghead = 1;
594                 return &dfp[2];
595         }
596         return NULL;
597 }
598
599 /*
600  * Remove a bestfree entry from the table.
601  */
602 STATIC void
603 xfs_dir2_data_freeremove(
604         struct xfs_dir2_data_hdr *hdr,          /* data block header */
605         struct xfs_dir2_data_free *bf,          /* bestfree table pointer */
606         struct xfs_dir2_data_free *dfp,         /* bestfree entry pointer */
607         int                     *loghead)       /* out: log data header */
608 {
609
610         ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
611                hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
612                hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
613                hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
614
615         /*
616          * It's the first entry, slide the next 2 up.
617          */
618         if (dfp == &bf[0]) {
619                 bf[0] = bf[1];
620                 bf[1] = bf[2];
621         }
622         /*
623          * It's the second entry, slide the 3rd entry up.
624          */
625         else if (dfp == &bf[1])
626                 bf[1] = bf[2];
627         /*
628          * Must be the last entry.
629          */
630         else
631                 ASSERT(dfp == &bf[2]);
632         /*
633          * Clear the 3rd entry, must be zero now.
634          */
635         bf[2].length = 0;
636         bf[2].offset = 0;
637         *loghead = 1;
638 }
639
640 /*
641  * Given a data block, reconstruct its bestfree map.
642  */
643 void
644 xfs_dir2_data_freescan(
645         struct xfs_mount                *mp,
646         struct xfs_dir2_data_hdr        *hdr,
647         int                             *loghead)
648 {
649         struct xfs_da_geometry          *geo = mp->m_dir_geo;
650         struct xfs_dir2_data_free       *bf = xfs_dir2_data_bestfree_p(mp, hdr);
651         void                            *addr = hdr;
652         unsigned int                    offset = geo->data_entry_offset;
653         unsigned int                    end;
654
655         ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
656                hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
657                hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
658                hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
659
660         /*
661          * Start by clearing the table.
662          */
663         memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT);
664         *loghead = 1;
665
666         end = xfs_dir3_data_end_offset(geo, addr);
667         while (offset < end) {
668                 struct xfs_dir2_data_unused     *dup = addr + offset;
669                 struct xfs_dir2_data_entry      *dep = addr + offset;
670
671                 /*
672                  * If it's a free entry, insert it.
673                  */
674                 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
675                         ASSERT(offset ==
676                                be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)));
677                         xfs_dir2_data_freeinsert(hdr, bf, dup, loghead);
678                         offset += be16_to_cpu(dup->length);
679                         continue;
680                 }
681
682                 /*
683                  * For active entries, check their tags and skip them.
684                  */
685                 ASSERT(offset ==
686                        be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)));
687                 offset += xfs_dir2_data_entsize(mp, dep->namelen);
688         }
689 }
690
691 /*
692  * Initialize a data block at the given block number in the directory.
693  * Give back the buffer for the created block.
694  */
695 int                                             /* error */
696 xfs_dir3_data_init(
697         struct xfs_da_args              *args,  /* directory operation args */
698         xfs_dir2_db_t                   blkno,  /* logical dir block number */
699         struct xfs_buf                  **bpp)  /* output block buffer */
700 {
701         struct xfs_trans                *tp = args->trans;
702         struct xfs_inode                *dp = args->dp;
703         struct xfs_mount                *mp = dp->i_mount;
704         struct xfs_da_geometry          *geo = args->geo;
705         struct xfs_buf                  *bp;
706         struct xfs_dir2_data_hdr        *hdr;
707         struct xfs_dir2_data_unused     *dup;
708         struct xfs_dir2_data_free       *bf;
709         int                             error;
710         int                             i;
711
712         /*
713          * Get the buffer set up for the block.
714          */
715         error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, blkno),
716                                &bp, XFS_DATA_FORK);
717         if (error)
718                 return error;
719         bp->b_ops = &xfs_dir3_data_buf_ops;
720         xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_DATA_BUF);
721
722         /*
723          * Initialize the header.
724          */
725         hdr = bp->b_addr;
726         if (xfs_has_crc(mp)) {
727                 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
728
729                 memset(hdr3, 0, sizeof(*hdr3));
730                 hdr3->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC);
731                 hdr3->blkno = cpu_to_be64(xfs_buf_daddr(bp));
732                 hdr3->owner = cpu_to_be64(args->owner);
733                 uuid_copy(&hdr3->uuid, &mp->m_sb.sb_meta_uuid);
734
735         } else
736                 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
737
738         bf = xfs_dir2_data_bestfree_p(mp, hdr);
739         bf[0].offset = cpu_to_be16(geo->data_entry_offset);
740         bf[0].length = cpu_to_be16(geo->blksize - geo->data_entry_offset);
741         for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
742                 bf[i].length = 0;
743                 bf[i].offset = 0;
744         }
745
746         /*
747          * Set up an unused entry for the block's body.
748          */
749         dup = bp->b_addr + geo->data_entry_offset;
750         dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
751         dup->length = bf[0].length;
752         *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr);
753
754         /*
755          * Log it and return it.
756          */
757         xfs_dir2_data_log_header(args, bp);
758         xfs_dir2_data_log_unused(args, bp, dup);
759         *bpp = bp;
760         return 0;
761 }
762
763 /*
764  * Log an active data entry from the block.
765  */
766 void
767 xfs_dir2_data_log_entry(
768         struct xfs_da_args      *args,
769         struct xfs_buf          *bp,
770         xfs_dir2_data_entry_t   *dep)           /* data entry pointer */
771 {
772         struct xfs_mount        *mp = bp->b_mount;
773         struct xfs_dir2_data_hdr *hdr = bp->b_addr;
774
775         ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
776                hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
777                hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
778                hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
779
780         xfs_trans_log_buf(args->trans, bp, (uint)((char *)dep - (char *)hdr),
781                 (uint)((char *)(xfs_dir2_data_entry_tag_p(mp, dep) + 1) -
782                        (char *)hdr - 1));
783 }
784
785 /*
786  * Log a data block header.
787  */
788 void
789 xfs_dir2_data_log_header(
790         struct xfs_da_args      *args,
791         struct xfs_buf          *bp)
792 {
793 #ifdef DEBUG
794         struct xfs_dir2_data_hdr *hdr = bp->b_addr;
795
796         ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
797                hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
798                hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
799                hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
800 #endif
801
802         xfs_trans_log_buf(args->trans, bp, 0, args->geo->data_entry_offset - 1);
803 }
804
805 /*
806  * Log a data unused entry.
807  */
808 void
809 xfs_dir2_data_log_unused(
810         struct xfs_da_args      *args,
811         struct xfs_buf          *bp,
812         xfs_dir2_data_unused_t  *dup)           /* data unused pointer */
813 {
814         xfs_dir2_data_hdr_t     *hdr = bp->b_addr;
815
816         ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
817                hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) ||
818                hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
819                hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC));
820
821         /*
822          * Log the first part of the unused entry.
823          */
824         xfs_trans_log_buf(args->trans, bp, (uint)((char *)dup - (char *)hdr),
825                 (uint)((char *)&dup->length + sizeof(dup->length) -
826                        1 - (char *)hdr));
827         /*
828          * Log the end (tag) of the unused entry.
829          */
830         xfs_trans_log_buf(args->trans, bp,
831                 (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr),
832                 (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr +
833                        sizeof(xfs_dir2_data_off_t) - 1));
834 }
835
836 /*
837  * Make a byte range in the data block unused.
838  * Its current contents are unimportant.
839  */
840 void
841 xfs_dir2_data_make_free(
842         struct xfs_da_args      *args,
843         struct xfs_buf          *bp,
844         xfs_dir2_data_aoff_t    offset,         /* starting byte offset */
845         xfs_dir2_data_aoff_t    len,            /* length in bytes */
846         int                     *needlogp,      /* out: log header */
847         int                     *needscanp)     /* out: regen bestfree */
848 {
849         xfs_dir2_data_hdr_t     *hdr;           /* data block pointer */
850         xfs_dir2_data_free_t    *dfp;           /* bestfree pointer */
851         int                     needscan;       /* need to regen bestfree */
852         xfs_dir2_data_unused_t  *newdup;        /* new unused entry */
853         xfs_dir2_data_unused_t  *postdup;       /* unused entry after us */
854         xfs_dir2_data_unused_t  *prevdup;       /* unused entry before us */
855         unsigned int            end;
856         struct xfs_dir2_data_free *bf;
857
858         hdr = bp->b_addr;
859
860         /*
861          * Figure out where the end of the data area is.
862          */
863         end = xfs_dir3_data_end_offset(args->geo, hdr);
864         ASSERT(end != 0);
865
866         /*
867          * If this isn't the start of the block, then back up to
868          * the previous entry and see if it's free.
869          */
870         if (offset > args->geo->data_entry_offset) {
871                 __be16                  *tagp;  /* tag just before us */
872
873                 tagp = (__be16 *)((char *)hdr + offset) - 1;
874                 prevdup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp));
875                 if (be16_to_cpu(prevdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
876                         prevdup = NULL;
877         } else
878                 prevdup = NULL;
879         /*
880          * If this isn't the end of the block, see if the entry after
881          * us is free.
882          */
883         if (offset + len < end) {
884                 postdup =
885                         (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
886                 if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
887                         postdup = NULL;
888         } else
889                 postdup = NULL;
890         ASSERT(*needscanp == 0);
891         needscan = 0;
892         /*
893          * Previous and following entries are both free,
894          * merge everything into a single free entry.
895          */
896         bf = xfs_dir2_data_bestfree_p(args->dp->i_mount, hdr);
897         if (prevdup && postdup) {
898                 xfs_dir2_data_free_t    *dfp2;  /* another bestfree pointer */
899
900                 /*
901                  * See if prevdup and/or postdup are in bestfree table.
902                  */
903                 dfp = xfs_dir2_data_freefind(hdr, bf, prevdup);
904                 dfp2 = xfs_dir2_data_freefind(hdr, bf, postdup);
905                 /*
906                  * We need a rescan unless there are exactly 2 free entries
907                  * namely our two.  Then we know what's happening, otherwise
908                  * since the third bestfree is there, there might be more
909                  * entries.
910                  */
911                 needscan = (bf[2].length != 0);
912                 /*
913                  * Fix up the new big freespace.
914                  */
915                 be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length));
916                 *xfs_dir2_data_unused_tag_p(prevdup) =
917                         cpu_to_be16((char *)prevdup - (char *)hdr);
918                 xfs_dir2_data_log_unused(args, bp, prevdup);
919                 if (!needscan) {
920                         /*
921                          * Has to be the case that entries 0 and 1 are
922                          * dfp and dfp2 (don't know which is which), and
923                          * entry 2 is empty.
924                          * Remove entry 1 first then entry 0.
925                          */
926                         ASSERT(dfp && dfp2);
927                         if (dfp == &bf[1]) {
928                                 dfp = &bf[0];
929                                 ASSERT(dfp2 == dfp);
930                                 dfp2 = &bf[1];
931                         }
932                         xfs_dir2_data_freeremove(hdr, bf, dfp2, needlogp);
933                         xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
934                         /*
935                          * Now insert the new entry.
936                          */
937                         dfp = xfs_dir2_data_freeinsert(hdr, bf, prevdup,
938                                                        needlogp);
939                         ASSERT(dfp == &bf[0]);
940                         ASSERT(dfp->length == prevdup->length);
941                         ASSERT(!dfp[1].length);
942                         ASSERT(!dfp[2].length);
943                 }
944         }
945         /*
946          * The entry before us is free, merge with it.
947          */
948         else if (prevdup) {
949                 dfp = xfs_dir2_data_freefind(hdr, bf, prevdup);
950                 be16_add_cpu(&prevdup->length, len);
951                 *xfs_dir2_data_unused_tag_p(prevdup) =
952                         cpu_to_be16((char *)prevdup - (char *)hdr);
953                 xfs_dir2_data_log_unused(args, bp, prevdup);
954                 /*
955                  * If the previous entry was in the table, the new entry
956                  * is longer, so it will be in the table too.  Remove
957                  * the old one and add the new one.
958                  */
959                 if (dfp) {
960                         xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
961                         xfs_dir2_data_freeinsert(hdr, bf, prevdup, needlogp);
962                 }
963                 /*
964                  * Otherwise we need a scan if the new entry is big enough.
965                  */
966                 else {
967                         needscan = be16_to_cpu(prevdup->length) >
968                                    be16_to_cpu(bf[2].length);
969                 }
970         }
971         /*
972          * The following entry is free, merge with it.
973          */
974         else if (postdup) {
975                 dfp = xfs_dir2_data_freefind(hdr, bf, postdup);
976                 newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset);
977                 newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
978                 newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length));
979                 *xfs_dir2_data_unused_tag_p(newdup) =
980                         cpu_to_be16((char *)newdup - (char *)hdr);
981                 xfs_dir2_data_log_unused(args, bp, newdup);
982                 /*
983                  * If the following entry was in the table, the new entry
984                  * is longer, so it will be in the table too.  Remove
985                  * the old one and add the new one.
986                  */
987                 if (dfp) {
988                         xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
989                         xfs_dir2_data_freeinsert(hdr, bf, newdup, needlogp);
990                 }
991                 /*
992                  * Otherwise we need a scan if the new entry is big enough.
993                  */
994                 else {
995                         needscan = be16_to_cpu(newdup->length) >
996                                    be16_to_cpu(bf[2].length);
997                 }
998         }
999         /*
1000          * Neither neighbor is free.  Make a new entry.
1001          */
1002         else {
1003                 newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset);
1004                 newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
1005                 newdup->length = cpu_to_be16(len);
1006                 *xfs_dir2_data_unused_tag_p(newdup) =
1007                         cpu_to_be16((char *)newdup - (char *)hdr);
1008                 xfs_dir2_data_log_unused(args, bp, newdup);
1009                 xfs_dir2_data_freeinsert(hdr, bf, newdup, needlogp);
1010         }
1011         *needscanp = needscan;
1012 }
1013
1014 /* Check our free data for obvious signs of corruption. */
1015 static inline xfs_failaddr_t
1016 xfs_dir2_data_check_free(
1017         struct xfs_dir2_data_hdr        *hdr,
1018         struct xfs_dir2_data_unused     *dup,
1019         xfs_dir2_data_aoff_t            offset,
1020         xfs_dir2_data_aoff_t            len)
1021 {
1022         if (hdr->magic != cpu_to_be32(XFS_DIR2_DATA_MAGIC) &&
1023             hdr->magic != cpu_to_be32(XFS_DIR3_DATA_MAGIC) &&
1024             hdr->magic != cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) &&
1025             hdr->magic != cpu_to_be32(XFS_DIR3_BLOCK_MAGIC))
1026                 return __this_address;
1027         if (be16_to_cpu(dup->freetag) != XFS_DIR2_DATA_FREE_TAG)
1028                 return __this_address;
1029         if (offset < (char *)dup - (char *)hdr)
1030                 return __this_address;
1031         if (offset + len > (char *)dup + be16_to_cpu(dup->length) - (char *)hdr)
1032                 return __this_address;
1033         if ((char *)dup - (char *)hdr !=
1034                         be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)))
1035                 return __this_address;
1036         return NULL;
1037 }
1038
1039 /* Sanity-check a new bestfree entry. */
1040 static inline xfs_failaddr_t
1041 xfs_dir2_data_check_new_free(
1042         struct xfs_dir2_data_hdr        *hdr,
1043         struct xfs_dir2_data_free       *dfp,
1044         struct xfs_dir2_data_unused     *newdup)
1045 {
1046         if (dfp == NULL)
1047                 return __this_address;
1048         if (dfp->length != newdup->length)
1049                 return __this_address;
1050         if (be16_to_cpu(dfp->offset) != (char *)newdup - (char *)hdr)
1051                 return __this_address;
1052         return NULL;
1053 }
1054
1055 /*
1056  * Take a byte range out of an existing unused space and make it un-free.
1057  */
1058 int
1059 xfs_dir2_data_use_free(
1060         struct xfs_da_args      *args,
1061         struct xfs_buf          *bp,
1062         xfs_dir2_data_unused_t  *dup,           /* unused entry */
1063         xfs_dir2_data_aoff_t    offset,         /* starting offset to use */
1064         xfs_dir2_data_aoff_t    len,            /* length to use */
1065         int                     *needlogp,      /* out: need to log header */
1066         int                     *needscanp)     /* out: need regen bestfree */
1067 {
1068         xfs_dir2_data_hdr_t     *hdr;           /* data block header */
1069         xfs_dir2_data_free_t    *dfp;           /* bestfree pointer */
1070         xfs_dir2_data_unused_t  *newdup;        /* new unused entry */
1071         xfs_dir2_data_unused_t  *newdup2;       /* another new unused entry */
1072         struct xfs_dir2_data_free *bf;
1073         xfs_failaddr_t          fa;
1074         int                     matchback;      /* matches end of freespace */
1075         int                     matchfront;     /* matches start of freespace */
1076         int                     needscan;       /* need to regen bestfree */
1077         int                     oldlen;         /* old unused entry's length */
1078
1079         hdr = bp->b_addr;
1080         fa = xfs_dir2_data_check_free(hdr, dup, offset, len);
1081         if (fa)
1082                 goto corrupt;
1083         /*
1084          * Look up the entry in the bestfree table.
1085          */
1086         oldlen = be16_to_cpu(dup->length);
1087         bf = xfs_dir2_data_bestfree_p(args->dp->i_mount, hdr);
1088         dfp = xfs_dir2_data_freefind(hdr, bf, dup);
1089         ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length));
1090         /*
1091          * Check for alignment with front and back of the entry.
1092          */
1093         matchfront = (char *)dup - (char *)hdr == offset;
1094         matchback = (char *)dup + oldlen - (char *)hdr == offset + len;
1095         ASSERT(*needscanp == 0);
1096         needscan = 0;
1097         /*
1098          * If we matched it exactly we just need to get rid of it from
1099          * the bestfree table.
1100          */
1101         if (matchfront && matchback) {
1102                 if (dfp) {
1103                         needscan = (bf[2].offset != 0);
1104                         if (!needscan)
1105                                 xfs_dir2_data_freeremove(hdr, bf, dfp,
1106                                                          needlogp);
1107                 }
1108         }
1109         /*
1110          * We match the first part of the entry.
1111          * Make a new entry with the remaining freespace.
1112          */
1113         else if (matchfront) {
1114                 newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
1115                 newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
1116                 newdup->length = cpu_to_be16(oldlen - len);
1117                 *xfs_dir2_data_unused_tag_p(newdup) =
1118                         cpu_to_be16((char *)newdup - (char *)hdr);
1119                 xfs_dir2_data_log_unused(args, bp, newdup);
1120                 /*
1121                  * If it was in the table, remove it and add the new one.
1122                  */
1123                 if (dfp) {
1124                         xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
1125                         dfp = xfs_dir2_data_freeinsert(hdr, bf, newdup,
1126                                                        needlogp);
1127                         fa = xfs_dir2_data_check_new_free(hdr, dfp, newdup);
1128                         if (fa)
1129                                 goto corrupt;
1130                         /*
1131                          * If we got inserted at the last slot,
1132                          * that means we don't know if there was a better
1133                          * choice for the last slot, or not.  Rescan.
1134                          */
1135                         needscan = dfp == &bf[2];
1136                 }
1137         }
1138         /*
1139          * We match the last part of the entry.
1140          * Trim the allocated space off the tail of the entry.
1141          */
1142         else if (matchback) {
1143                 newdup = dup;
1144                 newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup);
1145                 *xfs_dir2_data_unused_tag_p(newdup) =
1146                         cpu_to_be16((char *)newdup - (char *)hdr);
1147                 xfs_dir2_data_log_unused(args, bp, newdup);
1148                 /*
1149                  * If it was in the table, remove it and add the new one.
1150                  */
1151                 if (dfp) {
1152                         xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
1153                         dfp = xfs_dir2_data_freeinsert(hdr, bf, newdup,
1154                                                        needlogp);
1155                         fa = xfs_dir2_data_check_new_free(hdr, dfp, newdup);
1156                         if (fa)
1157                                 goto corrupt;
1158                         /*
1159                          * If we got inserted at the last slot,
1160                          * that means we don't know if there was a better
1161                          * choice for the last slot, or not.  Rescan.
1162                          */
1163                         needscan = dfp == &bf[2];
1164                 }
1165         }
1166         /*
1167          * Poking out the middle of an entry.
1168          * Make two new entries.
1169          */
1170         else {
1171                 newdup = dup;
1172                 newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup);
1173                 *xfs_dir2_data_unused_tag_p(newdup) =
1174                         cpu_to_be16((char *)newdup - (char *)hdr);
1175                 xfs_dir2_data_log_unused(args, bp, newdup);
1176                 newdup2 = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
1177                 newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
1178                 newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length));
1179                 *xfs_dir2_data_unused_tag_p(newdup2) =
1180                         cpu_to_be16((char *)newdup2 - (char *)hdr);
1181                 xfs_dir2_data_log_unused(args, bp, newdup2);
1182                 /*
1183                  * If the old entry was in the table, we need to scan
1184                  * if the 3rd entry was valid, since these entries
1185                  * are smaller than the old one.
1186                  * If we don't need to scan that means there were 1 or 2
1187                  * entries in the table, and removing the old and adding
1188                  * the 2 new will work.
1189                  */
1190                 if (dfp) {
1191                         needscan = (bf[2].length != 0);
1192                         if (!needscan) {
1193                                 xfs_dir2_data_freeremove(hdr, bf, dfp,
1194                                                          needlogp);
1195                                 xfs_dir2_data_freeinsert(hdr, bf, newdup,
1196                                                          needlogp);
1197                                 xfs_dir2_data_freeinsert(hdr, bf, newdup2,
1198                                                          needlogp);
1199                         }
1200                 }
1201         }
1202         *needscanp = needscan;
1203         return 0;
1204 corrupt:
1205         xfs_corruption_error(__func__, XFS_ERRLEVEL_LOW, args->dp->i_mount,
1206                         hdr, sizeof(*hdr), __FILE__, __LINE__, fa);
1207         xfs_da_mark_sick(args);
1208         return -EFSCORRUPTED;
1209 }
1210
1211 /* Find the end of the entry data in a data/block format dir block. */
1212 unsigned int
1213 xfs_dir3_data_end_offset(
1214         struct xfs_da_geometry          *geo,
1215         struct xfs_dir2_data_hdr        *hdr)
1216 {
1217         void                            *p;
1218
1219         switch (hdr->magic) {
1220         case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
1221         case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
1222                 p = xfs_dir2_block_leaf_p(xfs_dir2_block_tail_p(geo, hdr));
1223                 return p - (void *)hdr;
1224         case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
1225         case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
1226                 return geo->blksize;
1227         default:
1228                 return 0;
1229         }
1230 }
This page took 0.106879 seconds and 4 git commands to generate.