LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_dir2_data.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-djwx @ Mon Jul 31 20:08:22 PDT 2023 Lines: 467 547 85.4 %
Date: 2023-07-31 20:08:22 Functions: 27 27 100.0 %

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

Generated by: LCOV version 1.14