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-djwa @ Mon Jul 31 20:08:17 PDT 2023 Lines: 469 547 85.7 %
Date: 2023-07-31 20:08:17 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    68633916 : xfs_dir2_data_bestfree_p(
      29             :         struct xfs_mount                *mp,
      30             :         struct xfs_dir2_data_hdr        *hdr)
      31             : {
      32    68633916 :         if (xfs_has_crc(mp))
      33   584797384 :                 return ((struct xfs_dir3_data_hdr *)hdr)->best_free;
      34       83429 :         return hdr->bestfree;
      35             : }
      36             : 
      37             : /*
      38             :  * Pointer to an entry's tag word.
      39             :  */
      40             : __be16 *
      41 68262457950 : xfs_dir2_data_entry_tag_p(
      42             :         struct xfs_mount                *mp,
      43             :         struct xfs_dir2_data_entry      *dep)
      44             : {
      45 >13652*10^7 :         return (__be16 *)((char *)dep +
      46 68262457950 :                 xfs_dir2_data_entsize(mp, dep->namelen) - sizeof(__be16));
      47             : }
      48             : 
      49             : uint8_t
      50 18604559922 : xfs_dir2_data_get_ftype(
      51             :         struct xfs_mount                *mp,
      52             :         struct xfs_dir2_data_entry      *dep)
      53             : {
      54 18604559922 :         if (xfs_has_ftype(mp)) {
      55 88067369839 :                 uint8_t                 ftype = dep->name[dep->namelen];
      56             : 
      57 88067369839 :                 if (likely(ftype < XFS_DIR3_FT_MAX))
      58 19367110890 :                         return ftype;
      59             :         }
      60             : 
      61             :         return XFS_DIR3_FT_UNKNOWN;
      62             : }
      63             : 
      64             : void
      65    36833746 : xfs_dir2_data_put_ftype(
      66             :         struct xfs_mount                *mp,
      67             :         struct xfs_dir2_data_entry      *dep,
      68             :         uint8_t                         ftype)
      69             : {
      70    36833746 :         ASSERT(ftype < XFS_DIR3_FT_MAX);
      71    36833746 :         ASSERT(dep->namelen != 0);
      72             : 
      73    36833746 :         if (xfs_has_ftype(mp))
      74    36834494 :                 dep->name[dep->namelen] = ftype;
      75    36833746 : }
      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    16706133 :         return (geo->blksize - sizeof(struct xfs_dir2_block_tail) -
      88    16706133 :                 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   428124085 : __xfs_dir3_data_check(
      99             :         struct xfs_inode        *dp,            /* incore inode pointer */
     100             :         struct xfs_buf          *bp)            /* data block's buffer */
     101             : {
     102   428124085 :         xfs_dir2_dataptr_t      addr;           /* addr for leaf lookup */
     103   428124085 :         xfs_dir2_data_free_t    *bf;            /* bestfree table */
     104   428124085 :         xfs_dir2_block_tail_t   *btp=NULL;      /* block tail */
     105   428124085 :         int                     count;          /* count of entries found */
     106   428124085 :         xfs_dir2_data_hdr_t     *hdr;           /* data block header */
     107   428124085 :         xfs_dir2_data_free_t    *dfp;           /* bestfree entry */
     108   428124085 :         int                     freeseen;       /* mask of bestfrees seen */
     109   428124085 :         xfs_dahash_t            hash;           /* hash of current name */
     110   428124085 :         int                     i;              /* leaf index */
     111   428124085 :         int                     lastfree;       /* last entry was unused */
     112   428124085 :         xfs_dir2_leaf_entry_t   *lep=NULL;      /* block leaf entries */
     113   428124085 :         struct xfs_mount        *mp = bp->b_mount;
     114   428124085 :         int                     stale;          /* count of stale leaves */
     115   428124085 :         struct xfs_name         name;
     116   428124085 :         unsigned int            offset;
     117   428124085 :         unsigned int            end;
     118   428124085 :         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   428124085 :         if (dp && !S_ISDIR(VFS_I(dp)->i_mode))
     124           0 :                 return __this_address;
     125             : 
     126   428124085 :         hdr = bp->b_addr;
     127   428124085 :         offset = geo->data_entry_offset;
     128             : 
     129   428124085 :         switch (hdr->magic) {
     130             :         case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
     131             :         case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
     132    16706133 :                 btp = xfs_dir2_block_tail_p(geo, hdr);
     133    16706133 :                 lep = xfs_dir2_block_leaf_p(btp);
     134             : 
     135    33412266 :                 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   428124085 :         end = xfs_dir3_data_end_offset(geo, hdr);
     146   428124085 :         if (!end)
     147           0 :                 return __this_address;
     148             : 
     149             :         /*
     150             :          * Account for zero bestfree entries.
     151             :          */
     152   428124085 :         bf = xfs_dir2_data_bestfree_p(mp, hdr);
     153   428124085 :         count = lastfree = freeseen = 0;
     154   428124085 :         if (!bf[0].length) {
     155   132228683 :                 if (bf[0].offset)
     156           0 :                         return __this_address;
     157             :                 freeseen |= 1 << 0;
     158             :         }
     159   428124085 :         if (!bf[1].length) {
     160   198450144 :                 if (bf[1].offset)
     161           0 :                         return __this_address;
     162   198450144 :                 freeseen |= 1 << 1;
     163             :         }
     164   428124085 :         if (!bf[2].length) {
     165   228156833 :                 if (bf[2].offset)
     166           0 :                         return __this_address;
     167   228156833 :                 freeseen |= 1 << 2;
     168             :         }
     169             : 
     170   428124085 :         if (be16_to_cpu(bf[0].length) < be16_to_cpu(bf[1].length))
     171           0 :                 return __this_address;
     172   428124085 :         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 74569123679 :         while (offset < end) {
     178 74141196781 :                 struct xfs_dir2_data_unused     *dup = bp->b_addr + offset;
     179 74141196781 :                 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 74141196781 :                 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
     187  5477710754 :                         xfs_failaddr_t  fa;
     188             : 
     189  5477710754 :                         if (lastfree != 0)
     190           0 :                                 return __this_address;
     191  5477710754 :                         if (offset + be16_to_cpu(dup->length) > end)
     192           0 :                                 return __this_address;
     193  5477710754 :                         if (be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) !=
     194             :                             offset)
     195           0 :                                 return __this_address;
     196  5477710754 :                         fa = xfs_dir2_data_freefind_verify(hdr, bf, dup, &dfp);
     197  5496879887 :                         if (fa)
     198           0 :                                 return fa;
     199  5496879887 :                         if (dfp) {
     200   731436431 :                                 i = (int)(dfp - bf);
     201   731436431 :                                 if ((freeseen & (1 << i)) != 0)
     202           0 :                                         return __this_address;
     203   731436431 :                                 freeseen |= 1 << i;
     204             :                         } else {
     205  9530886912 :                                 if (be16_to_cpu(dup->length) >
     206  4765443456 :                                     be16_to_cpu(bf[2].length))
     207           0 :                                         return __this_address;
     208             :                         }
     209  5496879887 :                         offset += be16_to_cpu(dup->length);
     210  5496879887 :                         lastfree = 1;
     211  5496879887 :                         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 68663486027 :                 if (dep->namelen == 0)
     220           0 :                         return __this_address;
     221 68663486027 :                 if (!xfs_verify_dir_ino(mp, be64_to_cpu(dep->inumber)))
     222           0 :                         return __this_address;
     223 >13673*10^7 :                 if (offset + xfs_dir2_data_entsize(mp, dep->namelen) > end)
     224           0 :                         return __this_address;
     225 68643914612 :                 if (be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)) != offset)
     226           0 :                         return __this_address;
     227 >13734*10^7 :                 if (xfs_dir2_data_get_ftype(mp, dep) >= XFS_DIR3_FT_MAX)
     228           0 :                         return __this_address;
     229 68643914612 :                 count++;
     230 68643914612 :                 lastfree = 0;
     231 68643914612 :                 if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
     232             :                     hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
     233   649621180 :                         addr = xfs_dir2_db_off_to_dataptr(geo, geo->datablk,
     234             :                                                 (xfs_dir2_data_aoff_t)
     235   649621180 :                                                 ((char *)dep - (char *)hdr));
     236   650215013 :                         name.name = dep->name;
     237   650215013 :                         name.len = dep->namelen;
     238   650215013 :                         hash = xfs_dir2_hashname(mp, &name);
     239 59551552377 :                         for (i = 0; i < be32_to_cpu(btp->count); i++) {
     240 59560004241 :                                 if (be32_to_cpu(lep[i].address) == addr &&
     241   651283579 :                                     be32_to_cpu(lep[i].hashval) == hash)
     242             :                                         break;
     243             :                         }
     244   649826275 :                         if (i >= be32_to_cpu(btp->count))
     245           0 :                                 return __this_address;
     246             :                 }
     247 >13734*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   427926898 :         if (freeseen != 7)
     253           0 :                 return __this_address;
     254   427926898 :         if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC) ||
     255             :             hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC)) {
     256  1470987808 :                 for (i = stale = 0; i < be32_to_cpu(btp->count); i++) {
     257   718786063 :                         if (lep[i].address ==
     258             :                             cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
     259    64373507 :                                 stale++;
     260  1420906662 :                         if (i > 0 && be32_to_cpu(lep[i].hashval) <
     261   702120599 :                                      be32_to_cpu(lep[i - 1].hashval))
     262           0 :                                 return __this_address;
     263             :                 }
     264    33415682 :                 if (count != be32_to_cpu(btp->count) - be32_to_cpu(btp->stale))
     265          70 :                         return __this_address;
     266    16707785 :                 if (stale != be32_to_cpu(btp->stale))
     267           0 :                         return __this_address;
     268             :         }
     269             :         return NULL;
     270             : }
     271             : 
     272             : #ifdef DEBUG
     273             : void
     274   311833592 : xfs_dir3_data_check(
     275             :         struct xfs_inode        *dp,
     276             :         struct xfs_buf          *bp)
     277             : {
     278   311833592 :         xfs_failaddr_t          fa;
     279             : 
     280   311833592 :         fa = __xfs_dir3_data_check(dp, bp);
     281   311873129 :         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   115888330 : xfs_dir3_data_verify(
     292             :         struct xfs_buf          *bp)
     293             : {
     294   115888330 :         struct xfs_mount        *mp = bp->b_mount;
     295   115888330 :         struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
     296             : 
     297   115888330 :         if (!xfs_verify_magic(bp, hdr3->magic))
     298           0 :                 return __this_address;
     299             : 
     300   115889747 :         if (xfs_has_crc(mp)) {
     301   115885893 :                 if (!uuid_equal(&hdr3->uuid, &mp->m_sb.sb_meta_uuid))
     302           0 :                         return __this_address;
     303   115878255 :                 if (be64_to_cpu(hdr3->blkno) != xfs_buf_daddr(bp))
     304           0 :                         return __this_address;
     305   115889528 :                 if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn)))
     306           0 :                         return __this_address;
     307             :         }
     308   115892382 :         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       42937 : xfs_dir3_data_reada_verify(
     318             :         struct xfs_buf          *bp)
     319             : {
     320       42937 :         struct xfs_dir2_data_hdr *hdr = bp->b_addr;
     321             : 
     322       42937 :         switch (hdr->magic) {
     323        1103 :         case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
     324             :         case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
     325        1103 :                 bp->b_ops = &xfs_dir3_block_buf_ops;
     326        1103 :                 bp->b_ops->verify_read(bp);
     327        1103 :                 return;
     328       41834 :         case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
     329             :         case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
     330       41834 :                 bp->b_ops = &xfs_dir3_data_buf_ops;
     331       41834 :                 bp->b_ops->verify_read(bp);
     332       41834 :                 return;
     333             :         default:
     334           0 :                 xfs_verifier_error(bp, -EFSCORRUPTED, __this_address);
     335           0 :                 break;
     336             :         }
     337             : }
     338             : 
     339             : static void
     340      175025 : xfs_dir3_data_read_verify(
     341             :         struct xfs_buf  *bp)
     342             : {
     343      175025 :         struct xfs_mount        *mp = bp->b_mount;
     344      175025 :         xfs_failaddr_t          fa;
     345             : 
     346      350050 :         if (xfs_has_crc(mp) &&
     347             :             !xfs_buf_verify_cksum(bp, XFS_DIR3_DATA_CRC_OFF))
     348          18 :                 xfs_verifier_error(bp, -EFSBADCRC, __this_address);
     349             :         else {
     350      175007 :                 fa = xfs_dir3_data_verify(bp);
     351      175007 :                 if (fa)
     352           0 :                         xfs_verifier_error(bp, -EFSCORRUPTED, fa);
     353             :         }
     354      175025 : }
     355             : 
     356             : static void
     357      707011 : xfs_dir3_data_write_verify(
     358             :         struct xfs_buf  *bp)
     359             : {
     360      707011 :         struct xfs_mount        *mp = bp->b_mount;
     361      707011 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     362      707011 :         struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
     363      707011 :         xfs_failaddr_t          fa;
     364             : 
     365      707011 :         fa = xfs_dir3_data_verify(bp);
     366      707011 :         if (fa) {
     367           0 :                 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
     368           0 :                 return;
     369             :         }
     370             : 
     371      707011 :         if (!xfs_has_crc(mp))
     372             :                 return;
     373             : 
     374      707011 :         if (bip)
     375      707011 :                 hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
     376             : 
     377      707011 :         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   413058102 : xfs_dir3_data_header_check(
     399             :         struct xfs_inode        *dp,
     400             :         struct xfs_buf          *bp)
     401             : {
     402   413058102 :         struct xfs_mount        *mp = dp->i_mount;
     403             : 
     404   413058102 :         if (xfs_has_crc(mp)) {
     405   413058102 :                 struct xfs_dir3_data_hdr *hdr3 = bp->b_addr;
     406             : 
     407   413058102 :                 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   413000867 : 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   413000867 :         xfs_failaddr_t          fa;
     423   413000867 :         int                     err;
     424             : 
     425   413000867 :         err = xfs_da_read_buf(tp, dp, bno, flags, bpp, XFS_DATA_FORK,
     426             :                         &xfs_dir3_data_buf_ops);
     427   413406779 :         if (err || !*bpp)
     428             :                 return err;
     429             : 
     430             :         /* Check things that we can't do in the verifier. */
     431   413402581 :         fa = xfs_dir3_data_header_check(dp, *bpp);
     432   413406931 :         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   413406931 :         xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_DATA_BUF);
     440   413406931 :         return err;
     441             : }
     442             : 
     443             : int
     444   104345942 : xfs_dir3_data_readahead(
     445             :         struct xfs_inode        *dp,
     446             :         xfs_dablk_t             bno,
     447             :         unsigned int            flags)
     448             : {
     449   104345942 :         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  5497405616 : 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  5497405616 :         struct xfs_dir2_data_free       *dfp;
     465  5497405616 :         xfs_dir2_data_aoff_t            off;
     466  5497405616 :         bool                            matched = false;
     467  5497405616 :         bool                            seenzero = false;
     468             : 
     469  5497405616 :         *bf_ent = NULL;
     470  5497405616 :         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 21963846035 :         for (dfp = &bf[0]; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) {
     478 16466440419 :                 if (!dfp->offset) {
     479   191876320 :                         if (dfp->length)
     480           0 :                                 return __this_address;
     481   191876320 :                         seenzero = true;
     482   191876320 :                         continue;
     483             :                 }
     484 16274564099 :                 if (seenzero)
     485           0 :                         return __this_address;
     486 16274564099 :                 if (be16_to_cpu(dfp->offset) == off) {
     487   725179595 :                         matched = true;
     488   725179595 :                         if (dfp->length != dup->length)
     489           0 :                                 return __this_address;
     490 15549384504 :                 } else if (be16_to_cpu(dfp->offset) > off) {
     491  3470131645 :                         if (off + be16_to_cpu(dup->length) >
     492             :                                         be16_to_cpu(dfp->offset))
     493           0 :                                 return __this_address;
     494             :                 } else {
     495 24158505718 :                         if (be16_to_cpu(dfp->offset) +
     496 12079252859 :                                         be16_to_cpu(dfp->length) > off)
     497           0 :                                 return __this_address;
     498             :                 }
     499 30453771132 :                 if (!matched &&
     500 14904386628 :                     be16_to_cpu(dfp->length) < be16_to_cpu(dup->length))
     501           0 :                         return __this_address;
     502 27056155490 :                 if (dfp > &bf[0] &&
     503 10781591391 :                     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  5497405616 :         *bf_ent = xfs_dir2_data_freefind(hdr, bf, dup);
     509  5497405616 :         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  5514096854 : 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  5514096854 :         xfs_dir2_data_free_t    *dfp;           /* bestfree entry */
     523  5514096854 :         xfs_dir2_data_aoff_t    off;            /* offset value needed */
     524             : 
     525  5514096854 :         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 11028193708 :         if (be16_to_cpu(dup->length) <
     532  5514096854 :             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 14176215577 :         for (dfp = &bf[0]; dfp < &bf[XFS_DIR2_DATA_FD_COUNT]; dfp++) {
     538 11003231774 :                 if (!dfp->offset)
     539             :                         return NULL;
     540 11003231774 :                 if (be16_to_cpu(dfp->offset) == off)
     541   766682395 :                         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   543256049 : 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   543256049 :         xfs_dir2_data_free_t    new;            /* new bestfree entry */
     560             : 
     561   543256049 :         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   543256049 :         new.length = dup->length;
     567   543256049 :         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   543256049 :         if (be16_to_cpu(new.length) > be16_to_cpu(dfp[0].length)) {
     573    53222668 :                 dfp[2] = dfp[1];
     574    53222668 :                 dfp[1] = dfp[0];
     575    53222668 :                 dfp[0] = new;
     576    53222668 :                 *loghead = 1;
     577    53222668 :                 return &dfp[0];
     578             :         }
     579   490033381 :         if (be16_to_cpu(new.length) > be16_to_cpu(dfp[1].length)) {
     580    33744195 :                 dfp[2] = dfp[1];
     581    33744195 :                 dfp[1] = new;
     582    33744195 :                 *loghead = 1;
     583    33744195 :                 return &dfp[1];
     584             :         }
     585   456289186 :         if (be16_to_cpu(new.length) > be16_to_cpu(dfp[2].length)) {
     586    34097206 :                 dfp[2] = new;
     587    34097206 :                 *loghead = 1;
     588    34097206 :                 return &dfp[2];
     589             :         }
     590             :         return NULL;
     591             : }
     592             : 
     593             : /*
     594             :  * Remove a bestfree entry from the table.
     595             :  */
     596             : STATIC void
     597    31451300 : 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    31451300 :         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    31451300 :         if (dfp == &bf[0]) {
     613    29769492 :                 bf[0] = bf[1];
     614    29769492 :                 bf[1] = bf[2];
     615             :         }
     616             :         /*
     617             :          * It's the second entry, slide the 3rd entry up.
     618             :          */
     619     1681808 :         else if (dfp == &bf[1])
     620     1406554 :                 bf[1] = bf[2];
     621             :         /*
     622             :          * Must be the last entry.
     623             :          */
     624             :         else
     625      275254 :                 ASSERT(dfp == &bf[2]);
     626             :         /*
     627             :          * Clear the 3rd entry, must be zero now.
     628             :          */
     629    31451300 :         bf[2].length = 0;
     630    31451300 :         bf[2].offset = 0;
     631    31451300 :         *loghead = 1;
     632    31451300 : }
     633             : 
     634             : /*
     635             :  * Given a data block, reconstruct its bestfree map.
     636             :  */
     637             : void
     638    19624624 : xfs_dir2_data_freescan(
     639             :         struct xfs_mount                *mp,
     640             :         struct xfs_dir2_data_hdr        *hdr,
     641             :         int                             *loghead)
     642             : {
     643    19624624 :         struct xfs_da_geometry          *geo = mp->m_dir_geo;
     644    19624624 :         struct xfs_dir2_data_free       *bf = xfs_dir2_data_bestfree_p(mp, hdr);
     645    19624624 :         void                            *addr = hdr;
     646    19624624 :         unsigned int                    offset = geo->data_entry_offset;
     647    19624624 :         unsigned int                    end;
     648             : 
     649    19624624 :         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    19624624 :         memset(bf, 0, sizeof(*bf) * XFS_DIR2_DATA_FD_COUNT);
     658    19624624 :         *loghead = 1;
     659             : 
     660    19624624 :         end = xfs_dir3_data_end_offset(geo, addr);
     661  3105173410 :         while (offset < end) {
     662  3085547674 :                 struct xfs_dir2_data_unused     *dup = addr + offset;
     663  3085547674 :                 struct xfs_dir2_data_entry      *dep = addr + offset;
     664             : 
     665             :                 /*
     666             :                  * If it's a free entry, insert it.
     667             :                  */
     668  3085547674 :                 if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
     669   500338557 :                         ASSERT(offset ==
     670             :                                be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)));
     671   500338557 :                         xfs_dir2_data_freeinsert(hdr, bf, dup, loghead);
     672   500339669 :                         offset += be16_to_cpu(dup->length);
     673   500339669 :                         continue;
     674             :                 }
     675             : 
     676             :                 /*
     677             :                  * For active entries, check their tags and skip them.
     678             :                  */
     679  2585209117 :                 ASSERT(offset ==
     680             :                        be16_to_cpu(*xfs_dir2_data_entry_tag_p(mp, dep)));
     681  5171056684 :                 offset += xfs_dir2_data_entsize(mp, dep->namelen);
     682             :         }
     683    19625736 : }
     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       94753 : 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       94753 :         struct xfs_trans                *tp = args->trans;
     696       94753 :         struct xfs_inode                *dp = args->dp;
     697       94753 :         struct xfs_mount                *mp = dp->i_mount;
     698       94753 :         struct xfs_da_geometry          *geo = args->geo;
     699       94753 :         struct xfs_buf                  *bp;
     700       94753 :         struct xfs_dir2_data_hdr        *hdr;
     701       94753 :         struct xfs_dir2_data_unused     *dup;
     702       94753 :         struct xfs_dir2_data_free       *bf;
     703       94753 :         int                             error;
     704       94753 :         int                             i;
     705             : 
     706             :         /*
     707             :          * Get the buffer set up for the block.
     708             :          */
     709       94753 :         error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, blkno),
     710             :                                &bp, XFS_DATA_FORK);
     711       94753 :         if (error)
     712             :                 return error;
     713       94753 :         bp->b_ops = &xfs_dir3_data_buf_ops;
     714       94753 :         xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_DATA_BUF);
     715             : 
     716             :         /*
     717             :          * Initialize the header.
     718             :          */
     719       94753 :         hdr = bp->b_addr;
     720       94753 :         if (xfs_has_crc(mp)) {
     721       94749 :                 struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
     722             : 
     723       94749 :                 memset(hdr3, 0, sizeof(*hdr3));
     724       94749 :                 hdr3->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC);
     725       94749 :                 hdr3->blkno = cpu_to_be64(xfs_buf_daddr(bp));
     726       94749 :                 hdr3->owner = cpu_to_be64(dp->i_ino);
     727       94749 :                 uuid_copy(&hdr3->uuid, &mp->m_sb.sb_meta_uuid);
     728             : 
     729             :         } else
     730           4 :                 hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
     731             : 
     732       94753 :         bf = xfs_dir2_data_bestfree_p(mp, hdr);
     733       94753 :         bf[0].offset = cpu_to_be16(geo->data_entry_offset);
     734       94753 :         bf[0].length = cpu_to_be16(geo->blksize - geo->data_entry_offset);
     735      284259 :         for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) {
     736      189506 :                 bf[i].length = 0;
     737      189506 :                 bf[i].offset = 0;
     738             :         }
     739             : 
     740             :         /*
     741             :          * Set up an unused entry for the block's body.
     742             :          */
     743       94753 :         dup = bp->b_addr + geo->data_entry_offset;
     744       94753 :         dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
     745       94753 :         dup->length = bf[0].length;
     746       94753 :         *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr);
     747             : 
     748             :         /*
     749             :          * Log it and return it.
     750             :          */
     751       94753 :         xfs_dir2_data_log_header(args, bp);
     752       94753 :         xfs_dir2_data_log_unused(args, bp, dup);
     753       94753 :         *bpp = bp;
     754       94753 :         return 0;
     755             : }
     756             : 
     757             : /*
     758             :  * Log an active data entry from the block.
     759             :  */
     760             : void
     761    36832225 : 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    36832225 :         struct xfs_mount        *mp = bp->b_mount;
     767    36832225 :         struct xfs_dir2_data_hdr *hdr = bp->b_addr;
     768             : 
     769    36832225 :         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    36832225 :         xfs_trans_log_buf(args->trans, bp, (uint)((char *)dep - (char *)hdr),
     775    36832225 :                 (uint)((char *)(xfs_dir2_data_entry_tag_p(mp, dep) + 1) -
     776    36832225 :                        (char *)hdr - 1));
     777    36832453 : }
     778             : 
     779             : /*
     780             :  * Log a data block header.
     781             :  */
     782             : void
     783    55583630 : xfs_dir2_data_log_header(
     784             :         struct xfs_da_args      *args,
     785             :         struct xfs_buf          *bp)
     786             : {
     787             : #ifdef DEBUG
     788    55583630 :         struct xfs_dir2_data_hdr *hdr = bp->b_addr;
     789             : 
     790    55583630 :         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    55583630 :         xfs_trans_log_buf(args->trans, bp, 0, args->geo->data_entry_offset - 1);
     797    55584386 : }
     798             : 
     799             : /*
     800             :  * Log a data unused entry.
     801             :  */
     802             : void
     803    49154237 : 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    49154237 :         xfs_dir2_data_hdr_t     *hdr = bp->b_addr;
     809             : 
     810    49154237 :         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    49154237 :         xfs_trans_log_buf(args->trans, bp, (uint)((char *)dup - (char *)hdr),
     819    49154237 :                 (uint)((char *)&dup->length + sizeof(dup->length) -
     820    49154237 :                        1 - (char *)hdr));
     821             :         /*
     822             :          * Log the end (tag) of the unused entry.
     823             :          */
     824    49156949 :         xfs_trans_log_buf(args->trans, bp,
     825    49156949 :                 (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr),
     826             :                 (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr +
     827             :                        sizeof(xfs_dir2_data_off_t) - 1));
     828    49160022 : }
     829             : 
     830             : /*
     831             :  * Make a byte range in the data block unused.
     832             :  * Its current contents are unimportant.
     833             :  */
     834             : void
     835    32658292 : 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    32658292 :         xfs_dir2_data_hdr_t     *hdr;           /* data block pointer */
     844    32658292 :         xfs_dir2_data_free_t    *dfp;           /* bestfree pointer */
     845    32658292 :         int                     needscan;       /* need to regen bestfree */
     846    32658292 :         xfs_dir2_data_unused_t  *newdup;        /* new unused entry */
     847    32658292 :         xfs_dir2_data_unused_t  *postdup;       /* unused entry after us */
     848    32658292 :         xfs_dir2_data_unused_t  *prevdup;       /* unused entry before us */
     849    32658292 :         unsigned int            end;
     850    32658292 :         struct xfs_dir2_data_free *bf;
     851             : 
     852    32658292 :         hdr = bp->b_addr;
     853             : 
     854             :         /*
     855             :          * Figure out where the end of the data area is.
     856             :          */
     857    32658292 :         end = xfs_dir3_data_end_offset(args->geo, hdr);
     858    32658292 :         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    32658292 :         if (offset > args->geo->data_entry_offset) {
     865    32491223 :                 __be16                  *tagp;  /* tag just before us */
     866             : 
     867    32491223 :                 tagp = (__be16 *)((char *)hdr + offset) - 1;
     868    32491223 :                 prevdup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp));
     869    32491223 :                 if (be16_to_cpu(prevdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
     870    24784698 :                         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    32658292 :         if (offset + len < end) {
     878    32497377 :                 postdup =
     879    32497377 :                         (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
     880    32497377 :                 if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG)
     881    27310925 :                         postdup = NULL;
     882             :         } else
     883             :                 postdup = NULL;
     884    32658292 :         ASSERT(*needscanp == 0);
     885    32658292 :         needscan = 0;
     886             :         /*
     887             :          * Previous and following entries are both free,
     888             :          * merge everything into a single free entry.
     889             :          */
     890    32658292 :         bf = xfs_dir2_data_bestfree_p(args->dp->i_mount, hdr);
     891    32658292 :         if (prevdup && postdup) {
     892     1593563 :                 xfs_dir2_data_free_t    *dfp2;  /* another bestfree pointer */
     893             : 
     894             :                 /*
     895             :                  * See if prevdup and/or postdup are in bestfree table.
     896             :                  */
     897     1593563 :                 dfp = xfs_dir2_data_freefind(hdr, bf, prevdup);
     898     1593563 :                 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     1593563 :                 needscan = (bf[2].length != 0);
     906             :                 /*
     907             :                  * Fix up the new big freespace.
     908             :                  */
     909     3187126 :                 be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length));
     910     3187162 :                 *xfs_dir2_data_unused_tag_p(prevdup) =
     911     1593581 :                         cpu_to_be16((char *)prevdup - (char *)hdr);
     912     1593581 :                 xfs_dir2_data_log_unused(args, bp, prevdup);
     913     1593596 :                 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       66266 :                         ASSERT(dfp && dfp2);
     921       66266 :                         if (dfp == &bf[1]) {
     922       55343 :                                 dfp = &bf[0];
     923       55343 :                                 ASSERT(dfp2 == dfp);
     924             :                                 dfp2 = &bf[1];
     925             :                         }
     926       66266 :                         xfs_dir2_data_freeremove(hdr, bf, dfp2, needlogp);
     927       66266 :                         xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
     928             :                         /*
     929             :                          * Now insert the new entry.
     930             :                          */
     931       66266 :                         dfp = xfs_dir2_data_freeinsert(hdr, bf, prevdup,
     932             :                                                        needlogp);
     933       66266 :                         ASSERT(dfp == &bf[0]);
     934       66266 :                         ASSERT(dfp->length == prevdup->length);
     935       66266 :                         ASSERT(!dfp[1].length);
     936       66266 :                         ASSERT(!dfp[2].length);
     937             :                 }
     938             :         }
     939             :         /*
     940             :          * The entry before us is free, merge with it.
     941             :          */
     942    31064729 :         else if (prevdup) {
     943     6114791 :                 dfp = xfs_dir2_data_freefind(hdr, bf, prevdup);
     944     6114791 :                 be16_add_cpu(&prevdup->length, len);
     945    12229572 :                 *xfs_dir2_data_unused_tag_p(prevdup) =
     946     6114786 :                         cpu_to_be16((char *)prevdup - (char *)hdr);
     947     6114786 :                 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     6114950 :                 if (dfp) {
     954     4554383 :                         xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
     955     4554392 :                         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     3121134 :                         needscan = be16_to_cpu(prevdup->length) >
     962     1560567 :                                    be16_to_cpu(bf[2].length);
     963             :                 }
     964             :         }
     965             :         /*
     966             :          * The following entry is free, merge with it.
     967             :          */
     968    24949938 :         else if (postdup) {
     969     3593273 :                 dfp = xfs_dir2_data_freefind(hdr, bf, postdup);
     970     3593273 :                 newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset);
     971     3593273 :                 newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
     972     7186546 :                 newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length));
     973     7186546 :                 *xfs_dir2_data_unused_tag_p(newdup) =
     974     3593273 :                         cpu_to_be16((char *)newdup - (char *)hdr);
     975     3593273 :                 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     3593254 :                 if (dfp) {
     982      558302 :                         xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
     983      558303 :                         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     6069904 :                         needscan = be16_to_cpu(newdup->length) >
     990     3034952 :                                    be16_to_cpu(bf[2].length);
     991             :                 }
     992             :         }
     993             :         /*
     994             :          * Neither neighbor is free.  Make a new entry.
     995             :          */
     996             :         else {
     997    21356665 :                 newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset);
     998    21356665 :                 newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
     999    21356665 :                 newdup->length = cpu_to_be16(len);
    1000    42713330 :                 *xfs_dir2_data_unused_tag_p(newdup) =
    1001    21356665 :                         cpu_to_be16((char *)newdup - (char *)hdr);
    1002    21356665 :                 xfs_dir2_data_log_unused(args, bp, newdup);
    1003    21357043 :                 xfs_dir2_data_freeinsert(hdr, bf, newdup, needlogp);
    1004             :         }
    1005    32659151 :         *needscanp = needscan;
    1006    32659151 : }
    1007             : 
    1008             : /* Check our free data for obvious signs of corruption. */
    1009             : static inline xfs_failaddr_t
    1010    35745301 : 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    35745301 :         if (hdr->magic != cpu_to_be32(XFS_DIR2_DATA_MAGIC) &&
    1017     2245476 :             hdr->magic != cpu_to_be32(XFS_DIR3_DATA_MAGIC) &&
    1018     2245124 :             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    35745301 :         if (be16_to_cpu(dup->freetag) != XFS_DIR2_DATA_FREE_TAG)
    1022           0 :                 return __this_address;
    1023    35745301 :         if (offset < (char *)dup - (char *)hdr)
    1024           0 :                 return __this_address;
    1025    35745301 :         if (offset + len > (char *)dup + be16_to_cpu(dup->length) - (char *)hdr)
    1026           0 :                 return __this_address;
    1027    35745301 :         if ((char *)dup - (char *)hdr !=
    1028    35745301 :                         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    16006961 : 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    16006961 :         if (dfp == NULL)
    1041           0 :                 return __this_address;
    1042    16006961 :         if (dfp->length != newdup->length)
    1043           0 :                 return __this_address;
    1044    16006961 :         if (be16_to_cpu(dfp->offset) != (char *)newdup - (char *)hdr)
    1045         898 :                 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    35743662 : 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    35743662 :         xfs_dir2_data_hdr_t     *hdr;           /* data block header */
    1063    35743662 :         xfs_dir2_data_free_t    *dfp;           /* bestfree pointer */
    1064    35743662 :         xfs_dir2_data_unused_t  *newdup;        /* new unused entry */
    1065    35743662 :         xfs_dir2_data_unused_t  *newdup2;       /* another new unused entry */
    1066    35743662 :         struct xfs_dir2_data_free *bf;
    1067    35743662 :         xfs_failaddr_t          fa;
    1068    35743662 :         int                     matchback;      /* matches end of freespace */
    1069    35743662 :         int                     matchfront;     /* matches start of freespace */
    1070    35743662 :         int                     needscan;       /* need to regen bestfree */
    1071    35743662 :         int                     oldlen;         /* old unused entry's length */
    1072             : 
    1073    35743662 :         hdr = bp->b_addr;
    1074    35743662 :         fa = xfs_dir2_data_check_free(hdr, dup, offset, len);
    1075    35745143 :         if (fa)
    1076           0 :                 goto corrupt;
    1077             :         /*
    1078             :          * Look up the entry in the bestfree table.
    1079             :          */
    1080    35745143 :         oldlen = be16_to_cpu(dup->length);
    1081    35745143 :         bf = xfs_dir2_data_bestfree_p(args->dp->i_mount, hdr);
    1082    35745143 :         dfp = xfs_dir2_data_freefind(hdr, bf, dup);
    1083    35745143 :         ASSERT(dfp || oldlen <= be16_to_cpu(bf[2].length));
    1084             :         /*
    1085             :          * Check for alignment with front and back of the entry.
    1086             :          */
    1087    35745143 :         matchfront = (char *)dup - (char *)hdr == offset;
    1088    35745143 :         matchback = (char *)dup + oldlen - (char *)hdr == offset + len;
    1089    35745143 :         ASSERT(*needscanp == 0);
    1090    35745143 :         needscan = 0;
    1091             :         /*
    1092             :          * If we matched it exactly we just need to get rid of it from
    1093             :          * the bestfree table.
    1094             :          */
    1095    35745143 :         if (matchfront && matchback) {
    1096    19718312 :                 if (dfp) {
    1097    19714467 :                         needscan = (bf[2].offset != 0);
    1098    19714467 :                         if (!needscan)
    1099    10199396 :                                 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    16026831 :         else if (matchfront) {
    1108    15139214 :                 newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len);
    1109    15139214 :                 newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG);
    1110    15139214 :                 newdup->length = cpu_to_be16(oldlen - len);
    1111    30278428 :                 *xfs_dir2_data_unused_tag_p(newdup) =
    1112    15139214 :                         cpu_to_be16((char *)newdup - (char *)hdr);
    1113    15139214 :                 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    15138928 :                 if (dfp) {
    1118    15138671 :                         xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
    1119    15139039 :                         dfp = xfs_dir2_data_freeinsert(hdr, bf, newdup,
    1120             :                                                        needlogp);
    1121    15139249 :                         fa = xfs_dir2_data_check_new_free(hdr, dfp, newdup);
    1122    15139302 :                         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    15139302 :                         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      887617 :         else if (matchback) {
    1137      887617 :                 newdup = dup;
    1138      887617 :                 newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup);
    1139     1775234 :                 *xfs_dir2_data_unused_tag_p(newdup) =
    1140      887617 :                         cpu_to_be16((char *)newdup - (char *)hdr);
    1141      887617 :                 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      887623 :                 if (dfp) {
    1146      867812 :                         xfs_dir2_data_freeremove(hdr, bf, dfp, needlogp);
    1147      867801 :                         dfp = xfs_dir2_data_freeinsert(hdr, bf, newdup,
    1148             :                                                        needlogp);
    1149      867805 :                         fa = xfs_dir2_data_check_new_free(hdr, dfp, newdup);
    1150      867812 :                         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      867812 :                         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    35745595 :         *needscanp = needscan;
    1197    35745595 :         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   595813052 : xfs_dir3_data_end_offset(
    1207             :         struct xfs_da_geometry          *geo,
    1208             :         struct xfs_dir2_data_hdr        *hdr)
    1209             : {
    1210   595813052 :         void                            *p;
    1211             : 
    1212   595813052 :         switch (hdr->magic) {
    1213             :         case cpu_to_be32(XFS_DIR3_BLOCK_MAGIC):
    1214             :         case cpu_to_be32(XFS_DIR2_BLOCK_MAGIC):
    1215    18973366 :                 p = xfs_dir2_block_leaf_p(xfs_dir2_block_tail_p(geo, hdr));
    1216    18973366 :                 return p - (void *)hdr;
    1217   576839686 :         case cpu_to_be32(XFS_DIR3_DATA_MAGIC):
    1218             :         case cpu_to_be32(XFS_DIR2_DATA_MAGIC):
    1219   576839686 :                 return geo->blksize;
    1220             :         default:
    1221             :                 return 0;
    1222             :         }
    1223             : }

Generated by: LCOV version 1.14