LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_attr_leaf.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsa @ Mon Jul 31 20:08:27 PDT 2023 Lines: 1318 1450 90.9 %
Date: 2023-07-31 20:08:27 Functions: 48 48 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (c) 2000-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_sb.h"
      14             : #include "xfs_mount.h"
      15             : #include "xfs_da_format.h"
      16             : #include "xfs_da_btree.h"
      17             : #include "xfs_inode.h"
      18             : #include "xfs_trans.h"
      19             : #include "xfs_bmap_btree.h"
      20             : #include "xfs_bmap.h"
      21             : #include "xfs_attr_sf.h"
      22             : #include "xfs_attr.h"
      23             : #include "xfs_attr_remote.h"
      24             : #include "xfs_attr_leaf.h"
      25             : #include "xfs_error.h"
      26             : #include "xfs_trace.h"
      27             : #include "xfs_buf_item.h"
      28             : #include "xfs_dir2.h"
      29             : #include "xfs_log.h"
      30             : #include "xfs_ag.h"
      31             : #include "xfs_errortag.h"
      32             : #include "xfs_health.h"
      33             : 
      34             : 
      35             : /*
      36             :  * xfs_attr_leaf.c
      37             :  *
      38             :  * Routines to implement leaf blocks of attributes as Btrees of hashed names.
      39             :  */
      40             : 
      41             : /*========================================================================
      42             :  * Function prototypes for the kernel.
      43             :  *========================================================================*/
      44             : 
      45             : /*
      46             :  * Routines used for growing the Btree.
      47             :  */
      48             : STATIC int xfs_attr3_leaf_create(struct xfs_da_args *args,
      49             :                                  xfs_dablk_t which_block, struct xfs_buf **bpp);
      50             : STATIC int xfs_attr3_leaf_add_work(struct xfs_buf *leaf_buffer,
      51             :                                    struct xfs_attr3_icleaf_hdr *ichdr,
      52             :                                    struct xfs_da_args *args, int freemap_index);
      53             : STATIC void xfs_attr3_leaf_compact(struct xfs_da_args *args,
      54             :                                    struct xfs_attr3_icleaf_hdr *ichdr,
      55             :                                    struct xfs_buf *leaf_buffer);
      56             : STATIC void xfs_attr3_leaf_rebalance(xfs_da_state_t *state,
      57             :                                                    xfs_da_state_blk_t *blk1,
      58             :                                                    xfs_da_state_blk_t *blk2);
      59             : STATIC int xfs_attr3_leaf_figure_balance(xfs_da_state_t *state,
      60             :                         xfs_da_state_blk_t *leaf_blk_1,
      61             :                         struct xfs_attr3_icleaf_hdr *ichdr1,
      62             :                         xfs_da_state_blk_t *leaf_blk_2,
      63             :                         struct xfs_attr3_icleaf_hdr *ichdr2,
      64             :                         int *number_entries_in_blk1,
      65             :                         int *number_usedbytes_in_blk1);
      66             : 
      67             : /*
      68             :  * Utility routines.
      69             :  */
      70             : STATIC void xfs_attr3_leaf_moveents(struct xfs_da_args *args,
      71             :                         struct xfs_attr_leafblock *src_leaf,
      72             :                         struct xfs_attr3_icleaf_hdr *src_ichdr, int src_start,
      73             :                         struct xfs_attr_leafblock *dst_leaf,
      74             :                         struct xfs_attr3_icleaf_hdr *dst_ichdr, int dst_start,
      75             :                         int move_count);
      76             : STATIC int xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index);
      77             : 
      78             : /*
      79             :  * attr3 block 'firstused' conversion helpers.
      80             :  *
      81             :  * firstused refers to the offset of the first used byte of the nameval region
      82             :  * of an attr leaf block. The region starts at the tail of the block and expands
      83             :  * backwards towards the middle. As such, firstused is initialized to the block
      84             :  * size for an empty leaf block and is reduced from there.
      85             :  *
      86             :  * The attr3 block size is pegged to the fsb size and the maximum fsb is 64k.
      87             :  * The in-core firstused field is 32-bit and thus supports the maximum fsb size.
      88             :  * The on-disk field is only 16-bit, however, and overflows at 64k. Since this
      89             :  * only occurs at exactly 64k, we use zero as a magic on-disk value to represent
      90             :  * the attr block size. The following helpers manage the conversion between the
      91             :  * in-core and on-disk formats.
      92             :  */
      93             : 
      94             : static void
      95  2436850989 : xfs_attr3_leaf_firstused_from_disk(
      96             :         struct xfs_da_geometry          *geo,
      97             :         struct xfs_attr3_icleaf_hdr     *to,
      98             :         struct xfs_attr_leafblock       *from)
      99             : {
     100  2436850989 :         struct xfs_attr3_leaf_hdr       *hdr3;
     101             : 
     102  2436850989 :         if (from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)) {
     103  2436850989 :                 hdr3 = (struct xfs_attr3_leaf_hdr *) from;
     104  2436850989 :                 to->firstused = be16_to_cpu(hdr3->firstused);
     105             :         } else {
     106           0 :                 to->firstused = be16_to_cpu(from->hdr.firstused);
     107             :         }
     108             : 
     109             :         /*
     110             :          * Convert from the magic fsb size value to actual blocksize. This
     111             :          * should only occur for empty blocks when the block size overflows
     112             :          * 16-bits.
     113             :          */
     114  2436850989 :         if (to->firstused == XFS_ATTR3_LEAF_NULLOFF) {
     115           2 :                 ASSERT(!to->count && !to->usedbytes);
     116           2 :                 ASSERT(geo->blksize > USHRT_MAX);
     117           2 :                 to->firstused = geo->blksize;
     118             :         }
     119  2436850989 : }
     120             : 
     121             : static void
     122   305595796 : xfs_attr3_leaf_firstused_to_disk(
     123             :         struct xfs_da_geometry          *geo,
     124             :         struct xfs_attr_leafblock       *to,
     125             :         struct xfs_attr3_icleaf_hdr     *from)
     126             : {
     127   305595796 :         struct xfs_attr3_leaf_hdr       *hdr3;
     128   305595796 :         uint32_t                        firstused;
     129             : 
     130             :         /* magic value should only be seen on disk */
     131   305595796 :         ASSERT(from->firstused != XFS_ATTR3_LEAF_NULLOFF);
     132             : 
     133             :         /*
     134             :          * Scale down the 32-bit in-core firstused value to the 16-bit on-disk
     135             :          * value. This only overflows at the max supported value of 64k. Use the
     136             :          * magic on-disk value to represent block size in this case.
     137             :          */
     138   305595796 :         firstused = from->firstused;
     139   305595796 :         if (firstused > USHRT_MAX) {
     140           1 :                 ASSERT(from->firstused == geo->blksize);
     141             :                 firstused = XFS_ATTR3_LEAF_NULLOFF;
     142             :         }
     143             : 
     144   305595796 :         if (from->magic == XFS_ATTR3_LEAF_MAGIC) {
     145   305595796 :                 hdr3 = (struct xfs_attr3_leaf_hdr *) to;
     146   305595796 :                 hdr3->firstused = cpu_to_be16(firstused);
     147             :         } else {
     148           0 :                 to->hdr.firstused = cpu_to_be16(firstused);
     149             :         }
     150   305595796 : }
     151             : 
     152             : void
     153  2436359234 : xfs_attr3_leaf_hdr_from_disk(
     154             :         struct xfs_da_geometry          *geo,
     155             :         struct xfs_attr3_icleaf_hdr     *to,
     156             :         struct xfs_attr_leafblock       *from)
     157             : {
     158  2436359234 :         int     i;
     159             : 
     160  2436359234 :         ASSERT(from->hdr.info.magic == cpu_to_be16(XFS_ATTR_LEAF_MAGIC) ||
     161             :                from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC));
     162             : 
     163  2436359234 :         if (from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)) {
     164  2436359234 :                 struct xfs_attr3_leaf_hdr *hdr3 = (struct xfs_attr3_leaf_hdr *)from;
     165             : 
     166  2436359234 :                 to->forw = be32_to_cpu(hdr3->info.hdr.forw);
     167  2436359234 :                 to->back = be32_to_cpu(hdr3->info.hdr.back);
     168  2436359234 :                 to->magic = be16_to_cpu(hdr3->info.hdr.magic);
     169  2436359234 :                 to->count = be16_to_cpu(hdr3->count);
     170  2436359234 :                 to->usedbytes = be16_to_cpu(hdr3->usedbytes);
     171  2436359234 :                 xfs_attr3_leaf_firstused_from_disk(geo, to, from);
     172  2437129004 :                 to->holes = hdr3->holes;
     173             : 
     174  9733585225 :                 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
     175  7296456221 :                         to->freemap[i].base = be16_to_cpu(hdr3->freemap[i].base);
     176 14592912442 :                         to->freemap[i].size = be16_to_cpu(hdr3->freemap[i].size);
     177             :                 }
     178             :                 return;
     179             :         }
     180           0 :         to->forw = be32_to_cpu(from->hdr.info.forw);
     181           0 :         to->back = be32_to_cpu(from->hdr.info.back);
     182           0 :         to->magic = be16_to_cpu(from->hdr.info.magic);
     183           0 :         to->count = be16_to_cpu(from->hdr.count);
     184           0 :         to->usedbytes = be16_to_cpu(from->hdr.usedbytes);
     185           0 :         xfs_attr3_leaf_firstused_from_disk(geo, to, from);
     186           0 :         to->holes = from->hdr.holes;
     187             : 
     188           0 :         for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
     189           0 :                 to->freemap[i].base = be16_to_cpu(from->hdr.freemap[i].base);
     190           0 :                 to->freemap[i].size = be16_to_cpu(from->hdr.freemap[i].size);
     191             :         }
     192             : }
     193             : 
     194             : void
     195   305501070 : xfs_attr3_leaf_hdr_to_disk(
     196             :         struct xfs_da_geometry          *geo,
     197             :         struct xfs_attr_leafblock       *to,
     198             :         struct xfs_attr3_icleaf_hdr     *from)
     199             : {
     200   305501070 :         int                             i;
     201             : 
     202   305501070 :         ASSERT(from->magic == XFS_ATTR_LEAF_MAGIC ||
     203             :                from->magic == XFS_ATTR3_LEAF_MAGIC);
     204             : 
     205   305501070 :         if (from->magic == XFS_ATTR3_LEAF_MAGIC) {
     206   305501070 :                 struct xfs_attr3_leaf_hdr *hdr3 = (struct xfs_attr3_leaf_hdr *)to;
     207             : 
     208   305501070 :                 hdr3->info.hdr.forw = cpu_to_be32(from->forw);
     209   305501070 :                 hdr3->info.hdr.back = cpu_to_be32(from->back);
     210   305501070 :                 hdr3->info.hdr.magic = cpu_to_be16(from->magic);
     211   305501070 :                 hdr3->count = cpu_to_be16(from->count);
     212   305501070 :                 hdr3->usedbytes = cpu_to_be16(from->usedbytes);
     213   305501070 :                 xfs_attr3_leaf_firstused_to_disk(geo, to, from);
     214   305595178 :                 hdr3->holes = from->holes;
     215   305595178 :                 hdr3->pad1 = 0;
     216             : 
     217  1222159115 :                 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
     218   916563937 :                         hdr3->freemap[i].base = cpu_to_be16(from->freemap[i].base);
     219  1833127874 :                         hdr3->freemap[i].size = cpu_to_be16(from->freemap[i].size);
     220             :                 }
     221             :                 return;
     222             :         }
     223           0 :         to->hdr.info.forw = cpu_to_be32(from->forw);
     224           0 :         to->hdr.info.back = cpu_to_be32(from->back);
     225           0 :         to->hdr.info.magic = cpu_to_be16(from->magic);
     226           0 :         to->hdr.count = cpu_to_be16(from->count);
     227           0 :         to->hdr.usedbytes = cpu_to_be16(from->usedbytes);
     228           0 :         xfs_attr3_leaf_firstused_to_disk(geo, to, from);
     229           0 :         to->hdr.holes = from->holes;
     230           0 :         to->hdr.pad1 = 0;
     231             : 
     232           0 :         for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
     233           0 :                 to->hdr.freemap[i].base = cpu_to_be16(from->freemap[i].base);
     234           0 :                 to->hdr.freemap[i].size = cpu_to_be16(from->freemap[i].size);
     235             :         }
     236             : }
     237             : 
     238             : static xfs_failaddr_t
     239   986349090 : xfs_attr3_leaf_verify_entry(
     240             :         struct xfs_mount                        *mp,
     241             :         char                                    *buf_end,
     242             :         struct xfs_attr_leafblock               *leaf,
     243             :         struct xfs_attr3_icleaf_hdr             *leafhdr,
     244             :         struct xfs_attr_leaf_entry              *ent,
     245             :         int                                     idx,
     246             :         __u32                                   *last_hashval)
     247             : {
     248   986349090 :         struct xfs_attr_leaf_name_local         *lentry;
     249   986349090 :         struct xfs_attr_leaf_name_remote        *rentry;
     250   986349090 :         char                                    *name_end;
     251   986349090 :         unsigned int                            nameidx;
     252   986349090 :         unsigned int                            namesize;
     253   986349090 :         __u32                                   hashval;
     254             : 
     255             :         /* hash order check */
     256   986349090 :         hashval = be32_to_cpu(ent->hashval);
     257   986349090 :         if (hashval < *last_hashval)
     258           0 :                 return __this_address;
     259   986349090 :         *last_hashval = hashval;
     260             : 
     261   986349090 :         nameidx = be16_to_cpu(ent->nameidx);
     262   986349090 :         if (nameidx < leafhdr->firstused || nameidx >= mp->m_attr_geo->blksize)
     263           0 :                 return __this_address;
     264             : 
     265             :         /*
     266             :          * Check the name information.  The namelen fields are u8 so we can't
     267             :          * possibly exceed the maximum name length of 255 bytes.
     268             :          */
     269   986356170 :         if (ent->flags & XFS_ATTR_LOCAL) {
     270   986355008 :                 lentry = xfs_attr3_leaf_name_local(leaf, idx);
     271   986355008 :                 namesize = xfs_attr_leaf_entsize_local(lentry->namelen,
     272   986355008 :                                 be16_to_cpu(lentry->valuelen));
     273   986355008 :                 name_end = (char *)lentry + namesize;
     274   986355008 :                 if (lentry->namelen == 0)
     275           0 :                         return __this_address;
     276             :         } else {
     277        1162 :                 rentry = xfs_attr3_leaf_name_remote(leaf, idx);
     278        1162 :                 namesize = xfs_attr_leaf_entsize_remote(rentry->namelen);
     279        1162 :                 name_end = (char *)rentry + namesize;
     280        1162 :                 if (rentry->namelen == 0)
     281           0 :                         return __this_address;
     282        1162 :                 if (!(ent->flags & XFS_ATTR_INCOMPLETE) &&
     283        1160 :                     rentry->valueblk == 0)
     284           0 :                         return __this_address;
     285             :         }
     286             : 
     287   986356170 :         if (name_end > buf_end)
     288           0 :                 return __this_address;
     289             : 
     290             :         return NULL;
     291             : }
     292             : 
     293             : /*
     294             :  * Validate an attribute leaf block.
     295             :  *
     296             :  * Empty leaf blocks can occur under the following circumstances:
     297             :  *
     298             :  * 1. setxattr adds a new extended attribute to a file;
     299             :  * 2. The file has zero existing attributes;
     300             :  * 3. The attribute is too large to fit in the attribute fork;
     301             :  * 4. The attribute is small enough to fit in a leaf block;
     302             :  * 5. A log flush occurs after committing the transaction that creates
     303             :  *    the (empty) leaf block; and
     304             :  * 6. The filesystem goes down after the log flush but before the new
     305             :  *    attribute can be committed to the leaf block.
     306             :  *
     307             :  * Hence we need to ensure that we don't fail the validation purely
     308             :  * because the leaf is empty.
     309             :  */
     310             : static xfs_failaddr_t
     311    51878945 : xfs_attr3_leaf_verify(
     312             :         struct xfs_buf                  *bp)
     313             : {
     314    51878945 :         struct xfs_attr3_icleaf_hdr     ichdr;
     315    51878945 :         struct xfs_mount                *mp = bp->b_mount;
     316    51878945 :         struct xfs_attr_leafblock       *leaf = bp->b_addr;
     317    51878945 :         struct xfs_attr_leaf_entry      *entries;
     318    51878945 :         struct xfs_attr_leaf_entry      *ent;
     319    51878945 :         char                            *buf_end;
     320    51878945 :         uint32_t                        end;    /* must be 32bit - see below */
     321    51878945 :         __u32                           last_hashval = 0;
     322    51878945 :         int                             i;
     323    51878945 :         xfs_failaddr_t                  fa;
     324             : 
     325    51878945 :         xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
     326             : 
     327    51879081 :         fa = xfs_da3_blkinfo_verify(bp, bp->b_addr);
     328    51879328 :         if (fa)
     329             :                 return fa;
     330             : 
     331             :         /*
     332             :          * firstused is the block offset of the first name info structure.
     333             :          * Make sure it doesn't go off the block or crash into the header.
     334             :          */
     335    51879321 :         if (ichdr.firstused > mp->m_attr_geo->blksize)
     336           0 :                 return __this_address;
     337   103758625 :         if (ichdr.firstused < xfs_attr3_leaf_hdr_size(leaf))
     338           0 :                 return __this_address;
     339             : 
     340             :         /* Make sure the entries array doesn't crash into the name info. */
     341    51879321 :         entries = xfs_attr3_leaf_entryp(bp->b_addr);
     342    51879321 :         if ((char *)&entries[ichdr.count] >
     343    51879321 :             (char *)bp->b_addr + ichdr.firstused)
     344           0 :                 return __this_address;
     345             : 
     346             :         /*
     347             :          * NOTE: This verifier historically failed empty leaf buffers because
     348             :          * we expect the fork to be in another format. Empty attr fork format
     349             :          * conversions are possible during xattr set, however, and format
     350             :          * conversion is not atomic with the xattr set that triggers it. We
     351             :          * cannot assume leaf blocks are non-empty until that is addressed.
     352             :         */
     353    51879321 :         buf_end = (char *)bp->b_addr + mp->m_attr_geo->blksize;
     354  1038270353 :         for (i = 0, ent = entries; i < ichdr.count; ent++, i++) {
     355   986391149 :                 fa = xfs_attr3_leaf_verify_entry(mp, buf_end, leaf, &ichdr,
     356             :                                 ent, i, &last_hashval);
     357   986391032 :                 if (fa)
     358           0 :                         return fa;
     359             :         }
     360             : 
     361             :         /*
     362             :          * Quickly check the freemap information.  Attribute data has to be
     363             :          * aligned to 4-byte boundaries, and likewise for the free space.
     364             :          *
     365             :          * Note that for 64k block size filesystems, the freemap entries cannot
     366             :          * overflow as they are only be16 fields. However, when checking end
     367             :          * pointer of the freemap, we have to be careful to detect overflows and
     368             :          * so use uint32_t for those checks.
     369             :          */
     370   207516630 :         for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
     371   155637426 :                 if (ichdr.freemap[i].base > mp->m_attr_geo->blksize)
     372           0 :                         return __this_address;
     373   155637426 :                 if (ichdr.freemap[i].base & 0x3)
     374           0 :                         return __this_address;
     375   155637426 :                 if (ichdr.freemap[i].size > mp->m_attr_geo->blksize)
     376           0 :                         return __this_address;
     377   155637426 :                 if (ichdr.freemap[i].size & 0x3)
     378           0 :                         return __this_address;
     379             : 
     380             :                 /* be care of 16 bit overflows here */
     381   155637426 :                 end = (uint32_t)ichdr.freemap[i].base + ichdr.freemap[i].size;
     382   155637426 :                 if (end < ichdr.freemap[i].base)
     383           0 :                         return __this_address;
     384   155637426 :                 if (end > mp->m_attr_geo->blksize)
     385           0 :                         return __this_address;
     386             :         }
     387             : 
     388             :         return NULL;
     389             : }
     390             : 
     391             : xfs_failaddr_t
     392  1287575178 : xfs_attr3_leaf_header_check(
     393             :         struct xfs_buf          *bp,
     394             :         xfs_ino_t               owner)
     395             : {
     396  1287575178 :         struct xfs_mount        *mp = bp->b_mount;
     397             : 
     398  1287575178 :         if (xfs_has_crc(mp)) {
     399  1287575178 :                 struct xfs_attr3_leafblock *hdr3 = bp->b_addr;
     400             : 
     401  1287575178 :                 ASSERT(hdr3->hdr.info.hdr.magic ==
     402             :                                 cpu_to_be16(XFS_ATTR3_LEAF_MAGIC));
     403             : 
     404  1287575178 :                 if (be64_to_cpu(hdr3->hdr.info.owner) != owner)
     405           0 :                         return __this_address;
     406             :         }
     407             : 
     408             :         return NULL;
     409             : }
     410             : 
     411             : static void
     412    49185759 : xfs_attr3_leaf_write_verify(
     413             :         struct xfs_buf  *bp)
     414             : {
     415    49185759 :         struct xfs_mount        *mp = bp->b_mount;
     416    49185759 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     417    49185759 :         struct xfs_attr3_leaf_hdr *hdr3 = bp->b_addr;
     418    49185759 :         xfs_failaddr_t          fa;
     419             : 
     420    49185759 :         fa = xfs_attr3_leaf_verify(bp);
     421    49185759 :         if (fa) {
     422           0 :                 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
     423           0 :                 return;
     424             :         }
     425             : 
     426    49185759 :         if (!xfs_has_crc(mp))
     427             :                 return;
     428             : 
     429    49185759 :         if (bip)
     430    49185759 :                 hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
     431             : 
     432    49185759 :         xfs_buf_update_cksum(bp, XFS_ATTR3_LEAF_CRC_OFF);
     433             : }
     434             : 
     435             : /*
     436             :  * leaf/node format detection on trees is sketchy, so a node read can be done on
     437             :  * leaf level blocks when detection identifies the tree as a node format tree
     438             :  * incorrectly. In this case, we need to swap the verifier to match the correct
     439             :  * format of the block being read.
     440             :  */
     441             : static void
     442      289330 : xfs_attr3_leaf_read_verify(
     443             :         struct xfs_buf          *bp)
     444             : {
     445      289330 :         struct xfs_mount        *mp = bp->b_mount;
     446      289330 :         xfs_failaddr_t          fa;
     447             : 
     448      578660 :         if (xfs_has_crc(mp) &&
     449             :              !xfs_buf_verify_cksum(bp, XFS_ATTR3_LEAF_CRC_OFF))
     450         204 :                 xfs_verifier_error(bp, -EFSBADCRC, __this_address);
     451             :         else {
     452      289126 :                 fa = xfs_attr3_leaf_verify(bp);
     453      289126 :                 if (fa)
     454           0 :                         xfs_verifier_error(bp, -EFSCORRUPTED, fa);
     455             :         }
     456      289330 : }
     457             : 
     458             : const struct xfs_buf_ops xfs_attr3_leaf_buf_ops = {
     459             :         .name = "xfs_attr3_leaf",
     460             :         .magic16 = { cpu_to_be16(XFS_ATTR_LEAF_MAGIC),
     461             :                      cpu_to_be16(XFS_ATTR3_LEAF_MAGIC) },
     462             :         .verify_read = xfs_attr3_leaf_read_verify,
     463             :         .verify_write = xfs_attr3_leaf_write_verify,
     464             :         .verify_struct = xfs_attr3_leaf_verify,
     465             : };
     466             : 
     467             : int
     468   968187432 : xfs_attr3_leaf_read(
     469             :         struct xfs_trans        *tp,
     470             :         struct xfs_inode        *dp,
     471             :         xfs_ino_t               owner,
     472             :         xfs_dablk_t             bno,
     473             :         struct xfs_buf          **bpp)
     474             : {
     475   968187432 :         xfs_failaddr_t          fa;
     476   968187432 :         int                     err;
     477             : 
     478   968187432 :         err = xfs_da_read_buf(tp, dp, bno, 0, bpp, XFS_ATTR_FORK,
     479             :                         &xfs_attr3_leaf_buf_ops);
     480   969006166 :         if (err || !(*bpp))
     481             :                 return err;
     482             : 
     483   969006094 :         fa = xfs_attr3_leaf_header_check(*bpp, owner);
     484   968770795 :         if (fa) {
     485           0 :                 __xfs_buf_mark_corrupt(*bpp, fa);
     486           0 :                 xfs_trans_brelse(tp, *bpp);
     487           0 :                 *bpp = NULL;
     488           0 :                 xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK);
     489           0 :                 return -EFSCORRUPTED;
     490             :         }
     491             : 
     492   968770795 :         if (tp)
     493   542558437 :                 xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_ATTR_LEAF_BUF);
     494             :         return 0;
     495             : }
     496             : 
     497             : /*========================================================================
     498             :  * Namespace helper routines
     499             :  *========================================================================*/
     500             : 
     501             : /*
     502             :  * If we are in log recovery, then we want the lookup to ignore the INCOMPLETE
     503             :  * flag on disk - if there's an incomplete attr then recovery needs to tear it
     504             :  * down. If there's no incomplete attr, then recovery needs to tear that attr
     505             :  * down to replace it with the attr that has been logged. In this case, the
     506             :  * INCOMPLETE flag will not be set in attr->attr_filter, but rather
     507             :  * XFS_DA_OP_RECOVERY will be set in args->op_flags.
     508             :  */
     509             : static bool
     510  5827456562 : xfs_attr_match(
     511             :         const struct xfs_da_args        *args,
     512             :         uint8_t                         namelen,
     513             :         const unsigned char             *name,
     514             :         unsigned int                    valuelen,
     515             :         const void                      *value,
     516             :         int                             flags)
     517             : {
     518             : 
     519  5827456562 :         if (args->namelen != namelen)
     520             :                 return false;
     521 10881954974 :         if (memcmp(args->name, name, namelen) != 0)
     522             :                 return false;
     523             : 
     524   464223107 :         if (args->op_flags & XFS_DA_OP_NVLOOKUP) {
     525   180650857 :                 if (args->valuelen != valuelen)
     526             :                         return false;
     527   180645393 :                 if (args->valuelen && !value) {
     528             :                         /* not implemented for remote values */
     529           0 :                         ASSERT(0);
     530           0 :                         return false;
     531             :                 }
     532   180645393 :                 if (valuelen && !args->value) {
     533             :                         /* caller gave us valuelen > 0 but no value?? */
     534           0 :                         ASSERT(0);
     535           0 :                         return false;
     536             :                 }
     537   361290786 :                 if (valuelen > 0 && memcmp(args->value, value, valuelen) != 0)
     538             :                         return false;
     539             :         }
     540             : 
     541             :         /* Recovery ignores the INCOMPLETE flag. */
     542   458971649 :         if ((args->op_flags & XFS_DA_OP_RECOVERY) &&
     543          65 :             args->attr_filter == (flags & XFS_ATTR_NSP_ONDISK_MASK))
     544             :                 return true;
     545             : 
     546             :         /* All remaining matches need to be filtered by INCOMPLETE state. */
     547   458971598 :         if (args->attr_filter !=
     548   458971598 :             (flags & (XFS_ATTR_NSP_ONDISK_MASK | XFS_ATTR_INCOMPLETE)))
     549      783556 :                 return false;
     550             :         return true;
     551             : }
     552             : 
     553             : static int
     554   121724346 : xfs_attr_copy_value(
     555             :         struct xfs_da_args      *args,
     556             :         unsigned char           *value,
     557             :         int                     valuelen)
     558             : {
     559             :         /* vlookups already supplied the attr value; don't copy anything */
     560   121724346 :         if (args->op_flags & XFS_DA_OP_NVLOOKUP)
     561             :                 return 0;
     562             : 
     563             :         /*
     564             :          * No copy if all we have to do is get the length
     565             :          */
     566    25225934 :         if (!args->valuelen) {
     567    12675431 :                 args->valuelen = valuelen;
     568    12675431 :                 return 0;
     569             :         }
     570             : 
     571             :         /*
     572             :          * No copy if the length of the existing buffer is too small
     573             :          */
     574    12550503 :         if (args->valuelen < valuelen) {
     575           0 :                 args->valuelen = valuelen;
     576           0 :                 return -ERANGE;
     577             :         }
     578             : 
     579    12550503 :         if (!args->value) {
     580         146 :                 args->value = kvmalloc(valuelen, GFP_KERNEL | __GFP_NOLOCKDEP);
     581         146 :                 if (!args->value)
     582             :                         return -ENOMEM;
     583             :         }
     584    12550503 :         args->valuelen = valuelen;
     585             : 
     586             :         /* remote block xattr requires IO for copy-in */
     587    12550503 :         if (args->rmtblkno)
     588         639 :                 return xfs_attr_rmtval_get(args);
     589             : 
     590             :         /*
     591             :          * This is to prevent a GCC warning because the remote xattr case
     592             :          * doesn't have a value to pass in. In that case, we never reach here,
     593             :          * but GCC can't work that out and so throws a "passing NULL to
     594             :          * memcpy" warning.
     595             :          */
     596    12549864 :         if (!value)
     597             :                 return -EINVAL;
     598    25099728 :         memcpy(args->value, value, valuelen);
     599    12549864 :         return 0;
     600             : }
     601             : 
     602             : /*========================================================================
     603             :  * External routines when attribute fork size < XFS_LITINO(mp).
     604             :  *========================================================================*/
     605             : 
     606             : /*
     607             :  * Query whether the total requested number of attr fork bytes of extended
     608             :  * attribute space will be able to fit inline.
     609             :  *
     610             :  * Returns zero if not, else the i_forkoff fork offset to be used in the
     611             :  * literal area for attribute data once the new bytes have been added.
     612             :  *
     613             :  * i_forkoff must be 8 byte aligned, hence is stored as a >>3 value;
     614             :  * special case for dev/uuid inodes, they have fixed size data forks.
     615             :  */
     616             : int
     617   362889608 : xfs_attr_shortform_bytesfit(
     618             :         struct xfs_inode        *dp,
     619             :         int                     bytes)
     620             : {
     621   362889608 :         struct xfs_mount        *mp = dp->i_mount;
     622   362889608 :         int64_t                 dsize;
     623   362889608 :         int                     minforkoff;
     624   362889608 :         int                     maxforkoff;
     625   362889608 :         int                     offset;
     626             : 
     627             :         /*
     628             :          * Check if the new size could fit at all first:
     629             :          */
     630   362889618 :         if (bytes > XFS_LITINO(mp))
     631             :                 return 0;
     632             : 
     633             :         /* rounded down */
     634   276159558 :         offset = (XFS_LITINO(mp) - bytes) >> 3;
     635             : 
     636   276159558 :         if (dp->i_df.if_format == XFS_DINODE_FMT_DEV) {
     637    30791844 :                 minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
     638    30791844 :                 return (offset >= minforkoff) ? minforkoff : 0;
     639             :         }
     640             : 
     641             :         /*
     642             :          * If the requested numbers of bytes is smaller or equal to the
     643             :          * current attribute fork size we can always proceed.
     644             :          *
     645             :          * Note that if_bytes in the data fork might actually be larger than
     646             :          * the current data fork size is due to delalloc extents. In that
     647             :          * case either the extent count will go down when they are converted
     648             :          * to real extents, or the delalloc conversion will take care of the
     649             :          * literal area rebalancing.
     650             :          */
     651   245367714 :         if (bytes <= xfs_inode_attr_fork_size(dp))
     652   212171952 :                 return dp->i_forkoff;
     653             : 
     654             :         /*
     655             :          * For attr2 we can try to move the forkoff if there is space in the
     656             :          * literal area, but for the old format we are done if there is no
     657             :          * space in the fixed attribute fork.
     658             :          */
     659    33195762 :         if (!xfs_has_attr2(mp))
     660             :                 return 0;
     661             : 
     662    33195762 :         dsize = dp->i_df.if_bytes;
     663             : 
     664    33195762 :         switch (dp->i_df.if_format) {
     665    32870377 :         case XFS_DINODE_FMT_EXTENTS:
     666             :                 /*
     667             :                  * If there is no attr fork and the data fork is extents,
     668             :                  * determine if creating the default attr fork will result
     669             :                  * in the extents form migrating to btree. If so, the
     670             :                  * minimum offset only needs to be the space required for
     671             :                  * the btree root.
     672             :                  */
     673    32870377 :                 if (!dp->i_forkoff && dp->i_df.if_bytes >
     674      318507 :                     xfs_default_attroffset(dp))
     675          82 :                         dsize = xfs_bmdr_space_calc(MINDBTPTRS);
     676             :                 break;
     677      173814 :         case XFS_DINODE_FMT_BTREE:
     678             :                 /*
     679             :                  * If we have a data btree then keep forkoff if we have one,
     680             :                  * otherwise we are adding a new attr, so then we set
     681             :                  * minforkoff to where the btree root can finish so we have
     682             :                  * plenty of room for attrs
     683             :                  */
     684      173814 :                 if (dp->i_forkoff) {
     685      173796 :                         if (offset < dp->i_forkoff)
     686             :                                 return 0;
     687           0 :                         return dp->i_forkoff;
     688             :                 }
     689          18 :                 dsize = xfs_bmap_bmdr_space(dp->i_df.if_broot);
     690          18 :                 break;
     691             :         }
     692             : 
     693             :         /*
     694             :          * A data fork btree root must have space for at least
     695             :          * MINDBTPTRS key/ptr pairs if the data fork is small or empty.
     696             :          */
     697    33021954 :         minforkoff = max_t(int64_t, dsize, xfs_bmdr_space_calc(MINDBTPTRS));
     698    33021954 :         minforkoff = roundup(minforkoff, 8) >> 3;
     699             : 
     700             :         /* attr fork btree root can have at least this many key/ptr pairs */
     701    33021954 :         maxforkoff = XFS_LITINO(mp) - xfs_bmdr_space_calc(MINABTPTRS);
     702    33021954 :         maxforkoff = maxforkoff >> 3;     /* rounded down */
     703             : 
     704    33021954 :         if (offset >= maxforkoff)
     705             :                 return maxforkoff;
     706    32744189 :         if (offset >= minforkoff)
     707    20501440 :                 return offset;
     708             :         return 0;
     709             : }
     710             : 
     711             : /*
     712             :  * Switch on the ATTR2 superblock bit (implies also FEATURES2) unless:
     713             :  * - noattr2 mount option is set,
     714             :  * - on-disk version bit says it is already set, or
     715             :  * - the attr2 mount option is not set to enable automatic upgrade from attr1.
     716             :  */
     717             : STATIC void
     718   282682667 : xfs_sbversion_add_attr2(
     719             :         struct xfs_mount        *mp,
     720             :         struct xfs_trans        *tp)
     721             : {
     722   282682667 :         if (xfs_has_noattr2(mp))
     723             :                 return;
     724   282682667 :         if (mp->m_sb.sb_features2 & XFS_SB_VERSION2_ATTR2BIT)
     725             :                 return;
     726           0 :         if (!xfs_has_attr2(mp))
     727             :                 return;
     728             : 
     729           0 :         spin_lock(&mp->m_sb_lock);
     730           0 :         xfs_add_attr2(mp);
     731           0 :         spin_unlock(&mp->m_sb_lock);
     732           0 :         xfs_log_sb(tp);
     733             : }
     734             : 
     735             : /*
     736             :  * Create the initial contents of a shortform attribute list.
     737             :  */
     738             : void
     739    67464282 : xfs_attr_shortform_create(
     740             :         struct xfs_da_args      *args)
     741             : {
     742    67464282 :         struct xfs_inode        *dp = args->dp;
     743    67464282 :         struct xfs_ifork        *ifp = &dp->i_af;
     744    67464282 :         struct xfs_attr_sf_hdr  *hdr;
     745             : 
     746    67464282 :         trace_xfs_attr_sf_create(args);
     747             : 
     748    67465870 :         ASSERT(ifp->if_bytes == 0);
     749    67465870 :         if (ifp->if_format == XFS_DINODE_FMT_EXTENTS)
     750    67465737 :                 ifp->if_format = XFS_DINODE_FMT_LOCAL;
     751    67465870 :         xfs_idata_realloc(dp, sizeof(*hdr), XFS_ATTR_FORK);
     752    67465764 :         hdr = (struct xfs_attr_sf_hdr *)ifp->if_u1.if_data;
     753    67465764 :         memset(hdr, 0, sizeof(*hdr));
     754    67465764 :         hdr->totsize = cpu_to_be16(sizeof(*hdr));
     755    67465764 :         xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
     756    67465988 : }
     757             : 
     758             : /*
     759             :  * Return -EEXIST if attr is found, or -ENOATTR if not
     760             :  * args:  args containing attribute name and namelen
     761             :  * sfep:  If not null, pointer will be set to the last attr entry found on
     762             :           -EEXIST.  On -ENOATTR pointer is left at the last entry in the list
     763             :  * basep: If not null, pointer is set to the byte offset of the entry in the
     764             :  *        list on -EEXIST.  On -ENOATTR, pointer is left at the byte offset of
     765             :  *        the last entry in the list
     766             :  */
     767             : int
     768   371804874 : xfs_attr_sf_findname(
     769             :         struct xfs_da_args       *args,
     770             :         struct xfs_attr_sf_entry **sfep,
     771             :         unsigned int             *basep)
     772             : {
     773   371804874 :         struct xfs_attr_shortform *sf;
     774   371804874 :         struct xfs_attr_sf_entry *sfe;
     775   371804874 :         unsigned int            base = sizeof(struct xfs_attr_sf_hdr);
     776   371804874 :         int                     size = 0;
     777   371804874 :         int                     end;
     778   371804874 :         int                     i;
     779             : 
     780   371804874 :         sf = (struct xfs_attr_shortform *)args->dp->i_af.if_u1.if_data;
     781   371804874 :         sfe = &sf->list[0];
     782   371804874 :         end = sf->hdr.count;
     783   899025765 :         for (i = 0; i < end; sfe = xfs_attr_sf_nextentry(sfe),
     784   527220891 :                              base += size, i++) {
     785   656566473 :                 size = xfs_attr_sf_entsize(sfe);
     786   656629957 :                 if (!xfs_attr_match(args, sfe->namelen, sfe->nameval,
     787   656566473 :                                     sfe->valuelen, &sfe->nameval[sfe->namelen],
     788   656566473 :                                     sfe->flags))
     789   527220891 :                         continue;
     790             :                 break;
     791             :         }
     792             : 
     793   371868358 :         if (sfep != NULL)
     794   282682084 :                 *sfep = sfe;
     795             : 
     796   371868358 :         if (basep != NULL)
     797   102520546 :                 *basep = base;
     798             : 
     799   371868358 :         if (i == end)
     800   242461011 :                 return -ENOATTR;
     801             :         return -EEXIST;
     802             : }
     803             : 
     804             : /*
     805             :  * Add a name/value pair to the shortform attribute list.
     806             :  * Overflow from the inode has already been checked for.
     807             :  */
     808             : void
     809   180178442 : xfs_attr_shortform_add(
     810             :         struct xfs_da_args              *args,
     811             :         int                             forkoff)
     812             : {
     813   180178442 :         struct xfs_attr_shortform       *sf;
     814   180178442 :         struct xfs_attr_sf_entry        *sfe;
     815   180178442 :         int                             offset, size;
     816   180178442 :         struct xfs_mount                *mp;
     817   180178442 :         struct xfs_inode                *dp;
     818   180178442 :         struct xfs_ifork                *ifp;
     819             : 
     820   180178442 :         trace_xfs_attr_sf_add(args);
     821             : 
     822   180185156 :         dp = args->dp;
     823   180185156 :         mp = dp->i_mount;
     824   180185156 :         dp->i_forkoff = forkoff;
     825             : 
     826   180185156 :         ifp = &dp->i_af;
     827   180185156 :         ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
     828   180185156 :         sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
     829   180185156 :         if (xfs_attr_sf_findname(args, &sfe, NULL) == -EEXIST)
     830           0 :                 ASSERT(0);
     831             : 
     832   180187044 :         offset = (char *)sfe - (char *)sf;
     833   180187044 :         size = xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
     834   180187044 :         xfs_idata_realloc(dp, size, XFS_ATTR_FORK);
     835   180183233 :         sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
     836   180183233 :         sfe = (struct xfs_attr_sf_entry *)((char *)sf + offset);
     837             : 
     838   180183233 :         sfe->namelen = args->namelen;
     839   180183233 :         sfe->valuelen = args->valuelen;
     840   180183233 :         sfe->flags = args->attr_filter;
     841   360366466 :         memcpy(sfe->nameval, args->name, args->namelen);
     842   360366466 :         memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
     843   180183233 :         sf->hdr.count++;
     844   180183233 :         be16_add_cpu(&sf->hdr.totsize, size);
     845   180182242 :         xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
     846             : 
     847   180190821 :         xfs_sbversion_add_attr2(mp, args->trans);
     848   180191754 : }
     849             : 
     850             : /*
     851             :  * After the last attribute is removed revert to original inode format,
     852             :  * making all literal area available to the data fork once more.
     853             :  */
     854             : void
     855    37687732 : xfs_attr_fork_remove(
     856             :         struct xfs_inode        *ip,
     857             :         struct xfs_trans        *tp)
     858             : {
     859    37687732 :         ASSERT(ip->i_af.if_nextents == 0);
     860             : 
     861    37687732 :         xfs_ifork_zap_attr(ip);
     862    37691243 :         ip->i_forkoff = 0;
     863    37691243 :         xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
     864    37694065 : }
     865             : 
     866             : /*
     867             :  * Remove an attribute from the shortform attribute list structure.
     868             :  */
     869             : int
     870   102496730 : xfs_attr_sf_removename(
     871             :         struct xfs_da_args              *args)
     872             : {
     873   102496730 :         struct xfs_attr_shortform       *sf;
     874   102496730 :         struct xfs_attr_sf_entry        *sfe;
     875   102496730 :         int                             size = 0, end, totsize;
     876   102496730 :         unsigned int                    base;
     877   102496730 :         struct xfs_mount                *mp;
     878   102496730 :         struct xfs_inode                *dp;
     879   102496730 :         int                             error;
     880             : 
     881   102496730 :         trace_xfs_attr_sf_remove(args);
     882             : 
     883   102500437 :         dp = args->dp;
     884   102500437 :         mp = dp->i_mount;
     885   102500437 :         sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data;
     886             : 
     887   102500437 :         error = xfs_attr_sf_findname(args, &sfe, &base);
     888             : 
     889             :         /*
     890             :          * If we are recovering an operation, finding nothing to
     891             :          * remove is not an error - it just means there was nothing
     892             :          * to clean up.
     893             :          */
     894   102498484 :         if (error == -ENOATTR && (args->op_flags & XFS_DA_OP_RECOVERY))
     895             :                 return 0;
     896   102498471 :         if (error != -EEXIST)
     897             :                 return error;
     898   102498471 :         size = xfs_attr_sf_entsize(sfe);
     899             : 
     900             :         /*
     901             :          * Fix up the attribute fork data, covering the hole
     902             :          */
     903   102498471 :         end = base + size;
     904   102498471 :         totsize = be16_to_cpu(sf->hdr.totsize);
     905   102498471 :         if (end != totsize)
     906    45532382 :                 memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end);
     907   102498471 :         sf->hdr.count--;
     908   102498471 :         be16_add_cpu(&sf->hdr.totsize, -size);
     909             : 
     910             :         /*
     911             :          * Fix up the start offset of the attribute fork
     912             :          */
     913   102499587 :         totsize -= size;
     914   102499587 :         if (totsize == sizeof(xfs_attr_sf_hdr_t) && xfs_has_attr2(mp) &&
     915    61067423 :             (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) &&
     916    60721550 :             !(args->op_flags & (XFS_DA_OP_ADDNAME | XFS_DA_OP_REPLACE)) &&
     917             :             !xfs_has_parent(mp)) {
     918         195 :                 xfs_attr_fork_remove(dp, args->trans);
     919             :         } else {
     920   102499392 :                 xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
     921   102499172 :                 dp->i_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
     922   102499942 :                 ASSERT(dp->i_forkoff);
     923   102499942 :                 ASSERT(totsize > sizeof(xfs_attr_sf_hdr_t) ||
     924             :                                 (args->op_flags & XFS_DA_OP_ADDNAME) ||
     925             :                                 !xfs_has_attr2(mp) ||
     926             :                                 dp->i_df.if_format == XFS_DINODE_FMT_BTREE ||
     927             :                                 xfs_has_parent(mp));
     928   102499942 :                 xfs_trans_log_inode(args->trans, dp,
     929             :                                         XFS_ILOG_CORE | XFS_ILOG_ADATA);
     930             :         }
     931             : 
     932   102499138 :         xfs_sbversion_add_attr2(mp, args->trans);
     933             : 
     934   102499138 :         return 0;
     935             : }
     936             : 
     937             : /*
     938             :  * Look up a name in a shortform attribute list structure.
     939             :  */
     940             : /*ARGSUSED*/
     941             : int
     942   164733147 : xfs_attr_shortform_lookup(xfs_da_args_t *args)
     943             : {
     944   164733147 :         struct xfs_attr_shortform *sf;
     945   164733147 :         struct xfs_attr_sf_entry *sfe;
     946   164733147 :         int i;
     947   164733147 :         struct xfs_ifork *ifp;
     948             : 
     949   164733147 :         trace_xfs_attr_sf_lookup(args);
     950             : 
     951   164737276 :         ifp = &args->dp->i_af;
     952   164737276 :         ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
     953   164737276 :         sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
     954   164737276 :         sfe = &sf->list[0];
     955   360099567 :         for (i = 0; i < sf->hdr.count;
     956   195362291 :                                 sfe = xfs_attr_sf_nextentry(sfe), i++) {
     957   208862551 :                 if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
     958   208862378 :                                 sfe->valuelen, &sfe->nameval[sfe->namelen],
     959   208862378 :                                 sfe->flags))
     960             :                         return -EEXIST;
     961             :         }
     962             :         return -ENOATTR;
     963             : }
     964             : 
     965             : /*
     966             :  * Retrieve the attribute value and length.
     967             :  *
     968             :  * If args->valuelen is zero, only the length needs to be returned.  Unlike a
     969             :  * lookup, we only return an error if the attribute does not exist or we can't
     970             :  * retrieve the value.
     971             :  */
     972             : int
     973   137802100 : xfs_attr_shortform_getvalue(
     974             :         struct xfs_da_args      *args)
     975             : {
     976   137802100 :         struct xfs_attr_shortform *sf;
     977   137802100 :         struct xfs_attr_sf_entry *sfe;
     978   137802100 :         int                     i;
     979             : 
     980   137802100 :         ASSERT(args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL);
     981   137802100 :         sf = (struct xfs_attr_shortform *)args->dp->i_af.if_u1.if_data;
     982   137802100 :         sfe = &sf->list[0];
     983   215345072 :         for (i = 0; i < sf->hdr.count;
     984    77542972 :                                 sfe = xfs_attr_sf_nextentry(sfe), i++) {
     985   178351724 :                 if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
     986   178361449 :                                 sfe->valuelen, &sfe->nameval[sfe->namelen],
     987   178361449 :                                 sfe->flags))
     988   100808752 :                         return xfs_attr_copy_value(args,
     989   100808752 :                                 &sfe->nameval[args->namelen], sfe->valuelen);
     990             :         }
     991             :         return -ENOATTR;
     992             : }
     993             : 
     994             : /* Convert from using the shortform to the leaf format. */
     995             : int
     996     8587864 : xfs_attr_shortform_to_leaf(
     997             :         struct xfs_da_args              *args)
     998             : {
     999     8587864 :         struct xfs_inode                *dp;
    1000     8587864 :         struct xfs_attr_shortform       *sf;
    1001     8587864 :         struct xfs_attr_sf_entry        *sfe;
    1002     8587864 :         struct xfs_da_args              nargs;
    1003     8587864 :         char                            *tmpbuffer;
    1004     8587864 :         int                             error, i, size;
    1005     8587864 :         xfs_dablk_t                     blkno;
    1006     8587864 :         struct xfs_buf                  *bp;
    1007     8587864 :         struct xfs_ifork                *ifp;
    1008             : 
    1009     8587864 :         trace_xfs_attr_sf_to_leaf(args);
    1010             : 
    1011     8588028 :         dp = args->dp;
    1012     8588028 :         ifp = &dp->i_af;
    1013     8588028 :         sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
    1014     8588028 :         size = be16_to_cpu(sf->hdr.totsize);
    1015     8588028 :         tmpbuffer = kmem_alloc(size, 0);
    1016     8587936 :         ASSERT(tmpbuffer != NULL);
    1017    17175872 :         memcpy(tmpbuffer, ifp->if_u1.if_data, size);
    1018     8587936 :         sf = (struct xfs_attr_shortform *)tmpbuffer;
    1019             : 
    1020     8587936 :         xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
    1021     8587914 :         xfs_bmap_local_to_extents_empty(args->trans, dp, XFS_ATTR_FORK);
    1022             : 
    1023     8588065 :         bp = NULL;
    1024     8588065 :         error = xfs_da_grow_inode(args, &blkno);
    1025     8587009 :         if (error)
    1026           1 :                 goto out;
    1027             : 
    1028     8587008 :         ASSERT(blkno == 0);
    1029     8587008 :         error = xfs_attr3_leaf_create(args, blkno, &bp);
    1030     8587868 :         if (error)
    1031           2 :                 goto out;
    1032             : 
    1033     8587866 :         memset((char *)&nargs, 0, sizeof(nargs));
    1034     8587866 :         nargs.dp = dp;
    1035     8587866 :         nargs.geo = args->geo;
    1036     8587866 :         nargs.total = args->total;
    1037     8587866 :         nargs.whichfork = XFS_ATTR_FORK;
    1038     8587866 :         nargs.trans = args->trans;
    1039     8587866 :         nargs.op_flags = XFS_DA_OP_OKNOENT | XFS_DA_OP_NVLOOKUP;
    1040     8587866 :         nargs.owner = args->owner;
    1041             : 
    1042     8587866 :         sfe = &sf->list[0];
    1043    52514328 :         for (i = 0; i < sf->hdr.count; i++) {
    1044    43926371 :                 nargs.name = sfe->nameval;
    1045    43926371 :                 nargs.namelen = sfe->namelen;
    1046    43926371 :                 nargs.value = &sfe->nameval[nargs.namelen];
    1047    43926371 :                 nargs.valuelen = sfe->valuelen;
    1048    87851545 :                 nargs.hashval = xfs_da_hashname(sfe->nameval,
    1049    43926371 :                                                 sfe->namelen);
    1050    43925174 :                 nargs.attr_filter = sfe->flags & XFS_ATTR_NSP_ONDISK_MASK;
    1051    43925174 :                 error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */
    1052    43925807 :                 ASSERT(error == -ENOATTR);
    1053    43925807 :                 error = xfs_attr3_leaf_add(bp, &nargs);
    1054    43926462 :                 ASSERT(error != -ENOSPC);
    1055    43926462 :                 if (error)
    1056           0 :                         goto out;
    1057    43926462 :                 sfe = xfs_attr_sf_nextentry(sfe);
    1058             :         }
    1059             :         error = 0;
    1060     8587960 : out:
    1061     8587960 :         kmem_free(tmpbuffer);
    1062     8588024 :         return error;
    1063             : }
    1064             : 
    1065             : /*
    1066             :  * Check a leaf attribute block to see if all the entries would fit into
    1067             :  * a shortform attribute list.
    1068             :  */
    1069             : int
    1070    95062841 : xfs_attr_shortform_allfit(
    1071             :         struct xfs_buf          *bp,
    1072             :         struct xfs_inode        *dp)
    1073             : {
    1074    95062841 :         struct xfs_attr_leafblock *leaf;
    1075    95062841 :         struct xfs_attr_leaf_entry *entry;
    1076    95062841 :         xfs_attr_leaf_name_local_t *name_loc;
    1077    95062841 :         struct xfs_attr3_icleaf_hdr leafhdr;
    1078    95062841 :         int                     bytes;
    1079    95062841 :         int                     i;
    1080    95062841 :         struct xfs_mount        *mp = bp->b_mount;
    1081             : 
    1082    95062841 :         leaf = bp->b_addr;
    1083    95062841 :         xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
    1084    95064935 :         entry = xfs_attr3_leaf_entryp(leaf);
    1085             : 
    1086             :         bytes = sizeof(struct xfs_attr_sf_hdr);
    1087  1818479053 :         for (i = 0; i < leafhdr.count; entry++, i++) {
    1088  1723415326 :                 if (entry->flags & XFS_ATTR_INCOMPLETE)
    1089           0 :                         continue;               /* don't copy partial entries */
    1090  1723415326 :                 if (!(entry->flags & XFS_ATTR_LOCAL))
    1091             :                         return 0;
    1092  1723415326 :                 name_loc = xfs_attr3_leaf_name_local(leaf, i);
    1093  1723415326 :                 if (name_loc->namelen >= XFS_ATTR_SF_ENTSIZE_MAX)
    1094             :                         return 0;
    1095  1723415326 :                 if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX)
    1096             :                         return 0;
    1097  1723414118 :                 bytes += xfs_attr_sf_entsize_byname(name_loc->namelen,
    1098           0 :                                         be16_to_cpu(name_loc->valuelen));
    1099             :         }
    1100    95063727 :         if (xfs_has_attr2(dp->i_mount) &&
    1101    95063727 :             (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) &&
    1102             :             (bytes == sizeof(struct xfs_attr_sf_hdr)))
    1103             :                 return -1;
    1104    95063709 :         return xfs_attr_shortform_bytesfit(dp, bytes);
    1105             : }
    1106             : 
    1107             : /* Verify the consistency of a raw inline attribute fork. */
    1108             : xfs_failaddr_t
    1109   666174458 : xfs_attr_shortform_verify_struct(
    1110             :         struct xfs_attr_shortform       *sfp,
    1111             :         size_t                          size)
    1112             : {
    1113   666174458 :         struct xfs_attr_sf_entry        *sfep;
    1114   666174458 :         struct xfs_attr_sf_entry        *next_sfep;
    1115   666174458 :         char                            *endp;
    1116   666174458 :         int                             i;
    1117             : 
    1118             :         /*
    1119             :          * Give up if the attribute is way too short.
    1120             :          */
    1121   666174458 :         if (size < sizeof(struct xfs_attr_sf_hdr))
    1122           0 :                 return __this_address;
    1123             : 
    1124   666174458 :         endp = (char *)sfp + size;
    1125             : 
    1126             :         /* Check all reported entries */
    1127   666174458 :         sfep = &sfp->list[0];
    1128  1544097331 :         for (i = 0; i < sfp->hdr.count; i++) {
    1129             :                 /*
    1130             :                  * struct xfs_attr_sf_entry has a variable length.
    1131             :                  * Check the fixed-offset parts of the structure are
    1132             :                  * within the data buffer.
    1133             :                  * xfs_attr_sf_entry is defined with a 1-byte variable
    1134             :                  * array at the end, so we must subtract that off.
    1135             :                  */
    1136   877893099 :                 if (((char *)sfep + sizeof(*sfep)) >= endp)
    1137           0 :                         return __this_address;
    1138             : 
    1139             :                 /* Don't allow names with known bad length. */
    1140   877893099 :                 if (sfep->namelen == 0)
    1141           0 :                         return __this_address;
    1142             : 
    1143             :                 /*
    1144             :                  * Check that the variable-length part of the structure is
    1145             :                  * within the data buffer.  The next entry starts after the
    1146             :                  * name component, so nextentry is an acceptable test.
    1147             :                  */
    1148   877893099 :                 next_sfep = xfs_attr_sf_nextentry(sfep);
    1149   877893099 :                 if ((char *)next_sfep > endp)
    1150           0 :                         return __this_address;
    1151             : 
    1152             :                 /*
    1153             :                  * Check for unknown flags.  Short form doesn't support
    1154             :                  * the incomplete or local bits, so we can use the namespace
    1155             :                  * mask here.
    1156             :                  */
    1157   877893099 :                 if (sfep->flags & ~XFS_ATTR_NSP_ONDISK_MASK)
    1158           0 :                         return __this_address;
    1159             : 
    1160             :                 /*
    1161             :                  * Check for invalid namespace combinations.  We only allow
    1162             :                  * one namespace flag per xattr, so we can just count the
    1163             :                  * bits (i.e. hweight) here.
    1164             :                  */
    1165  1755815972 :                 if (hweight8(sfep->flags & XFS_ATTR_NSP_ONDISK_MASK) > 1)
    1166           0 :                         return __this_address;
    1167             : 
    1168   877922873 :                 sfep = next_sfep;
    1169             :         }
    1170   666204232 :         if ((void *)sfep != (void *)endp)
    1171           0 :                 return __this_address;
    1172             : 
    1173             :         return NULL;
    1174             : }
    1175             : 
    1176             : /* Verify the consistency of an inline attribute fork. */
    1177             : xfs_failaddr_t
    1178   666167098 : xfs_attr_shortform_verify(
    1179             :         struct xfs_inode                *ip)
    1180             : {
    1181   666167098 :         struct xfs_attr_shortform       *sfp;
    1182   666167098 :         struct xfs_ifork                *ifp;
    1183   666167098 :         int64_t                         size;
    1184             : 
    1185   666167098 :         ASSERT(ip->i_af.if_format == XFS_DINODE_FMT_LOCAL);
    1186   666167098 :         ifp = xfs_ifork_ptr(ip, XFS_ATTR_FORK);
    1187   666167098 :         sfp = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
    1188   666167098 :         size = ifp->if_bytes;
    1189             : 
    1190   666167098 :         return xfs_attr_shortform_verify_struct(sfp, size);
    1191             : }
    1192             : 
    1193             : /*
    1194             :  * Convert a leaf attribute list to shortform attribute list
    1195             :  */
    1196             : int
    1197     4500905 : xfs_attr3_leaf_to_shortform(
    1198             :         struct xfs_buf          *bp,
    1199             :         struct xfs_da_args      *args,
    1200             :         int                     forkoff)
    1201             : {
    1202     4500905 :         struct xfs_attr_leafblock *leaf;
    1203     4500905 :         struct xfs_attr3_icleaf_hdr ichdr;
    1204     4500905 :         struct xfs_attr_leaf_entry *entry;
    1205     4500905 :         struct xfs_attr_leaf_name_local *name_loc;
    1206     4500905 :         struct xfs_da_args      nargs;
    1207     4500905 :         struct xfs_inode        *dp = args->dp;
    1208     4500905 :         char                    *tmpbuffer;
    1209     4500905 :         int                     error;
    1210     4500905 :         int                     i;
    1211             : 
    1212     4500905 :         trace_xfs_attr_leaf_to_sf(args);
    1213             : 
    1214     4501013 :         tmpbuffer = kmem_alloc(args->geo->blksize, 0);
    1215     4500995 :         if (!tmpbuffer)
    1216             :                 return -ENOMEM;
    1217             : 
    1218     9001990 :         memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
    1219             : 
    1220     4500995 :         leaf = (xfs_attr_leafblock_t *)tmpbuffer;
    1221     4500995 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    1222     4500983 :         entry = xfs_attr3_leaf_entryp(leaf);
    1223             : 
    1224             :         /* XXX (dgc): buffer is about to be marked stale - why zero it? */
    1225     4500983 :         memset(bp->b_addr, 0, args->geo->blksize);
    1226             : 
    1227             :         /*
    1228             :          * Clean out the prior contents of the attribute list.
    1229             :          */
    1230     4500983 :         error = xfs_da_shrink_inode(args, 0, bp);
    1231     4500968 :         if (error)
    1232           0 :                 goto out;
    1233             : 
    1234     4500968 :         if (forkoff == -1) {
    1235             :                 /*
    1236             :                  * Don't remove the attr fork if this operation is the first
    1237             :                  * part of a attr replace operations. We're going to add a new
    1238             :                  * attr immediately, so we need to keep the attr fork around in
    1239             :                  * this case.
    1240             :                  */
    1241          18 :                 if (!(args->op_flags & XFS_DA_OP_REPLACE)) {
    1242          14 :                         ASSERT(xfs_has_attr2(dp->i_mount));
    1243          14 :                         ASSERT(dp->i_df.if_format != XFS_DINODE_FMT_BTREE);
    1244          14 :                         xfs_attr_fork_remove(dp, args->trans);
    1245             :                 }
    1246          18 :                 goto out;
    1247             :         }
    1248             : 
    1249     4500950 :         xfs_attr_shortform_create(args);
    1250             : 
    1251             :         /*
    1252             :          * Copy the attributes
    1253             :          */
    1254     4500922 :         memset((char *)&nargs, 0, sizeof(nargs));
    1255     4500922 :         nargs.geo = args->geo;
    1256     4500922 :         nargs.dp = dp;
    1257     4500922 :         nargs.total = args->total;
    1258     4500922 :         nargs.whichfork = XFS_ATTR_FORK;
    1259     4500922 :         nargs.trans = args->trans;
    1260     4500922 :         nargs.op_flags = XFS_DA_OP_OKNOENT | XFS_DA_OP_NVLOOKUP;
    1261     4500922 :         nargs.owner = args->owner;
    1262             : 
    1263    28540357 :         for (i = 0; i < ichdr.count; entry++, i++) {
    1264    24039353 :                 if (entry->flags & XFS_ATTR_INCOMPLETE)
    1265           0 :                         continue;       /* don't copy partial entries */
    1266    24039353 :                 if (!entry->nameidx)
    1267           0 :                         continue;
    1268    24039353 :                 ASSERT(entry->flags & XFS_ATTR_LOCAL);
    1269    24039353 :                 name_loc = xfs_attr3_leaf_name_local(leaf, i);
    1270    24039353 :                 nargs.name = name_loc->nameval;
    1271    24039353 :                 nargs.namelen = name_loc->namelen;
    1272    24039353 :                 nargs.value = &name_loc->nameval[nargs.namelen];
    1273    24039353 :                 nargs.valuelen = be16_to_cpu(name_loc->valuelen);
    1274    24039353 :                 nargs.hashval = be32_to_cpu(entry->hashval);
    1275    24039353 :                 nargs.attr_filter = entry->flags & XFS_ATTR_NSP_ONDISK_MASK;
    1276    24039353 :                 xfs_attr_shortform_add(&nargs, forkoff);
    1277             :         }
    1278             :         error = 0;
    1279             : 
    1280     4501022 : out:
    1281     4501022 :         kmem_free(tmpbuffer);
    1282     4501022 :         return error;
    1283             : }
    1284             : 
    1285             : /*
    1286             :  * Convert from using a single leaf to a root node and a leaf.
    1287             :  */
    1288             : int
    1289       80091 : xfs_attr3_leaf_to_node(
    1290             :         struct xfs_da_args      *args)
    1291             : {
    1292       80091 :         struct xfs_attr_leafblock *leaf;
    1293       80091 :         struct xfs_attr3_icleaf_hdr icleafhdr;
    1294       80091 :         struct xfs_attr_leaf_entry *entries;
    1295       80091 :         struct xfs_da3_icnode_hdr icnodehdr;
    1296       80091 :         struct xfs_da_intnode   *node;
    1297       80091 :         struct xfs_inode        *dp = args->dp;
    1298       80091 :         struct xfs_mount        *mp = dp->i_mount;
    1299       80091 :         struct xfs_buf          *bp1 = NULL;
    1300       80091 :         struct xfs_buf          *bp2 = NULL;
    1301       80091 :         xfs_dablk_t             blkno;
    1302       80091 :         int                     error;
    1303             : 
    1304       80091 :         trace_xfs_attr_leaf_to_node(args);
    1305             : 
    1306       80091 :         if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_ATTR_LEAF_TO_NODE)) {
    1307           2 :                 error = -EIO;
    1308           2 :                 goto out;
    1309             :         }
    1310             : 
    1311       80089 :         error = xfs_da_grow_inode(args, &blkno);
    1312       80089 :         if (error)
    1313           0 :                 goto out;
    1314       80089 :         error = xfs_attr3_leaf_read(args->trans, dp, args->owner, 0, &bp1);
    1315       80089 :         if (error)
    1316           0 :                 goto out;
    1317             : 
    1318       80089 :         error = xfs_da_get_buf(args->trans, dp, blkno, &bp2, XFS_ATTR_FORK);
    1319       80089 :         if (error)
    1320           0 :                 goto out;
    1321             : 
    1322             :         /* copy leaf to new buffer, update identifiers */
    1323       80089 :         xfs_trans_buf_set_type(args->trans, bp2, XFS_BLFT_ATTR_LEAF_BUF);
    1324       80089 :         bp2->b_ops = bp1->b_ops;
    1325      160178 :         memcpy(bp2->b_addr, bp1->b_addr, args->geo->blksize);
    1326       80089 :         if (xfs_has_crc(mp)) {
    1327       80089 :                 struct xfs_da3_blkinfo *hdr3 = bp2->b_addr;
    1328       80089 :                 hdr3->blkno = cpu_to_be64(xfs_buf_daddr(bp2));
    1329             :         }
    1330       80089 :         xfs_trans_log_buf(args->trans, bp2, 0, args->geo->blksize - 1);
    1331             : 
    1332             :         /*
    1333             :          * Set up the new root node.
    1334             :          */
    1335       80089 :         error = xfs_da3_node_create(args, 0, 1, &bp1, XFS_ATTR_FORK);
    1336       80089 :         if (error)
    1337           0 :                 goto out;
    1338       80089 :         node = bp1->b_addr;
    1339       80089 :         xfs_da3_node_hdr_from_disk(mp, &icnodehdr, node);
    1340             : 
    1341       80089 :         leaf = bp2->b_addr;
    1342       80089 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &icleafhdr, leaf);
    1343       80089 :         entries = xfs_attr3_leaf_entryp(leaf);
    1344             : 
    1345             :         /* both on-disk, don't endian-flip twice */
    1346       80089 :         icnodehdr.btree[0].hashval = entries[icleafhdr.count - 1].hashval;
    1347       80089 :         icnodehdr.btree[0].before = cpu_to_be32(blkno);
    1348       80089 :         icnodehdr.count = 1;
    1349       80089 :         xfs_da3_node_hdr_to_disk(dp->i_mount, node, &icnodehdr);
    1350       80089 :         xfs_trans_log_buf(args->trans, bp1, 0, args->geo->blksize - 1);
    1351       80089 :         error = 0;
    1352       80091 : out:
    1353       80091 :         return error;
    1354             : }
    1355             : 
    1356             : /*========================================================================
    1357             :  * Routines used for growing the Btree.
    1358             :  *========================================================================*/
    1359             : 
    1360             : /*
    1361             :  * Create the initial contents of a leaf attribute list
    1362             :  * or a leaf in a node attribute list.
    1363             :  */
    1364             : STATIC int
    1365     8695983 : xfs_attr3_leaf_create(
    1366             :         struct xfs_da_args      *args,
    1367             :         xfs_dablk_t             blkno,
    1368             :         struct xfs_buf          **bpp)
    1369             : {
    1370     8695983 :         struct xfs_attr_leafblock *leaf;
    1371     8695983 :         struct xfs_attr3_icleaf_hdr ichdr;
    1372     8695983 :         struct xfs_inode        *dp = args->dp;
    1373     8695983 :         struct xfs_mount        *mp = dp->i_mount;
    1374     8695983 :         struct xfs_buf          *bp;
    1375     8695983 :         int                     error;
    1376             : 
    1377     8695983 :         trace_xfs_attr_leaf_create(args);
    1378             : 
    1379     8696315 :         error = xfs_da_get_buf(args->trans, args->dp, blkno, &bp,
    1380             :                                             XFS_ATTR_FORK);
    1381     8696519 :         if (error)
    1382             :                 return error;
    1383     8696512 :         bp->b_ops = &xfs_attr3_leaf_buf_ops;
    1384     8696512 :         xfs_trans_buf_set_type(args->trans, bp, XFS_BLFT_ATTR_LEAF_BUF);
    1385     8696363 :         leaf = bp->b_addr;
    1386     8696363 :         memset(leaf, 0, args->geo->blksize);
    1387             : 
    1388     8696363 :         memset(&ichdr, 0, sizeof(ichdr));
    1389     8696363 :         ichdr.firstused = args->geo->blksize;
    1390             : 
    1391     8696363 :         if (xfs_has_crc(mp)) {
    1392     8696363 :                 struct xfs_da3_blkinfo *hdr3 = bp->b_addr;
    1393             : 
    1394     8696363 :                 ichdr.magic = XFS_ATTR3_LEAF_MAGIC;
    1395             : 
    1396     8696363 :                 hdr3->blkno = cpu_to_be64(xfs_buf_daddr(bp));
    1397     8696363 :                 hdr3->owner = cpu_to_be64(args->owner);
    1398     8696363 :                 uuid_copy(&hdr3->uuid, &mp->m_sb.sb_meta_uuid);
    1399             : 
    1400     8696423 :                 ichdr.freemap[0].base = sizeof(struct xfs_attr3_leaf_hdr);
    1401             :         } else {
    1402           0 :                 ichdr.magic = XFS_ATTR_LEAF_MAGIC;
    1403           0 :                 ichdr.freemap[0].base = sizeof(struct xfs_attr_leaf_hdr);
    1404             :         }
    1405     8696423 :         ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base;
    1406             : 
    1407     8696423 :         xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr);
    1408     8696441 :         xfs_trans_log_buf(args->trans, bp, 0, args->geo->blksize - 1);
    1409             : 
    1410     8696476 :         *bpp = bp;
    1411     8696476 :         return 0;
    1412             : }
    1413             : 
    1414             : /*
    1415             :  * Split the leaf node, rebalance, then add the new entry.
    1416             :  */
    1417             : int
    1418      108622 : xfs_attr3_leaf_split(
    1419             :         struct xfs_da_state     *state,
    1420             :         struct xfs_da_state_blk *oldblk,
    1421             :         struct xfs_da_state_blk *newblk)
    1422             : {
    1423      108622 :         xfs_dablk_t blkno;
    1424      108622 :         int error;
    1425             : 
    1426      108622 :         trace_xfs_attr_leaf_split(state->args);
    1427             : 
    1428             :         /*
    1429             :          * Allocate space for a new leaf node.
    1430             :          */
    1431      108622 :         ASSERT(oldblk->magic == XFS_ATTR_LEAF_MAGIC);
    1432      108622 :         error = xfs_da_grow_inode(state->args, &blkno);
    1433      108622 :         if (error)
    1434             :                 return error;
    1435      108622 :         error = xfs_attr3_leaf_create(state->args, blkno, &newblk->bp);
    1436      108622 :         if (error)
    1437             :                 return error;
    1438      108622 :         newblk->blkno = blkno;
    1439      108622 :         newblk->magic = XFS_ATTR_LEAF_MAGIC;
    1440             : 
    1441             :         /*
    1442             :          * Rebalance the entries across the two leaves.
    1443             :          * NOTE: rebalance() currently depends on the 2nd block being empty.
    1444             :          */
    1445      108622 :         xfs_attr3_leaf_rebalance(state, oldblk, newblk);
    1446      108622 :         error = xfs_da3_blk_link(state, oldblk, newblk);
    1447      108622 :         if (error)
    1448             :                 return error;
    1449             : 
    1450             :         /*
    1451             :          * Save info on "old" attribute for "atomic rename" ops, leaf_add()
    1452             :          * modifies the index/blkno/rmtblk/rmtblkcnt fields to show the
    1453             :          * "new" attrs info.  Will need the "old" info to remove it later.
    1454             :          *
    1455             :          * Insert the "new" entry in the correct block.
    1456             :          */
    1457      108622 :         if (state->inleaf) {
    1458       24188 :                 trace_xfs_attr_leaf_add_old(state->args);
    1459       24188 :                 error = xfs_attr3_leaf_add(oldblk->bp, state->args);
    1460             :         } else {
    1461       84434 :                 trace_xfs_attr_leaf_add_new(state->args);
    1462       84434 :                 error = xfs_attr3_leaf_add(newblk->bp, state->args);
    1463             :         }
    1464             : 
    1465             :         /*
    1466             :          * Update last hashval in each block since we added the name.
    1467             :          */
    1468      108622 :         oldblk->hashval = xfs_attr_leaf_lasthash(oldblk->bp, NULL);
    1469      108622 :         newblk->hashval = xfs_attr_leaf_lasthash(newblk->bp, NULL);
    1470      108622 :         return error;
    1471             : }
    1472             : 
    1473             : /*
    1474             :  * Add a name to the leaf attribute list structure.
    1475             :  */
    1476             : int
    1477   199035261 : xfs_attr3_leaf_add(
    1478             :         struct xfs_buf          *bp,
    1479             :         struct xfs_da_args      *args)
    1480             : {
    1481   199035261 :         struct xfs_attr_leafblock *leaf;
    1482   199035261 :         struct xfs_attr3_icleaf_hdr ichdr;
    1483   199035261 :         int                     tablesize;
    1484   199035261 :         int                     entsize;
    1485   199035261 :         int                     sum;
    1486   199035261 :         int                     tmp;
    1487   199035261 :         int                     i;
    1488             : 
    1489   199035261 :         trace_xfs_attr_leaf_add(args);
    1490             : 
    1491   199088663 :         leaf = bp->b_addr;
    1492   199088663 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    1493   199059267 :         ASSERT(args->index >= 0 && args->index <= ichdr.count);
    1494   199059267 :         entsize = xfs_attr_leaf_newentsize(args, NULL);
    1495             : 
    1496             :         /*
    1497             :          * Search through freemap for first-fit on new name length.
    1498             :          * (may need to figure in size of entry struct too)
    1499             :          */
    1500   199082059 :         tablesize = (ichdr.count + 1) * sizeof(xfs_attr_leaf_entry_t)
    1501   199082059 :                                         + xfs_attr3_leaf_hdr_size(leaf);
    1502   483699641 :         for (sum = 0, i = XFS_ATTR_LEAF_MAPSIZE - 1; i >= 0; i--) {
    1503   482939119 :                 if (tablesize > ichdr.firstused) {
    1504      186291 :                         sum += ichdr.freemap[i].size;
    1505      186291 :                         continue;
    1506             :                 }
    1507   482752828 :                 if (!ichdr.freemap[i].size)
    1508   157576435 :                         continue;       /* no space in this map */
    1509   325176393 :                 tmp = entsize;
    1510   325176393 :                 if (ichdr.freemap[i].base < ichdr.firstused)
    1511   128046874 :                         tmp += sizeof(xfs_attr_leaf_entry_t);
    1512   325176393 :                 if (ichdr.freemap[i].size >= tmp) {
    1513   198321537 :                         tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, i);
    1514   198335737 :                         goto out_log_hdr;
    1515             :                 }
    1516   126854856 :                 sum += ichdr.freemap[i].size;
    1517             :         }
    1518             : 
    1519             :         /*
    1520             :          * If there are no holes in the address space of the block,
    1521             :          * and we don't have enough freespace, then compaction will do us
    1522             :          * no good and we should just give up.
    1523             :          */
    1524      760522 :         if (!ichdr.holes && sum < entsize)
    1525             :                 return -ENOSPC;
    1526             : 
    1527             :         /*
    1528             :          * Compact the entries to coalesce free space.
    1529             :          * This may change the hdr->count via dropping INCOMPLETE entries.
    1530             :          */
    1531      630077 :         xfs_attr3_leaf_compact(args, &ichdr, bp);
    1532             : 
    1533             :         /*
    1534             :          * After compaction, the block is guaranteed to have only one
    1535             :          * free region, in freemap[0].  If it is not big enough, give up.
    1536             :          */
    1537      630075 :         if (ichdr.freemap[0].size < (entsize + sizeof(xfs_attr_leaf_entry_t))) {
    1538       58268 :                 tmp = -ENOSPC;
    1539       58268 :                 goto out_log_hdr;
    1540             :         }
    1541             : 
    1542      571807 :         tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, 0);
    1543             : 
    1544   198965812 : out_log_hdr:
    1545   198965812 :         xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr);
    1546   198964854 :         xfs_trans_log_buf(args->trans, bp,
    1547   198964854 :                 XFS_DA_LOGRANGE(leaf, &leaf->hdr,
    1548             :                                 xfs_attr3_leaf_hdr_size(leaf)));
    1549   198964854 :         return tmp;
    1550             : }
    1551             : 
    1552             : /*
    1553             :  * Add a name to a leaf attribute list structure.
    1554             :  */
    1555             : STATIC int
    1556   198872497 : xfs_attr3_leaf_add_work(
    1557             :         struct xfs_buf          *bp,
    1558             :         struct xfs_attr3_icleaf_hdr *ichdr,
    1559             :         struct xfs_da_args      *args,
    1560             :         int                     mapindex)
    1561             : {
    1562   198872497 :         struct xfs_attr_leafblock *leaf;
    1563   198872497 :         struct xfs_attr_leaf_entry *entry;
    1564   198872497 :         struct xfs_attr_leaf_name_local *name_loc;
    1565   198872497 :         struct xfs_attr_leaf_name_remote *name_rmt;
    1566   198872497 :         struct xfs_mount        *mp;
    1567   198872497 :         int                     tmp;
    1568   198872497 :         int                     i;
    1569             : 
    1570   198872497 :         trace_xfs_attr_leaf_add_work(args);
    1571             : 
    1572   198891850 :         leaf = bp->b_addr;
    1573   198891850 :         ASSERT(mapindex >= 0 && mapindex < XFS_ATTR_LEAF_MAPSIZE);
    1574   198891850 :         ASSERT(args->index >= 0 && args->index <= ichdr->count);
    1575             : 
    1576             :         /*
    1577             :          * Force open some space in the entry array and fill it in.
    1578             :          */
    1579   198891850 :         entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
    1580   198891850 :         if (args->index < ichdr->count) {
    1581   173815770 :                 tmp  = ichdr->count - args->index;
    1582   173815770 :                 tmp *= sizeof(xfs_attr_leaf_entry_t);
    1583   347631540 :                 memmove(entry + 1, entry, tmp);
    1584   173815770 :                 xfs_trans_log_buf(args->trans, bp,
    1585   173815770 :                     XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
    1586             :         }
    1587   198896404 :         ichdr->count++;
    1588             : 
    1589             :         /*
    1590             :          * Allocate space for the new string (at the end of the run).
    1591             :          */
    1592   198896404 :         mp = args->trans->t_mountp;
    1593   198896404 :         ASSERT(ichdr->freemap[mapindex].base < args->geo->blksize);
    1594   198896404 :         ASSERT((ichdr->freemap[mapindex].base & 0x3) == 0);
    1595   198896404 :         ASSERT(ichdr->freemap[mapindex].size >=
    1596             :                 xfs_attr_leaf_newentsize(args, NULL));
    1597   198894165 :         ASSERT(ichdr->freemap[mapindex].size < args->geo->blksize);
    1598   198894165 :         ASSERT((ichdr->freemap[mapindex].size & 0x3) == 0);
    1599             : 
    1600   198894165 :         ichdr->freemap[mapindex].size -= xfs_attr_leaf_newentsize(args, &tmp);
    1601             : 
    1602   198880245 :         entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base +
    1603             :                                      ichdr->freemap[mapindex].size);
    1604   198880245 :         entry->hashval = cpu_to_be32(args->hashval);
    1605   198880245 :         entry->flags = args->attr_filter;
    1606   198880245 :         if (tmp)
    1607   198901072 :                 entry->flags |= XFS_ATTR_LOCAL;
    1608   198880245 :         if (args->op_flags & XFS_DA_OP_REPLACE) {
    1609    36991153 :                 if (!(args->op_flags & XFS_DA_OP_LOGGED))
    1610    36991262 :                         entry->flags |= XFS_ATTR_INCOMPLETE;
    1611    36991153 :                 if ((args->blkno2 == args->blkno) &&
    1612    36990477 :                     (args->index2 <= args->index)) {
    1613    36990887 :                         args->index2++;
    1614             :                 }
    1615             :         }
    1616   198880245 :         xfs_trans_log_buf(args->trans, bp,
    1617   198880245 :                           XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
    1618   555428926 :         ASSERT((args->index == 0) ||
    1619             :                (be32_to_cpu(entry->hashval) >= be32_to_cpu((entry-1)->hashval)));
    1620   546508222 :         ASSERT((args->index == ichdr->count - 1) ||
    1621             :                (be32_to_cpu(entry->hashval) <= be32_to_cpu((entry+1)->hashval)));
    1622             : 
    1623             :         /*
    1624             :          * For "remote" attribute values, simply note that we need to
    1625             :          * allocate space for the "remote" value.  We can't actually
    1626             :          * allocate the extents in this transaction, and we can't decide
    1627             :          * which blocks they should be as we might allocate more blocks
    1628             :          * as part of this transaction (a split operation for example).
    1629             :          */
    1630   198879990 :         if (entry->flags & XFS_ATTR_LOCAL) {
    1631   198879405 :                 name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
    1632   198879405 :                 name_loc->namelen = args->namelen;
    1633   198879405 :                 name_loc->valuelen = cpu_to_be16(args->valuelen);
    1634   397758810 :                 memcpy((char *)name_loc->nameval, args->name, args->namelen);
    1635   397758810 :                 memcpy((char *)&name_loc->nameval[args->namelen], args->value,
    1636             :                                    be16_to_cpu(name_loc->valuelen));
    1637             :         } else {
    1638         585 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
    1639         585 :                 name_rmt->namelen = args->namelen;
    1640        1170 :                 memcpy((char *)name_rmt->name, args->name, args->namelen);
    1641         585 :                 entry->flags |= XFS_ATTR_INCOMPLETE;
    1642             :                 /* just in case */
    1643         585 :                 name_rmt->valuelen = 0;
    1644         585 :                 name_rmt->valueblk = 0;
    1645         585 :                 args->rmtblkno = 1;
    1646         585 :                 args->rmtblkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen);
    1647         585 :                 args->rmtvaluelen = args->valuelen;
    1648             :         }
    1649   198879990 :         xfs_trans_log_buf(args->trans, bp,
    1650   198879990 :              XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index),
    1651             :                                    xfs_attr_leaf_entsize(leaf, args->index)));
    1652             : 
    1653             :         /*
    1654             :          * Update the control info for this leaf node
    1655             :          */
    1656   198887175 :         if (be16_to_cpu(entry->nameidx) < ichdr->firstused)
    1657   127887092 :                 ichdr->firstused = be16_to_cpu(entry->nameidx);
    1658             : 
    1659   397792180 :         ASSERT(ichdr->firstused >= ichdr->count * sizeof(xfs_attr_leaf_entry_t)
    1660             :                                         + xfs_attr3_leaf_hdr_size(leaf));
    1661   397774350 :         tmp = (ichdr->count - 1) * sizeof(xfs_attr_leaf_entry_t)
    1662   198887175 :                                         + xfs_attr3_leaf_hdr_size(leaf);
    1663             : 
    1664   795491911 :         for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
    1665   596604736 :                 if (ichdr->freemap[i].base == tmp) {
    1666   198822439 :                         ichdr->freemap[i].base += sizeof(xfs_attr_leaf_entry_t);
    1667   198822439 :                         ichdr->freemap[i].size -=
    1668   198822439 :                                 min_t(uint16_t, ichdr->freemap[i].size,
    1669             :                                                 sizeof(xfs_attr_leaf_entry_t));
    1670             :                 }
    1671             :         }
    1672   198887175 :         ichdr->usedbytes += xfs_attr_leaf_entsize(leaf, args->index);
    1673   198887175 :         return 0;
    1674             : }
    1675             : 
    1676             : /*
    1677             :  * Garbage collect a leaf attribute list block by copying it to a new buffer.
    1678             :  */
    1679             : STATIC void
    1680      630076 : xfs_attr3_leaf_compact(
    1681             :         struct xfs_da_args      *args,
    1682             :         struct xfs_attr3_icleaf_hdr *ichdr_dst,
    1683             :         struct xfs_buf          *bp)
    1684             : {
    1685      630076 :         struct xfs_attr_leafblock *leaf_src;
    1686      630076 :         struct xfs_attr_leafblock *leaf_dst;
    1687      630076 :         struct xfs_attr3_icleaf_hdr ichdr_src;
    1688      630076 :         struct xfs_trans        *trans = args->trans;
    1689      630076 :         char                    *tmpbuffer;
    1690             : 
    1691      630076 :         trace_xfs_attr_leaf_compact(args);
    1692             : 
    1693      630077 :         tmpbuffer = kmem_alloc(args->geo->blksize, 0);
    1694     1260154 :         memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
    1695      630077 :         memset(bp->b_addr, 0, args->geo->blksize);
    1696      630077 :         leaf_src = (xfs_attr_leafblock_t *)tmpbuffer;
    1697      630077 :         leaf_dst = bp->b_addr;
    1698             : 
    1699             :         /*
    1700             :          * Copy the on-disk header back into the destination buffer to ensure
    1701             :          * all the information in the header that is not part of the incore
    1702             :          * header structure is preserved.
    1703             :          */
    1704     1890230 :         memcpy(bp->b_addr, tmpbuffer, xfs_attr3_leaf_hdr_size(leaf_src));
    1705             : 
    1706             :         /* Initialise the incore headers */
    1707      630077 :         ichdr_src = *ichdr_dst; /* struct copy */
    1708      630077 :         ichdr_dst->firstused = args->geo->blksize;
    1709      630077 :         ichdr_dst->usedbytes = 0;
    1710      630077 :         ichdr_dst->count = 0;
    1711      630077 :         ichdr_dst->holes = 0;
    1712      630077 :         ichdr_dst->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_src);
    1713      630077 :         ichdr_dst->freemap[0].size = ichdr_dst->firstused -
    1714             :                                                 ichdr_dst->freemap[0].base;
    1715             : 
    1716             :         /* write the header back to initialise the underlying buffer */
    1717      630077 :         xfs_attr3_leaf_hdr_to_disk(args->geo, leaf_dst, ichdr_dst);
    1718             : 
    1719             :         /*
    1720             :          * Copy all entry's in the same (sorted) order,
    1721             :          * but allocate name/value pairs packed and in sequence.
    1722             :          */
    1723      630077 :         xfs_attr3_leaf_moveents(args, leaf_src, &ichdr_src, 0,
    1724      630077 :                                 leaf_dst, ichdr_dst, 0, ichdr_src.count);
    1725             :         /*
    1726             :          * this logs the entire buffer, but the caller must write the header
    1727             :          * back to the buffer when it is finished modifying it.
    1728             :          */
    1729      630076 :         xfs_trans_log_buf(trans, bp, 0, args->geo->blksize - 1);
    1730             : 
    1731      630077 :         kmem_free(tmpbuffer);
    1732      630077 : }
    1733             : 
    1734             : /*
    1735             :  * Compare two leaf blocks "order".
    1736             :  * Return 0 unless leaf2 should go before leaf1.
    1737             :  */
    1738             : static int
    1739      218717 : xfs_attr3_leaf_order(
    1740             :         struct xfs_buf  *leaf1_bp,
    1741             :         struct xfs_attr3_icleaf_hdr *leaf1hdr,
    1742             :         struct xfs_buf  *leaf2_bp,
    1743             :         struct xfs_attr3_icleaf_hdr *leaf2hdr)
    1744             : {
    1745      218717 :         struct xfs_attr_leaf_entry *entries1;
    1746      218717 :         struct xfs_attr_leaf_entry *entries2;
    1747             : 
    1748      218717 :         entries1 = xfs_attr3_leaf_entryp(leaf1_bp->b_addr);
    1749      218717 :         entries2 = xfs_attr3_leaf_entryp(leaf2_bp->b_addr);
    1750      328812 :         if (leaf1hdr->count > 0 && leaf2hdr->count > 0 &&
    1751      110095 :             ((be32_to_cpu(entries2[0].hashval) <
    1752      220067 :               be32_to_cpu(entries1[0].hashval)) ||
    1753      109972 :              (be32_to_cpu(entries2[leaf2hdr->count - 1].hashval) <
    1754      109972 :               be32_to_cpu(entries1[leaf1hdr->count - 1].hashval)))) {
    1755         123 :                 return 1;
    1756             :         }
    1757             :         return 0;
    1758             : }
    1759             : 
    1760             : int
    1761      108622 : xfs_attr_leaf_order(
    1762             :         struct xfs_buf  *leaf1_bp,
    1763             :         struct xfs_buf  *leaf2_bp)
    1764             : {
    1765      108622 :         struct xfs_attr3_icleaf_hdr ichdr1;
    1766      108622 :         struct xfs_attr3_icleaf_hdr ichdr2;
    1767      108622 :         struct xfs_mount *mp = leaf1_bp->b_mount;
    1768             : 
    1769      108622 :         xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr1, leaf1_bp->b_addr);
    1770      108622 :         xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr2, leaf2_bp->b_addr);
    1771      108622 :         return xfs_attr3_leaf_order(leaf1_bp, &ichdr1, leaf2_bp, &ichdr2);
    1772             : }
    1773             : 
    1774             : /*
    1775             :  * Redistribute the attribute list entries between two leaf nodes,
    1776             :  * taking into account the size of the new entry.
    1777             :  *
    1778             :  * NOTE: if new block is empty, then it will get the upper half of the
    1779             :  * old block.  At present, all (one) callers pass in an empty second block.
    1780             :  *
    1781             :  * This code adjusts the args->index/blkno and args->index2/blkno2 fields
    1782             :  * to match what it is doing in splitting the attribute leaf block.  Those
    1783             :  * values are used in "atomic rename" operations on attributes.  Note that
    1784             :  * the "new" and "old" values can end up in different blocks.
    1785             :  */
    1786             : STATIC void
    1787      108622 : xfs_attr3_leaf_rebalance(
    1788             :         struct xfs_da_state     *state,
    1789             :         struct xfs_da_state_blk *blk1,
    1790             :         struct xfs_da_state_blk *blk2)
    1791             : {
    1792      108622 :         struct xfs_da_args      *args;
    1793      108622 :         struct xfs_attr_leafblock *leaf1;
    1794      108622 :         struct xfs_attr_leafblock *leaf2;
    1795      108622 :         struct xfs_attr3_icleaf_hdr ichdr1;
    1796      108622 :         struct xfs_attr3_icleaf_hdr ichdr2;
    1797      108622 :         struct xfs_attr_leaf_entry *entries1;
    1798      108622 :         struct xfs_attr_leaf_entry *entries2;
    1799      108622 :         int                     count;
    1800      108622 :         int                     totallen;
    1801      108622 :         int                     max;
    1802      108622 :         int                     space;
    1803      108622 :         int                     swap;
    1804             : 
    1805             :         /*
    1806             :          * Set up environment.
    1807             :          */
    1808      108622 :         ASSERT(blk1->magic == XFS_ATTR_LEAF_MAGIC);
    1809      108622 :         ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC);
    1810      108622 :         leaf1 = blk1->bp->b_addr;
    1811      108622 :         leaf2 = blk2->bp->b_addr;
    1812      108622 :         xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr1, leaf1);
    1813      108622 :         xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr2, leaf2);
    1814      108622 :         ASSERT(ichdr2.count == 0);
    1815      108622 :         args = state->args;
    1816             : 
    1817      108622 :         trace_xfs_attr_leaf_rebalance(args);
    1818             : 
    1819             :         /*
    1820             :          * Check ordering of blocks, reverse if it makes things simpler.
    1821             :          *
    1822             :          * NOTE: Given that all (current) callers pass in an empty
    1823             :          * second block, this code should never set "swap".
    1824             :          */
    1825      108622 :         swap = 0;
    1826      108622 :         if (xfs_attr3_leaf_order(blk1->bp, &ichdr1, blk2->bp, &ichdr2)) {
    1827           0 :                 swap(blk1, blk2);
    1828             : 
    1829             :                 /* swap structures rather than reconverting them */
    1830           0 :                 swap(ichdr1, ichdr2);
    1831             : 
    1832           0 :                 leaf1 = blk1->bp->b_addr;
    1833           0 :                 leaf2 = blk2->bp->b_addr;
    1834           0 :                 swap = 1;
    1835             :         }
    1836             : 
    1837             :         /*
    1838             :          * Examine entries until we reduce the absolute difference in
    1839             :          * byte usage between the two blocks to a minimum.  Then get
    1840             :          * the direction to copy and the number of elements to move.
    1841             :          *
    1842             :          * "inleaf" is true if the new entry should be inserted into blk1.
    1843             :          * If "swap" is also true, then reverse the sense of "inleaf".
    1844             :          */
    1845      108622 :         state->inleaf = xfs_attr3_leaf_figure_balance(state, blk1, &ichdr1,
    1846             :                                                       blk2, &ichdr2,
    1847             :                                                       &count, &totallen);
    1848      108622 :         if (swap)
    1849           0 :                 state->inleaf = !state->inleaf;
    1850             : 
    1851             :         /*
    1852             :          * Move any entries required from leaf to leaf:
    1853             :          */
    1854      108622 :         if (count < ichdr1.count) {
    1855             :                 /*
    1856             :                  * Figure the total bytes to be added to the destination leaf.
    1857             :                  */
    1858             :                 /* number entries being moved */
    1859      108622 :                 count = ichdr1.count - count;
    1860      108622 :                 space  = ichdr1.usedbytes - totallen;
    1861      108622 :                 space += count * sizeof(xfs_attr_leaf_entry_t);
    1862             : 
    1863             :                 /*
    1864             :                  * leaf2 is the destination, compact it if it looks tight.
    1865             :                  */
    1866      108622 :                 max  = ichdr2.firstused - xfs_attr3_leaf_hdr_size(leaf1);
    1867      108622 :                 max -= ichdr2.count * sizeof(xfs_attr_leaf_entry_t);
    1868      108622 :                 if (space > max)
    1869           0 :                         xfs_attr3_leaf_compact(args, &ichdr2, blk2->bp);
    1870             : 
    1871             :                 /*
    1872             :                  * Move high entries from leaf1 to low end of leaf2.
    1873             :                  */
    1874      108622 :                 xfs_attr3_leaf_moveents(args, leaf1, &ichdr1,
    1875      108622 :                                 ichdr1.count - count, leaf2, &ichdr2, 0, count);
    1876             : 
    1877           0 :         } else if (count > ichdr1.count) {
    1878             :                 /*
    1879             :                  * I assert that since all callers pass in an empty
    1880             :                  * second buffer, this code should never execute.
    1881             :                  */
    1882           0 :                 ASSERT(0);
    1883             : 
    1884             :                 /*
    1885             :                  * Figure the total bytes to be added to the destination leaf.
    1886             :                  */
    1887             :                 /* number entries being moved */
    1888           0 :                 count -= ichdr1.count;
    1889           0 :                 space  = totallen - ichdr1.usedbytes;
    1890           0 :                 space += count * sizeof(xfs_attr_leaf_entry_t);
    1891             : 
    1892             :                 /*
    1893             :                  * leaf1 is the destination, compact it if it looks tight.
    1894             :                  */
    1895           0 :                 max  = ichdr1.firstused - xfs_attr3_leaf_hdr_size(leaf1);
    1896           0 :                 max -= ichdr1.count * sizeof(xfs_attr_leaf_entry_t);
    1897           0 :                 if (space > max)
    1898           0 :                         xfs_attr3_leaf_compact(args, &ichdr1, blk1->bp);
    1899             : 
    1900             :                 /*
    1901             :                  * Move low entries from leaf2 to high end of leaf1.
    1902             :                  */
    1903           0 :                 xfs_attr3_leaf_moveents(args, leaf2, &ichdr2, 0, leaf1, &ichdr1,
    1904           0 :                                         ichdr1.count, count);
    1905             :         }
    1906             : 
    1907      108622 :         xfs_attr3_leaf_hdr_to_disk(state->args->geo, leaf1, &ichdr1);
    1908      108622 :         xfs_attr3_leaf_hdr_to_disk(state->args->geo, leaf2, &ichdr2);
    1909      108622 :         xfs_trans_log_buf(args->trans, blk1->bp, 0, args->geo->blksize - 1);
    1910      108622 :         xfs_trans_log_buf(args->trans, blk2->bp, 0, args->geo->blksize - 1);
    1911             : 
    1912             :         /*
    1913             :          * Copy out last hashval in each block for B-tree code.
    1914             :          */
    1915      108622 :         entries1 = xfs_attr3_leaf_entryp(leaf1);
    1916      108622 :         entries2 = xfs_attr3_leaf_entryp(leaf2);
    1917      108622 :         blk1->hashval = be32_to_cpu(entries1[ichdr1.count - 1].hashval);
    1918      108622 :         blk2->hashval = be32_to_cpu(entries2[ichdr2.count - 1].hashval);
    1919             : 
    1920             :         /*
    1921             :          * Adjust the expected index for insertion.
    1922             :          * NOTE: this code depends on the (current) situation that the
    1923             :          * second block was originally empty.
    1924             :          *
    1925             :          * If the insertion point moved to the 2nd block, we must adjust
    1926             :          * the index.  We must also track the entry just following the
    1927             :          * new entry for use in an "atomic rename" operation, that entry
    1928             :          * is always the "old" entry and the "new" entry is what we are
    1929             :          * inserting.  The index/blkno fields refer to the "old" entry,
    1930             :          * while the index2/blkno2 fields refer to the "new" entry.
    1931             :          */
    1932      108622 :         if (blk1->index > ichdr1.count) {
    1933       82912 :                 ASSERT(state->inleaf == 0);
    1934       82912 :                 blk2->index = blk1->index - ichdr1.count;
    1935       82912 :                 args->index = args->index2 = blk2->index;
    1936       82912 :                 args->blkno = args->blkno2 = blk2->blkno;
    1937       25710 :         } else if (blk1->index == ichdr1.count) {
    1938        2970 :                 if (state->inleaf) {
    1939        1448 :                         args->index = blk1->index;
    1940        1448 :                         args->blkno = blk1->blkno;
    1941        1448 :                         args->index2 = 0;
    1942        1448 :                         args->blkno2 = blk2->blkno;
    1943             :                 } else {
    1944             :                         /*
    1945             :                          * On a double leaf split, the original attr location
    1946             :                          * is already stored in blkno2/index2, so don't
    1947             :                          * overwrite it overwise we corrupt the tree.
    1948             :                          */
    1949        1522 :                         blk2->index = blk1->index - ichdr1.count;
    1950        1522 :                         args->index = blk2->index;
    1951        1522 :                         args->blkno = blk2->blkno;
    1952        1522 :                         if (!state->extravalid) {
    1953             :                                 /*
    1954             :                                  * set the new attr location to match the old
    1955             :                                  * one and let the higher level split code
    1956             :                                  * decide where in the leaf to place it.
    1957             :                                  */
    1958        1522 :                                 args->index2 = blk2->index;
    1959        1522 :                                 args->blkno2 = blk2->blkno;
    1960             :                         }
    1961             :                 }
    1962             :         } else {
    1963       22740 :                 ASSERT(state->inleaf == 1);
    1964       22740 :                 args->index = args->index2 = blk1->index;
    1965       22740 :                 args->blkno = args->blkno2 = blk1->blkno;
    1966             :         }
    1967      108622 : }
    1968             : 
    1969             : /*
    1970             :  * Examine entries until we reduce the absolute difference in
    1971             :  * byte usage between the two blocks to a minimum.
    1972             :  * GROT: Is this really necessary?  With other than a 512 byte blocksize,
    1973             :  * GROT: there will always be enough room in either block for a new entry.
    1974             :  * GROT: Do a double-split for this case?
    1975             :  */
    1976             : STATIC int
    1977      108622 : xfs_attr3_leaf_figure_balance(
    1978             :         struct xfs_da_state             *state,
    1979             :         struct xfs_da_state_blk         *blk1,
    1980             :         struct xfs_attr3_icleaf_hdr     *ichdr1,
    1981             :         struct xfs_da_state_blk         *blk2,
    1982             :         struct xfs_attr3_icleaf_hdr     *ichdr2,
    1983             :         int                             *countarg,
    1984             :         int                             *usedbytesarg)
    1985             : {
    1986      108622 :         struct xfs_attr_leafblock       *leaf1 = blk1->bp->b_addr;
    1987      108622 :         struct xfs_attr_leafblock       *leaf2 = blk2->bp->b_addr;
    1988      108622 :         struct xfs_attr_leaf_entry      *entry;
    1989      108622 :         int                             count;
    1990      108622 :         int                             max;
    1991      108622 :         int                             index;
    1992      108622 :         int                             totallen = 0;
    1993      108622 :         int                             half;
    1994      108622 :         int                             lastdelta;
    1995      108622 :         int                             foundit = 0;
    1996      108622 :         int                             tmp;
    1997             : 
    1998             :         /*
    1999             :          * Examine entries until we reduce the absolute difference in
    2000             :          * byte usage between the two blocks to a minimum.
    2001             :          */
    2002      108622 :         max = ichdr1->count + ichdr2->count;
    2003      108622 :         half = (max + 1) * sizeof(*entry);
    2004      217244 :         half += ichdr1->usedbytes + ichdr2->usedbytes +
    2005      108622 :                         xfs_attr_leaf_newentsize(state->args, NULL);
    2006      108622 :         half /= 2;
    2007      108622 :         lastdelta = state->args->geo->blksize;
    2008      108622 :         entry = xfs_attr3_leaf_entryp(leaf1);
    2009     3099658 :         for (count = index = 0; count < max; entry++, index++, count++) {
    2010             : 
    2011             : #define XFS_ATTR_ABS(A) (((A) < 0) ? -(A) : (A))
    2012             :                 /*
    2013             :                  * The new entry is in the first block, account for it.
    2014             :                  */
    2015     3099658 :                 if (count == blk1->index) {
    2016       51420 :                         tmp = totallen + sizeof(*entry) +
    2017       25710 :                                 xfs_attr_leaf_newentsize(state->args, NULL);
    2018       25710 :                         if (XFS_ATTR_ABS(half - tmp) > lastdelta)
    2019             :                                 break;
    2020             :                         lastdelta = XFS_ATTR_ABS(half - tmp);
    2021             :                         totallen = tmp;
    2022             :                         foundit = 1;
    2023             :                 }
    2024             : 
    2025             :                 /*
    2026             :                  * Wrap around into the second block if necessary.
    2027             :                  */
    2028     3098136 :                 if (count == ichdr1->count) {
    2029           0 :                         leaf1 = leaf2;
    2030           0 :                         entry = xfs_attr3_leaf_entryp(leaf1);
    2031             :                         index = 0;
    2032             :                 }
    2033             : 
    2034             :                 /*
    2035             :                  * Figure out if next leaf entry would be too much.
    2036             :                  */
    2037     3098136 :                 tmp = totallen + sizeof(*entry) + xfs_attr_leaf_entsize(leaf1,
    2038             :                                                                         index);
    2039     3098136 :                 if (XFS_ATTR_ABS(half - tmp) > lastdelta)
    2040             :                         break;
    2041     2991036 :                 lastdelta = XFS_ATTR_ABS(half - tmp);
    2042     2991036 :                 totallen = tmp;
    2043             : #undef XFS_ATTR_ABS
    2044             :         }
    2045             : 
    2046             :         /*
    2047             :          * Calculate the number of usedbytes that will end up in lower block.
    2048             :          * If new entry not in lower block, fix up the count.
    2049             :          */
    2050      108622 :         totallen -= count * sizeof(*entry);
    2051      108622 :         if (foundit) {
    2052       48376 :                 totallen -= sizeof(*entry) +
    2053       24188 :                                 xfs_attr_leaf_newentsize(state->args, NULL);
    2054             :         }
    2055             : 
    2056      108622 :         *countarg = count;
    2057      108622 :         *usedbytesarg = totallen;
    2058      108622 :         return foundit;
    2059             : }
    2060             : 
    2061             : /*========================================================================
    2062             :  * Routines used for shrinking the Btree.
    2063             :  *========================================================================*/
    2064             : 
    2065             : /*
    2066             :  * Check a leaf block and its neighbors to see if the block should be
    2067             :  * collapsed into one or the other neighbor.  Always keep the block
    2068             :  * with the smaller block number.
    2069             :  * If the current block is over 50% full, don't try to join it, return 0.
    2070             :  * If the block is empty, fill in the state structure and return 2.
    2071             :  * If it can be collapsed, fill in the state structure and return 1.
    2072             :  * If nothing can be done, return 0.
    2073             :  *
    2074             :  * GROT: allow for INCOMPLETE entries in calculation.
    2075             :  */
    2076             : int
    2077     2065375 : xfs_attr3_leaf_toosmall(
    2078             :         struct xfs_da_state     *state,
    2079             :         int                     *action)
    2080             : {
    2081     2065375 :         struct xfs_attr_leafblock *leaf;
    2082     2065375 :         struct xfs_da_state_blk *blk;
    2083     2065375 :         struct xfs_attr3_icleaf_hdr ichdr;
    2084     2065375 :         struct xfs_buf          *bp;
    2085     2065375 :         xfs_dablk_t             blkno;
    2086     2065375 :         int                     bytes;
    2087     2065375 :         int                     forward;
    2088     2065375 :         int                     error;
    2089     2065375 :         int                     retval;
    2090     2065375 :         int                     i;
    2091             : 
    2092     2065375 :         trace_xfs_attr_leaf_toosmall(state->args);
    2093             : 
    2094             :         /*
    2095             :          * Check for the degenerate case of the block being over 50% full.
    2096             :          * If so, it's not worth even looking to see if we might be able
    2097             :          * to coalesce with a sibling.
    2098             :          */
    2099     2065401 :         blk = &state->path.blk[ state->path.active-1 ];
    2100     2065401 :         leaf = blk->bp->b_addr;
    2101     2065401 :         xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr, leaf);
    2102     2065401 :         bytes = xfs_attr3_leaf_hdr_size(leaf) +
    2103     2065401 :                 ichdr.count * sizeof(xfs_attr_leaf_entry_t) +
    2104     2065401 :                 ichdr.usedbytes;
    2105     2065401 :         if (bytes > (state->args->geo->blksize >> 1)) {
    2106     1388977 :                 *action = 0;    /* blk over 50%, don't try to join */
    2107     1388977 :                 return 0;
    2108             :         }
    2109             : 
    2110             :         /*
    2111             :          * Check for the degenerate case of the block being empty.
    2112             :          * If the block is empty, we'll simply delete it, no need to
    2113             :          * coalesce it with a sibling block.  We choose (arbitrarily)
    2114             :          * to merge with the forward block unless it is NULL.
    2115             :          */
    2116      676424 :         if (ichdr.count == 0) {
    2117             :                 /*
    2118             :                  * Make altpath point to the block we want to keep and
    2119             :                  * path point to the block we want to drop (this one).
    2120             :                  */
    2121           0 :                 forward = (ichdr.forw != 0);
    2122           0 :                 memcpy(&state->altpath, &state->path, sizeof(state->path));
    2123           0 :                 error = xfs_da3_path_shift(state, &state->altpath, forward,
    2124             :                                                  0, &retval);
    2125           0 :                 if (error)
    2126             :                         return error;
    2127           0 :                 if (retval) {
    2128           0 :                         *action = 0;
    2129             :                 } else {
    2130           0 :                         *action = 2;
    2131             :                 }
    2132           0 :                 return 0;
    2133             :         }
    2134             : 
    2135             :         /*
    2136             :          * Examine each sibling block to see if we can coalesce with
    2137             :          * at least 25% free space to spare.  We need to figure out
    2138             :          * whether to merge with the forward or the backward block.
    2139             :          * We prefer coalescing with the lower numbered sibling so as
    2140             :          * to shrink an attribute list over time.
    2141             :          */
    2142             :         /* start with smaller blk num */
    2143      676424 :         forward = ichdr.forw < ichdr.back;
    2144     2027018 :         for (i = 0; i < 2; forward = !forward, i++) {
    2145     1352069 :                 struct xfs_attr3_icleaf_hdr ichdr2;
    2146     1352069 :                 if (forward)
    2147             :                         blkno = ichdr.forw;
    2148             :                 else
    2149      676376 :                         blkno = ichdr.back;
    2150     1352069 :                 if (blkno == 0)
    2151      620124 :                         continue;
    2152      731945 :                 error = xfs_attr3_leaf_read(state->args->trans, state->args->dp,
    2153             :                                         state->args->owner, blkno, &bp);
    2154      731945 :                 if (error)
    2155           2 :                         return error;
    2156             : 
    2157      731943 :                 xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr2, bp->b_addr);
    2158             : 
    2159     1463886 :                 bytes = state->args->geo->blksize -
    2160      731943 :                         (state->args->geo->blksize >> 2) -
    2161      731943 :                         ichdr.usedbytes - ichdr2.usedbytes -
    2162      731943 :                         ((ichdr.count + ichdr2.count) *
    2163      731943 :                                         sizeof(xfs_attr_leaf_entry_t)) -
    2164      731943 :                         xfs_attr3_leaf_hdr_size(leaf);
    2165             : 
    2166      731943 :                 xfs_trans_brelse(state->args->trans, bp);
    2167      731943 :                 if (bytes >= 0)
    2168             :                         break;  /* fits with at least 25% to spare */
    2169             :         }
    2170      676422 :         if (i >= 2) {
    2171      674949 :                 *action = 0;
    2172      674949 :                 return 0;
    2173             :         }
    2174             : 
    2175             :         /*
    2176             :          * Make altpath point to the block we want to keep (the lower
    2177             :          * numbered block) and path point to the block we want to drop.
    2178             :          */
    2179        2946 :         memcpy(&state->altpath, &state->path, sizeof(state->path));
    2180        1473 :         if (blkno < blk->blkno) {
    2181         809 :                 error = xfs_da3_path_shift(state, &state->altpath, forward,
    2182             :                                                  0, &retval);
    2183             :         } else {
    2184         664 :                 error = xfs_da3_path_shift(state, &state->path, forward,
    2185             :                                                  0, &retval);
    2186             :         }
    2187        1473 :         if (error)
    2188             :                 return error;
    2189        1473 :         if (retval) {
    2190           0 :                 *action = 0;
    2191             :         } else {
    2192        1473 :                 *action = 1;
    2193             :         }
    2194             :         return 0;
    2195             : }
    2196             : 
    2197             : /*
    2198             :  * Remove a name from the leaf attribute list structure.
    2199             :  *
    2200             :  * Return 1 if leaf is less than 37% full, 0 if >= 37% full.
    2201             :  * If two leaves are 37% full, when combined they will leave 25% free.
    2202             :  */
    2203             : int
    2204    97096857 : xfs_attr3_leaf_remove(
    2205             :         struct xfs_buf          *bp,
    2206             :         struct xfs_da_args      *args)
    2207             : {
    2208    97096857 :         struct xfs_attr_leafblock *leaf;
    2209    97096857 :         struct xfs_attr3_icleaf_hdr ichdr;
    2210    97096857 :         struct xfs_attr_leaf_entry *entry;
    2211    97096857 :         int                     before;
    2212    97096857 :         int                     after;
    2213    97096857 :         int                     smallest;
    2214    97096857 :         int                     entsize;
    2215    97096857 :         int                     tablesize;
    2216    97096857 :         int                     tmp;
    2217    97096857 :         int                     i;
    2218             : 
    2219    97096857 :         trace_xfs_attr_leaf_remove(args);
    2220             : 
    2221    97098760 :         leaf = bp->b_addr;
    2222    97098760 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    2223             : 
    2224    97099468 :         ASSERT(ichdr.count > 0 && ichdr.count < args->geo->blksize / 8);
    2225    97099468 :         ASSERT(args->index >= 0 && args->index < ichdr.count);
    2226   194198904 :         ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) +
    2227             :                                         xfs_attr3_leaf_hdr_size(leaf));
    2228             : 
    2229    97099468 :         entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
    2230             : 
    2231    97099468 :         ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
    2232    97099468 :         ASSERT(be16_to_cpu(entry->nameidx) < args->geo->blksize);
    2233             : 
    2234             :         /*
    2235             :          * Scan through free region table:
    2236             :          *    check for adjacency of free'd entry with an existing one,
    2237             :          *    find smallest free region in case we need to replace it,
    2238             :          *    adjust any map that borders the entry table,
    2239             :          */
    2240    97099468 :         tablesize = ichdr.count * sizeof(xfs_attr_leaf_entry_t)
    2241    97099468 :                                         + xfs_attr3_leaf_hdr_size(leaf);
    2242    97099468 :         tmp = ichdr.freemap[0].size;
    2243    97099468 :         before = after = -1;
    2244    97099468 :         smallest = XFS_ATTR_LEAF_MAPSIZE - 1;
    2245    97099468 :         entsize = xfs_attr_leaf_entsize(leaf, args->index);
    2246   388381059 :         for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
    2247   291281435 :                 ASSERT(ichdr.freemap[i].base < args->geo->blksize);
    2248   291281435 :                 ASSERT(ichdr.freemap[i].size < args->geo->blksize);
    2249   291281591 :                 if (ichdr.freemap[i].base == tablesize) {
    2250    96950167 :                         ichdr.freemap[i].base -= sizeof(xfs_attr_leaf_entry_t);
    2251    96950167 :                         ichdr.freemap[i].size += sizeof(xfs_attr_leaf_entry_t);
    2252             :                 }
    2253             : 
    2254   291281591 :                 if (ichdr.freemap[i].base + ichdr.freemap[i].size ==
    2255   291281591 :                                 be16_to_cpu(entry->nameidx)) {
    2256             :                         before = i;
    2257   276000896 :                 } else if (ichdr.freemap[i].base ==
    2258   276000896 :                                 (be16_to_cpu(entry->nameidx) + entsize)) {
    2259             :                         after = i;
    2260   266583973 :                 } else if (ichdr.freemap[i].size < tmp) {
    2261   138135999 :                         tmp = ichdr.freemap[i].size;
    2262   138135999 :                         smallest = i;
    2263             :                 }
    2264             :         }
    2265             : 
    2266             :         /*
    2267             :          * Coalesce adjacent freemap regions,
    2268             :          * or replace the smallest region.
    2269             :          */
    2270    97099624 :         if ((before >= 0) || (after >= 0)) {
    2271    23473962 :                 if ((before >= 0) && (after >= 0)) {
    2272     1239661 :                         ichdr.freemap[before].size += entsize;
    2273     1239661 :                         ichdr.freemap[before].size += ichdr.freemap[after].size;
    2274     1239661 :                         ichdr.freemap[after].base = 0;
    2275     1239661 :                         ichdr.freemap[after].size = 0;
    2276    22234301 :                 } else if (before >= 0) {
    2277    14057112 :                         ichdr.freemap[before].size += entsize;
    2278             :                 } else {
    2279     8177189 :                         ichdr.freemap[after].base = be16_to_cpu(entry->nameidx);
    2280     8177189 :                         ichdr.freemap[after].size += entsize;
    2281             :                 }
    2282             :         } else {
    2283             :                 /*
    2284             :                  * Replace smallest region (if it is smaller than free'd entry)
    2285             :                  */
    2286    73625662 :                 if (ichdr.freemap[smallest].size < entsize) {
    2287    60447066 :                         ichdr.freemap[smallest].base = be16_to_cpu(entry->nameidx);
    2288    60447066 :                         ichdr.freemap[smallest].size = entsize;
    2289             :                 }
    2290             :         }
    2291             : 
    2292             :         /*
    2293             :          * Did we remove the first entry?
    2294             :          */
    2295    97099624 :         if (be16_to_cpu(entry->nameidx) == ichdr.firstused)
    2296             :                 smallest = 1;
    2297             :         else
    2298    90625811 :                 smallest = 0;
    2299             : 
    2300             :         /*
    2301             :          * Compress the remaining entries and zero out the removed stuff.
    2302             :          */
    2303    97099624 :         memset(xfs_attr3_leaf_name(leaf, args->index), 0, entsize);
    2304    97099624 :         ichdr.usedbytes -= entsize;
    2305    97099624 :         xfs_trans_log_buf(args->trans, bp,
    2306    97099624 :              XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index),
    2307             :                                    entsize));
    2308             : 
    2309    97095891 :         tmp = (ichdr.count - args->index) * sizeof(xfs_attr_leaf_entry_t);
    2310   194191782 :         memmove(entry, entry + 1, tmp);
    2311    97095891 :         ichdr.count--;
    2312    97095891 :         xfs_trans_log_buf(args->trans, bp,
    2313    97095891 :             XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(xfs_attr_leaf_entry_t)));
    2314             : 
    2315    97098017 :         entry = &xfs_attr3_leaf_entryp(leaf)[ichdr.count];
    2316    97098017 :         memset(entry, 0, sizeof(xfs_attr_leaf_entry_t));
    2317             : 
    2318             :         /*
    2319             :          * If we removed the first entry, re-find the first used byte
    2320             :          * in the name area.  Note that if the entry was the "firstused",
    2321             :          * then we don't have a "hole" in our block resulting from
    2322             :          * removing the name.
    2323             :          */
    2324    97098017 :         if (smallest) {
    2325     6473504 :                 tmp = args->geo->blksize;
    2326     6473504 :                 entry = xfs_attr3_leaf_entryp(leaf);
    2327    88209025 :                 for (i = ichdr.count - 1; i >= 0; entry++, i--) {
    2328    81735536 :                         ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
    2329    81735536 :                         ASSERT(be16_to_cpu(entry->nameidx) < args->geo->blksize);
    2330             : 
    2331    81735521 :                         if (be16_to_cpu(entry->nameidx) < tmp)
    2332             :                                 tmp = be16_to_cpu(entry->nameidx);
    2333             :                 }
    2334     6473489 :                 ichdr.firstused = tmp;
    2335     6473489 :                 ASSERT(ichdr.firstused != 0);
    2336             :         } else {
    2337    90624513 :                 ichdr.holes = 1;        /* mark as needing compaction */
    2338             :         }
    2339    97098002 :         xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr);
    2340    97099534 :         xfs_trans_log_buf(args->trans, bp,
    2341    97099534 :                           XFS_DA_LOGRANGE(leaf, &leaf->hdr,
    2342             :                                           xfs_attr3_leaf_hdr_size(leaf)));
    2343             : 
    2344             :         /*
    2345             :          * Check if leaf is less than 50% full, caller may want to
    2346             :          * "join" the leaf with a sibling if so.
    2347             :          */
    2348    97098718 :         tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) +
    2349    97098718 :               ichdr.count * sizeof(xfs_attr_leaf_entry_t);
    2350             : 
    2351    97098718 :         return tmp < args->geo->magicpct; /* leaf is < 37% full */
    2352             : }
    2353             : 
    2354             : /*
    2355             :  * Move all the attribute list entries from drop_leaf into save_leaf.
    2356             :  */
    2357             : void
    2358        1473 : xfs_attr3_leaf_unbalance(
    2359             :         struct xfs_da_state     *state,
    2360             :         struct xfs_da_state_blk *drop_blk,
    2361             :         struct xfs_da_state_blk *save_blk)
    2362             : {
    2363        1473 :         struct xfs_attr_leafblock *drop_leaf = drop_blk->bp->b_addr;
    2364        1473 :         struct xfs_attr_leafblock *save_leaf = save_blk->bp->b_addr;
    2365        1473 :         struct xfs_attr3_icleaf_hdr drophdr;
    2366        1473 :         struct xfs_attr3_icleaf_hdr savehdr;
    2367        1473 :         struct xfs_attr_leaf_entry *entry;
    2368             : 
    2369        1473 :         trace_xfs_attr_leaf_unbalance(state->args);
    2370             : 
    2371        1473 :         xfs_attr3_leaf_hdr_from_disk(state->args->geo, &drophdr, drop_leaf);
    2372        1473 :         xfs_attr3_leaf_hdr_from_disk(state->args->geo, &savehdr, save_leaf);
    2373        1473 :         entry = xfs_attr3_leaf_entryp(drop_leaf);
    2374             : 
    2375             :         /*
    2376             :          * Save last hashval from dying block for later Btree fixup.
    2377             :          */
    2378        1473 :         drop_blk->hashval = be32_to_cpu(entry[drophdr.count - 1].hashval);
    2379             : 
    2380             :         /*
    2381             :          * Check if we need a temp buffer, or can we do it in place.
    2382             :          * Note that we don't check "leaf" for holes because we will
    2383             :          * always be dropping it, toosmall() decided that for us already.
    2384             :          */
    2385        1473 :         if (savehdr.holes == 0) {
    2386             :                 /*
    2387             :                  * dest leaf has no holes, so we add there.  May need
    2388             :                  * to make some room in the entry array.
    2389             :                  */
    2390           2 :                 if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
    2391             :                                          drop_blk->bp, &drophdr)) {
    2392           1 :                         xfs_attr3_leaf_moveents(state->args,
    2393             :                                                 drop_leaf, &drophdr, 0,
    2394             :                                                 save_leaf, &savehdr, 0,
    2395             :                                                 drophdr.count);
    2396             :                 } else {
    2397           1 :                         xfs_attr3_leaf_moveents(state->args,
    2398             :                                                 drop_leaf, &drophdr, 0,
    2399             :                                                 save_leaf, &savehdr,
    2400           1 :                                                 savehdr.count, drophdr.count);
    2401             :                 }
    2402             :         } else {
    2403             :                 /*
    2404             :                  * Destination has holes, so we make a temporary copy
    2405             :                  * of the leaf and add them both to that.
    2406             :                  */
    2407        1471 :                 struct xfs_attr_leafblock *tmp_leaf;
    2408        1471 :                 struct xfs_attr3_icleaf_hdr tmphdr;
    2409             : 
    2410        1471 :                 tmp_leaf = kmem_zalloc(state->args->geo->blksize, 0);
    2411             : 
    2412             :                 /*
    2413             :                  * Copy the header into the temp leaf so that all the stuff
    2414             :                  * not in the incore header is present and gets copied back in
    2415             :                  * once we've moved all the entries.
    2416             :                  */
    2417        4413 :                 memcpy(tmp_leaf, save_leaf, xfs_attr3_leaf_hdr_size(save_leaf));
    2418             : 
    2419        1471 :                 memset(&tmphdr, 0, sizeof(tmphdr));
    2420        1471 :                 tmphdr.magic = savehdr.magic;
    2421        1471 :                 tmphdr.forw = savehdr.forw;
    2422        1471 :                 tmphdr.back = savehdr.back;
    2423        1471 :                 tmphdr.firstused = state->args->geo->blksize;
    2424             : 
    2425             :                 /* write the header to the temp buffer to initialise it */
    2426        1471 :                 xfs_attr3_leaf_hdr_to_disk(state->args->geo, tmp_leaf, &tmphdr);
    2427             : 
    2428        1471 :                 if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
    2429             :                                          drop_blk->bp, &drophdr)) {
    2430         122 :                         xfs_attr3_leaf_moveents(state->args,
    2431             :                                                 drop_leaf, &drophdr, 0,
    2432             :                                                 tmp_leaf, &tmphdr, 0,
    2433         122 :                                                 drophdr.count);
    2434         122 :                         xfs_attr3_leaf_moveents(state->args,
    2435             :                                                 save_leaf, &savehdr, 0,
    2436         122 :                                                 tmp_leaf, &tmphdr, tmphdr.count,
    2437         122 :                                                 savehdr.count);
    2438             :                 } else {
    2439        1349 :                         xfs_attr3_leaf_moveents(state->args,
    2440             :                                                 save_leaf, &savehdr, 0,
    2441             :                                                 tmp_leaf, &tmphdr, 0,
    2442        1349 :                                                 savehdr.count);
    2443        1349 :                         xfs_attr3_leaf_moveents(state->args,
    2444             :                                                 drop_leaf, &drophdr, 0,
    2445        1349 :                                                 tmp_leaf, &tmphdr, tmphdr.count,
    2446        1349 :                                                 drophdr.count);
    2447             :                 }
    2448        2942 :                 memcpy(save_leaf, tmp_leaf, state->args->geo->blksize);
    2449        1471 :                 savehdr = tmphdr; /* struct copy */
    2450        1471 :                 kmem_free(tmp_leaf);
    2451             :         }
    2452             : 
    2453        1473 :         xfs_attr3_leaf_hdr_to_disk(state->args->geo, save_leaf, &savehdr);
    2454        1473 :         xfs_trans_log_buf(state->args->trans, save_blk->bp, 0,
    2455        1473 :                                            state->args->geo->blksize - 1);
    2456             : 
    2457             :         /*
    2458             :          * Copy out last hashval in each block for B-tree code.
    2459             :          */
    2460        1473 :         entry = xfs_attr3_leaf_entryp(save_leaf);
    2461        1473 :         save_blk->hashval = be32_to_cpu(entry[savehdr.count - 1].hashval);
    2462        1473 : }
    2463             : 
    2464             : /*========================================================================
    2465             :  * Routines used for finding things in the Btree.
    2466             :  *========================================================================*/
    2467             : 
    2468             : /*
    2469             :  * Look up a name in a leaf attribute list structure.
    2470             :  * This is the internal routine, it uses the caller's buffer.
    2471             :  *
    2472             :  * Note that duplicate keys are allowed, but only check within the
    2473             :  * current leaf node.  The Btree code must check in adjacent leaf nodes.
    2474             :  *
    2475             :  * Return in args->index the index into the entry[] array of either
    2476             :  * the found entry, or where the entry should have been (insert before
    2477             :  * that entry).
    2478             :  *
    2479             :  * Don't change the args->value unless we find the attribute.
    2480             :  */
    2481             : int
    2482   847145574 : xfs_attr3_leaf_lookup_int(
    2483             :         struct xfs_buf          *bp,
    2484             :         struct xfs_da_args      *args)
    2485             : {
    2486   847145574 :         struct xfs_attr_leafblock *leaf;
    2487   847145574 :         struct xfs_attr3_icleaf_hdr ichdr;
    2488   847145574 :         struct xfs_attr_leaf_entry *entry;
    2489   847145574 :         struct xfs_attr_leaf_entry *entries;
    2490   847145574 :         struct xfs_attr_leaf_name_local *name_loc;
    2491   847145574 :         struct xfs_attr_leaf_name_remote *name_rmt;
    2492   847145574 :         xfs_dahash_t            hashval;
    2493   847145574 :         int                     probe;
    2494   847145574 :         int                     span;
    2495             : 
    2496   847145574 :         trace_xfs_attr_leaf_lookup(args);
    2497             : 
    2498   847213079 :         leaf = bp->b_addr;
    2499   847213079 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    2500   847651182 :         entries = xfs_attr3_leaf_entryp(leaf);
    2501   847651182 :         if (ichdr.count >= args->geo->blksize / 8) {
    2502           0 :                 xfs_buf_mark_corrupt(bp);
    2503           0 :                 xfs_da_mark_sick(args);
    2504           0 :                 return -EFSCORRUPTED;
    2505             :         }
    2506             : 
    2507             :         /*
    2508             :          * Binary search.  (note: small blocks will skip this loop)
    2509             :          */
    2510   847651182 :         hashval = args->hashval;
    2511   847651182 :         probe = span = ichdr.count / 2;
    2512  1431132070 :         for (entry = &entries[probe]; span > 4; entry = &entries[probe]) {
    2513   869205715 :                 span /= 2;
    2514  1738411430 :                 if (be32_to_cpu(entry->hashval) < hashval)
    2515   361041509 :                         probe += span;
    2516   508164206 :                 else if (be32_to_cpu(entry->hashval) > hashval)
    2517   222439379 :                         probe -= span;
    2518             :                 else
    2519             :                         break;
    2520             :         }
    2521   847651182 :         if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count))) {
    2522           0 :                 xfs_buf_mark_corrupt(bp);
    2523           0 :                 xfs_da_mark_sick(args);
    2524           0 :                 return -EFSCORRUPTED;
    2525             :         }
    2526   851415217 :         if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval)) {
    2527           0 :                 xfs_buf_mark_corrupt(bp);
    2528           0 :                 xfs_da_mark_sick(args);
    2529           0 :                 return -EFSCORRUPTED;
    2530             :         }
    2531             : 
    2532             :         /*
    2533             :          * Since we may have duplicate hashval's, find the first matching
    2534             :          * hashval in the leaf.
    2535             :          */
    2536  6869682523 :         while (probe > 0 && be32_to_cpu(entry->hashval) >= hashval) {
    2537  2776739148 :                 entry--;
    2538  2776739148 :                 probe--;
    2539             :         }
    2540  3650206228 :         while (probe < ichdr.count &&
    2541  1811905578 :                be32_to_cpu(entry->hashval) < hashval) {
    2542   990649468 :                 entry++;
    2543   990649468 :                 probe++;
    2544             :         }
    2545  1668954417 :         if (probe == ichdr.count || be32_to_cpu(entry->hashval) != hashval) {
    2546   330691218 :                 args->index = probe;
    2547   330691218 :                 return -ENOATTR;
    2548             :         }
    2549             : 
    2550             :         /*
    2551             :          * Duplicate keys may be present, so search all of them for a match.
    2552             :          */
    2553  9871193268 :         for (; probe < ichdr.count && (be32_to_cpu(entry->hashval) == hashval);
    2554  4569733190 :                         entry++, probe++) {
    2555             : /*
    2556             :  * GROT: Add code to remove incomplete entries.
    2557             :  */
    2558  4784297109 :                 if (entry->flags & XFS_ATTR_LOCAL) {
    2559  4784296525 :                         name_loc = xfs_attr3_leaf_name_local(leaf, probe);
    2560  9568612918 :                         if (!xfs_attr_match(args, name_loc->namelen,
    2561  4784296525 :                                         name_loc->nameval,
    2562  4784296525 :                                         be16_to_cpu(name_loc->valuelen),
    2563  4784296525 :                                         &name_loc->nameval[name_loc->namelen],
    2564             :                                         entry->flags))
    2565  4569733188 :                                 continue;
    2566   214583205 :                         args->index = probe;
    2567   214583205 :                         return -EEXIST;
    2568             :                 } else {
    2569         584 :                         name_rmt = xfs_attr3_leaf_name_remote(leaf, probe);
    2570         584 :                         if (!xfs_attr_match(args, name_rmt->namelen,
    2571         584 :                                         name_rmt->name, 0, NULL, entry->flags))
    2572           2 :                                 continue;
    2573         582 :                         args->index = probe;
    2574         582 :                         args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
    2575         582 :                         args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
    2576        1164 :                         args->rmtblkcnt = xfs_attr3_rmt_blocks(
    2577         582 :                                                         args->dp->i_mount,
    2578             :                                                         args->rmtvaluelen);
    2579         582 :                         return -EEXIST;
    2580             :                 }
    2581             :         }
    2582   302396045 :         args->index = probe;
    2583   302396045 :         return -ENOATTR;
    2584             : }
    2585             : 
    2586             : /*
    2587             :  * Get the value associated with an attribute name from a leaf attribute
    2588             :  * list structure.
    2589             :  *
    2590             :  * If args->valuelen is zero, only the length needs to be returned.  Unlike a
    2591             :  * lookup, we only return an error if the attribute does not exist or we can't
    2592             :  * retrieve the value.
    2593             :  */
    2594             : int
    2595    20911262 : xfs_attr3_leaf_getvalue(
    2596             :         struct xfs_buf          *bp,
    2597             :         struct xfs_da_args      *args)
    2598             : {
    2599    20911262 :         struct xfs_attr_leafblock *leaf;
    2600    20911262 :         struct xfs_attr3_icleaf_hdr ichdr;
    2601    20911262 :         struct xfs_attr_leaf_entry *entry;
    2602    20911262 :         struct xfs_attr_leaf_name_local *name_loc;
    2603    20911262 :         struct xfs_attr_leaf_name_remote *name_rmt;
    2604             : 
    2605    20911262 :         leaf = bp->b_addr;
    2606    20911262 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    2607    20912134 :         ASSERT(ichdr.count < args->geo->blksize / 8);
    2608    20912134 :         ASSERT(args->index < ichdr.count);
    2609             : 
    2610    20912134 :         entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
    2611    20912134 :         if (entry->flags & XFS_ATTR_LOCAL) {
    2612    20911467 :                 name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
    2613    20911467 :                 ASSERT(name_loc->namelen == args->namelen);
    2614    41822934 :                 ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0);
    2615    20911467 :                 return xfs_attr_copy_value(args,
    2616    20911467 :                                         &name_loc->nameval[args->namelen],
    2617    20911467 :                                         be16_to_cpu(name_loc->valuelen));
    2618             :         }
    2619             : 
    2620         667 :         name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
    2621         667 :         ASSERT(name_rmt->namelen == args->namelen);
    2622        1334 :         ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0);
    2623         667 :         args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
    2624         667 :         args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
    2625         667 :         args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount,
    2626             :                                                args->rmtvaluelen);
    2627         667 :         return xfs_attr_copy_value(args, NULL, args->rmtvaluelen);
    2628             : }
    2629             : 
    2630             : /*========================================================================
    2631             :  * Utility routines.
    2632             :  *========================================================================*/
    2633             : 
    2634             : /*
    2635             :  * Move the indicated entries from one leaf to another.
    2636             :  * NOTE: this routine modifies both source and destination leaves.
    2637             :  */
    2638             : /*ARGSUSED*/
    2639             : STATIC void
    2640      741641 : xfs_attr3_leaf_moveents(
    2641             :         struct xfs_da_args              *args,
    2642             :         struct xfs_attr_leafblock       *leaf_s,
    2643             :         struct xfs_attr3_icleaf_hdr     *ichdr_s,
    2644             :         int                             start_s,
    2645             :         struct xfs_attr_leafblock       *leaf_d,
    2646             :         struct xfs_attr3_icleaf_hdr     *ichdr_d,
    2647             :         int                             start_d,
    2648             :         int                             count)
    2649             : {
    2650      741641 :         struct xfs_attr_leaf_entry      *entry_s;
    2651      741641 :         struct xfs_attr_leaf_entry      *entry_d;
    2652      741641 :         int                             desti;
    2653      741641 :         int                             tmp;
    2654      741641 :         int                             i;
    2655             : 
    2656             :         /*
    2657             :          * Check for nothing to do.
    2658             :          */
    2659      741641 :         if (count == 0)
    2660             :                 return;
    2661             : 
    2662             :         /*
    2663             :          * Set up environment.
    2664             :          */
    2665      741641 :         ASSERT(ichdr_s->magic == XFS_ATTR_LEAF_MAGIC ||
    2666             :                ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC);
    2667      741641 :         ASSERT(ichdr_s->magic == ichdr_d->magic);
    2668      741641 :         ASSERT(ichdr_s->count > 0 && ichdr_s->count < args->geo->blksize / 8);
    2669     1483278 :         ASSERT(ichdr_s->firstused >= (ichdr_s->count * sizeof(*entry_s))
    2670             :                                         + xfs_attr3_leaf_hdr_size(leaf_s));
    2671      741641 :         ASSERT(ichdr_d->count < args->geo->blksize / 8);
    2672     1483282 :         ASSERT(ichdr_d->firstused >= (ichdr_d->count * sizeof(*entry_d))
    2673             :                                         + xfs_attr3_leaf_hdr_size(leaf_d));
    2674             : 
    2675      741641 :         ASSERT(start_s < ichdr_s->count);
    2676      741641 :         ASSERT(start_d <= ichdr_d->count);
    2677      741641 :         ASSERT(count <= ichdr_s->count);
    2678             : 
    2679             : 
    2680             :         /*
    2681             :          * Move the entries in the destination leaf up to make a hole?
    2682             :          */
    2683      741641 :         if (start_d < ichdr_d->count) {
    2684           1 :                 tmp  = ichdr_d->count - start_d;
    2685           1 :                 tmp *= sizeof(xfs_attr_leaf_entry_t);
    2686           1 :                 entry_s = &xfs_attr3_leaf_entryp(leaf_d)[start_d];
    2687           1 :                 entry_d = &xfs_attr3_leaf_entryp(leaf_d)[start_d + count];
    2688           2 :                 memmove(entry_d, entry_s, tmp);
    2689             :         }
    2690             : 
    2691             :         /*
    2692             :          * Copy all entry's in the same (sorted) order,
    2693             :          * but allocate attribute info packed and in sequence.
    2694             :          */
    2695      741641 :         entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
    2696      741641 :         entry_d = &xfs_attr3_leaf_entryp(leaf_d)[start_d];
    2697      741641 :         desti = start_d;
    2698    34407427 :         for (i = 0; i < count; entry_s++, entry_d++, desti++, i++) {
    2699    33665784 :                 ASSERT(be16_to_cpu(entry_s->nameidx) >= ichdr_s->firstused);
    2700    33665784 :                 tmp = xfs_attr_leaf_entsize(leaf_s, start_s + i);
    2701             : #ifdef GROT
    2702             :                 /*
    2703             :                  * Code to drop INCOMPLETE entries.  Difficult to use as we
    2704             :                  * may also need to change the insertion index.  Code turned
    2705             :                  * off for 6.2, should be revisited later.
    2706             :                  */
    2707             :                 if (entry_s->flags & XFS_ATTR_INCOMPLETE) { /* skip partials? */
    2708             :                         memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp);
    2709             :                         ichdr_s->usedbytes -= tmp;
    2710             :                         ichdr_s->count -= 1;
    2711             :                         entry_d--;      /* to compensate for ++ in loop hdr */
    2712             :                         desti--;
    2713             :                         if ((start_s + i) < offset)
    2714             :                                 result++;       /* insertion index adjustment */
    2715             :                 } else {
    2716             : #endif /* GROT */
    2717    33665784 :                         ichdr_d->firstused -= tmp;
    2718             :                         /* both on-disk, don't endian flip twice */
    2719    33665784 :                         entry_d->hashval = entry_s->hashval;
    2720    33665784 :                         entry_d->nameidx = cpu_to_be16(ichdr_d->firstused);
    2721    33665784 :                         entry_d->flags = entry_s->flags;
    2722    33665784 :                         ASSERT(be16_to_cpu(entry_d->nameidx) + tmp
    2723             :                                                         <= args->geo->blksize);
    2724    33665784 :                         memmove(xfs_attr3_leaf_name(leaf_d, desti),
    2725             :                                 xfs_attr3_leaf_name(leaf_s, start_s + i), tmp);
    2726    33665784 :                         ASSERT(be16_to_cpu(entry_s->nameidx) + tmp
    2727             :                                                         <= args->geo->blksize);
    2728    33665784 :                         memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp);
    2729    33665784 :                         ichdr_s->usedbytes -= tmp;
    2730    33665784 :                         ichdr_d->usedbytes += tmp;
    2731    33665784 :                         ichdr_s->count -= 1;
    2732    33665784 :                         ichdr_d->count += 1;
    2733    33665784 :                         tmp = ichdr_d->count * sizeof(xfs_attr_leaf_entry_t)
    2734    33665784 :                                         + xfs_attr3_leaf_hdr_size(leaf_d);
    2735    33665784 :                         ASSERT(ichdr_d->firstused >= tmp);
    2736             : #ifdef GROT
    2737             :                 }
    2738             : #endif /* GROT */
    2739             :         }
    2740             : 
    2741             :         /*
    2742             :          * Zero out the entries we just copied.
    2743             :          */
    2744      741643 :         if (start_s == ichdr_s->count) {
    2745      741643 :                 tmp = count * sizeof(xfs_attr_leaf_entry_t);
    2746      741643 :                 entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
    2747      741643 :                 ASSERT(((char *)entry_s + tmp) <=
    2748             :                        ((char *)leaf_s + args->geo->blksize));
    2749     1483286 :                 memset(entry_s, 0, tmp);
    2750             :         } else {
    2751             :                 /*
    2752             :                  * Move the remaining entries down to fill the hole,
    2753             :                  * then zero the entries at the top.
    2754             :                  */
    2755           0 :                 tmp  = (ichdr_s->count - count) * sizeof(xfs_attr_leaf_entry_t);
    2756           0 :                 entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s + count];
    2757           0 :                 entry_d = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
    2758           0 :                 memmove(entry_d, entry_s, tmp);
    2759             : 
    2760           0 :                 tmp = count * sizeof(xfs_attr_leaf_entry_t);
    2761           0 :                 entry_s = &xfs_attr3_leaf_entryp(leaf_s)[ichdr_s->count];
    2762           0 :                 ASSERT(((char *)entry_s + tmp) <=
    2763             :                        ((char *)leaf_s + args->geo->blksize));
    2764           0 :                 memset(entry_s, 0, tmp);
    2765             :         }
    2766             : 
    2767             :         /*
    2768             :          * Fill in the freemap information
    2769             :          */
    2770      741643 :         ichdr_d->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_d);
    2771      741643 :         ichdr_d->freemap[0].base += ichdr_d->count * sizeof(xfs_attr_leaf_entry_t);
    2772      741643 :         ichdr_d->freemap[0].size = ichdr_d->firstused - ichdr_d->freemap[0].base;
    2773      741643 :         ichdr_d->freemap[1].base = 0;
    2774      741643 :         ichdr_d->freemap[2].base = 0;
    2775      741643 :         ichdr_d->freemap[1].size = 0;
    2776      741643 :         ichdr_d->freemap[2].size = 0;
    2777      741643 :         ichdr_s->holes = 1;  /* leaf may not be compact */
    2778             : }
    2779             : 
    2780             : /*
    2781             :  * Pick up the last hashvalue from a leaf block.
    2782             :  */
    2783             : xfs_dahash_t
    2784   322765552 : xfs_attr_leaf_lasthash(
    2785             :         struct xfs_buf  *bp,
    2786             :         int             *count)
    2787             : {
    2788   322765552 :         struct xfs_attr3_icleaf_hdr ichdr;
    2789   322765552 :         struct xfs_attr_leaf_entry *entries;
    2790   322765552 :         struct xfs_mount *mp = bp->b_mount;
    2791             : 
    2792   322765552 :         xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, bp->b_addr);
    2793   322765811 :         entries = xfs_attr3_leaf_entryp(bp->b_addr);
    2794   322765811 :         if (count)
    2795     7510849 :                 *count = ichdr.count;
    2796   322765811 :         if (!ichdr.count)
    2797             :                 return 0;
    2798   322765805 :         return be32_to_cpu(entries[ichdr.count - 1].hashval);
    2799             : }
    2800             : 
    2801             : /*
    2802             :  * Calculate the number of bytes used to store the indicated attribute
    2803             :  * (whether local or remote only calculate bytes in this block).
    2804             :  */
    2805             : STATIC int
    2806   531550554 : xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
    2807             : {
    2808   531550554 :         struct xfs_attr_leaf_entry *entries;
    2809   531550554 :         xfs_attr_leaf_name_local_t *name_loc;
    2810   531550554 :         xfs_attr_leaf_name_remote_t *name_rmt;
    2811   531550554 :         int size;
    2812             : 
    2813   531550554 :         entries = xfs_attr3_leaf_entryp(leaf);
    2814   531550554 :         if (entries[index].flags & XFS_ATTR_LOCAL) {
    2815   531549368 :                 name_loc = xfs_attr3_leaf_name_local(leaf, index);
    2816   531549368 :                 size = xfs_attr_leaf_entsize_local(name_loc->namelen,
    2817   531549368 :                                                    be16_to_cpu(name_loc->valuelen));
    2818             :         } else {
    2819        1186 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf, index);
    2820        1186 :                 size = xfs_attr_leaf_entsize_remote(name_rmt->namelen);
    2821             :         }
    2822   531550554 :         return size;
    2823             : }
    2824             : 
    2825             : /*
    2826             :  * Calculate the number of bytes that would be required to store the new
    2827             :  * attribute (whether local or remote only calculate bytes in this block).
    2828             :  * This routine decides as a side effect whether the attribute will be
    2829             :  * a "local" or a "remote" attribute.
    2830             :  */
    2831             : int
    2832   831432342 : xfs_attr_leaf_newentsize(
    2833             :         struct xfs_da_args      *args,
    2834             :         int                     *local)
    2835             : {
    2836   831432342 :         int                     size;
    2837             : 
    2838   831432342 :         size = xfs_attr_leaf_entsize_local(args->namelen, args->valuelen);
    2839   831432342 :         if (size < xfs_attr_leaf_entsize_local_max(args->geo->blksize)) {
    2840   831429872 :                 if (local)
    2841   433336676 :                         *local = 1;
    2842   831429872 :                 return size;
    2843             :         }
    2844        2470 :         if (local)
    2845        1300 :                 *local = 0;
    2846        2470 :         return xfs_attr_leaf_entsize_remote(args->namelen);
    2847             : }
    2848             : 
    2849             : 
    2850             : /*========================================================================
    2851             :  * Manage the INCOMPLETE flag in a leaf entry
    2852             :  *========================================================================*/
    2853             : 
    2854             : /*
    2855             :  * Clear the INCOMPLETE flag on an entry in a leaf block.
    2856             :  */
    2857             : int
    2858         583 : xfs_attr3_leaf_clearflag(
    2859             :         struct xfs_da_args      *args)
    2860             : {
    2861         583 :         struct xfs_attr_leafblock *leaf;
    2862         583 :         struct xfs_attr_leaf_entry *entry;
    2863         583 :         struct xfs_attr_leaf_name_remote *name_rmt;
    2864         583 :         struct xfs_buf          *bp;
    2865         583 :         int                     error;
    2866             : #ifdef DEBUG
    2867         583 :         struct xfs_attr3_icleaf_hdr ichdr;
    2868         583 :         xfs_attr_leaf_name_local_t *name_loc;
    2869         583 :         int namelen;
    2870         583 :         char *name;
    2871             : #endif /* DEBUG */
    2872             : 
    2873         583 :         trace_xfs_attr_leaf_clearflag(args);
    2874             :         /*
    2875             :          * Set up the operation.
    2876             :          */
    2877         583 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
    2878             :                         args->blkno, &bp);
    2879         583 :         if (error)
    2880             :                 return error;
    2881             : 
    2882         583 :         leaf = bp->b_addr;
    2883         583 :         entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
    2884         583 :         ASSERT(entry->flags & XFS_ATTR_INCOMPLETE);
    2885             : 
    2886             : #ifdef DEBUG
    2887         583 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    2888         583 :         ASSERT(args->index < ichdr.count);
    2889         583 :         ASSERT(args->index >= 0);
    2890             : 
    2891         583 :         if (entry->flags & XFS_ATTR_LOCAL) {
    2892           0 :                 name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
    2893           0 :                 namelen = name_loc->namelen;
    2894           0 :                 name = (char *)name_loc->nameval;
    2895             :         } else {
    2896         583 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
    2897         583 :                 namelen = name_rmt->namelen;
    2898         583 :                 name = (char *)name_rmt->name;
    2899             :         }
    2900        1166 :         ASSERT(be32_to_cpu(entry->hashval) == args->hashval);
    2901         583 :         ASSERT(namelen == args->namelen);
    2902        1166 :         ASSERT(memcmp(name, args->name, namelen) == 0);
    2903             : #endif /* DEBUG */
    2904             : 
    2905         583 :         entry->flags &= ~XFS_ATTR_INCOMPLETE;
    2906         583 :         xfs_trans_log_buf(args->trans, bp,
    2907         583 :                          XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
    2908             : 
    2909         583 :         if (args->rmtblkno) {
    2910         583 :                 ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0);
    2911         583 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
    2912         583 :                 name_rmt->valueblk = cpu_to_be32(args->rmtblkno);
    2913         583 :                 name_rmt->valuelen = cpu_to_be32(args->rmtvaluelen);
    2914         583 :                 xfs_trans_log_buf(args->trans, bp,
    2915         583 :                          XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt)));
    2916             :         }
    2917             : 
    2918             :         return 0;
    2919             : }
    2920             : 
    2921             : /*
    2922             :  * Set the INCOMPLETE flag on an entry in a leaf block.
    2923             :  */
    2924             : int
    2925     1283324 : xfs_attr3_leaf_setflag(
    2926             :         struct xfs_da_args      *args)
    2927             : {
    2928     1283324 :         struct xfs_attr_leafblock *leaf;
    2929     1283324 :         struct xfs_attr_leaf_entry *entry;
    2930     1283324 :         struct xfs_attr_leaf_name_remote *name_rmt;
    2931     1283324 :         struct xfs_buf          *bp;
    2932     1283324 :         int error;
    2933             : #ifdef DEBUG
    2934     1283324 :         struct xfs_attr3_icleaf_hdr ichdr;
    2935             : #endif
    2936             : 
    2937     1283324 :         trace_xfs_attr_leaf_setflag(args);
    2938             : 
    2939             :         /*
    2940             :          * Set up the operation.
    2941             :          */
    2942     1283333 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
    2943             :                         args->blkno, &bp);
    2944     1283333 :         if (error)
    2945             :                 return error;
    2946             : 
    2947     1283322 :         leaf = bp->b_addr;
    2948             : #ifdef DEBUG
    2949     1283322 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    2950     1283331 :         ASSERT(args->index < ichdr.count);
    2951     1283331 :         ASSERT(args->index >= 0);
    2952             : #endif
    2953     1283331 :         entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
    2954             : 
    2955     1283331 :         ASSERT((entry->flags & XFS_ATTR_INCOMPLETE) == 0);
    2956     1283331 :         entry->flags |= XFS_ATTR_INCOMPLETE;
    2957     1283331 :         xfs_trans_log_buf(args->trans, bp,
    2958     1283331 :                         XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
    2959     1283333 :         if ((entry->flags & XFS_ATTR_LOCAL) == 0) {
    2960          12 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
    2961          12 :                 name_rmt->valueblk = 0;
    2962          12 :                 name_rmt->valuelen = 0;
    2963          12 :                 xfs_trans_log_buf(args->trans, bp,
    2964          12 :                          XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt)));
    2965             :         }
    2966             : 
    2967             :         return 0;
    2968             : }
    2969             : 
    2970             : /*
    2971             :  * In a single transaction, clear the INCOMPLETE flag on the leaf entry
    2972             :  * given by args->blkno/index and set the INCOMPLETE flag on the leaf
    2973             :  * entry given by args->blkno2/index2.
    2974             :  *
    2975             :  * Note that they could be in different blocks, or in the same block.
    2976             :  */
    2977             : int
    2978    36987270 : xfs_attr3_leaf_flipflags(
    2979             :         struct xfs_da_args      *args)
    2980             : {
    2981    36987270 :         struct xfs_attr_leafblock *leaf1;
    2982    36987270 :         struct xfs_attr_leafblock *leaf2;
    2983    36987270 :         struct xfs_attr_leaf_entry *entry1;
    2984    36987270 :         struct xfs_attr_leaf_entry *entry2;
    2985    36987270 :         struct xfs_attr_leaf_name_remote *name_rmt;
    2986    36987270 :         struct xfs_buf          *bp1;
    2987    36987270 :         struct xfs_buf          *bp2;
    2988    36987270 :         int error;
    2989             : #ifdef DEBUG
    2990    36987270 :         struct xfs_attr3_icleaf_hdr ichdr1;
    2991    36987270 :         struct xfs_attr3_icleaf_hdr ichdr2;
    2992    36987270 :         xfs_attr_leaf_name_local_t *name_loc;
    2993    36987270 :         int namelen1, namelen2;
    2994    36987270 :         char *name1, *name2;
    2995             : #endif /* DEBUG */
    2996             : 
    2997    36987270 :         trace_xfs_attr_leaf_flipflags(args);
    2998             : 
    2999             :         /*
    3000             :          * Read the block containing the "old" attr
    3001             :          */
    3002    36991226 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
    3003             :                         args->blkno, &bp1);
    3004    36988592 :         if (error)
    3005             :                 return error;
    3006             : 
    3007             :         /*
    3008             :          * Read the block containing the "new" attr, if it is different
    3009             :          */
    3010    36988592 :         if (args->blkno2 != args->blkno) {
    3011         438 :                 error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
    3012             :                                 args->blkno2, &bp2);
    3013         438 :                 if (error)
    3014             :                         return error;
    3015             :         } else {
    3016    36988154 :                 bp2 = bp1;
    3017             :         }
    3018             : 
    3019    36988592 :         leaf1 = bp1->b_addr;
    3020    36988592 :         entry1 = &xfs_attr3_leaf_entryp(leaf1)[args->index];
    3021             : 
    3022    36988592 :         leaf2 = bp2->b_addr;
    3023    36988592 :         entry2 = &xfs_attr3_leaf_entryp(leaf2)[args->index2];
    3024             : 
    3025             : #ifdef DEBUG
    3026    36988592 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr1, leaf1);
    3027    36991107 :         ASSERT(args->index < ichdr1.count);
    3028    36991107 :         ASSERT(args->index >= 0);
    3029             : 
    3030    36991107 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr2, leaf2);
    3031    36988885 :         ASSERT(args->index2 < ichdr2.count);
    3032    36988885 :         ASSERT(args->index2 >= 0);
    3033             : 
    3034    36988885 :         if (entry1->flags & XFS_ATTR_LOCAL) {
    3035    36988883 :                 name_loc = xfs_attr3_leaf_name_local(leaf1, args->index);
    3036    36988883 :                 namelen1 = name_loc->namelen;
    3037    36988883 :                 name1 = (char *)name_loc->nameval;
    3038             :         } else {
    3039           2 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index);
    3040           2 :                 namelen1 = name_rmt->namelen;
    3041           2 :                 name1 = (char *)name_rmt->name;
    3042             :         }
    3043    36988885 :         if (entry2->flags & XFS_ATTR_LOCAL) {
    3044    36991291 :                 name_loc = xfs_attr3_leaf_name_local(leaf2, args->index2);
    3045    36991291 :                 namelen2 = name_loc->namelen;
    3046    36991291 :                 name2 = (char *)name_loc->nameval;
    3047             :         } else {
    3048           0 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf2, args->index2);
    3049           0 :                 namelen2 = name_rmt->namelen;
    3050           0 :                 name2 = (char *)name_rmt->name;
    3051             :         }
    3052   110966655 :         ASSERT(be32_to_cpu(entry1->hashval) == be32_to_cpu(entry2->hashval));
    3053    36988885 :         ASSERT(namelen1 == namelen2);
    3054    73977770 :         ASSERT(memcmp(name1, name2, namelen1) == 0);
    3055             : #endif /* DEBUG */
    3056             : 
    3057    36988885 :         ASSERT(entry1->flags & XFS_ATTR_INCOMPLETE);
    3058    36988885 :         ASSERT((entry2->flags & XFS_ATTR_INCOMPLETE) == 0);
    3059             : 
    3060    36988885 :         entry1->flags &= ~XFS_ATTR_INCOMPLETE;
    3061    36988885 :         xfs_trans_log_buf(args->trans, bp1,
    3062    36988885 :                           XFS_DA_LOGRANGE(leaf1, entry1, sizeof(*entry1)));
    3063    36988903 :         if (args->rmtblkno) {
    3064           2 :                 ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0);
    3065           2 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index);
    3066           2 :                 name_rmt->valueblk = cpu_to_be32(args->rmtblkno);
    3067           2 :                 name_rmt->valuelen = cpu_to_be32(args->rmtvaluelen);
    3068           2 :                 xfs_trans_log_buf(args->trans, bp1,
    3069           2 :                          XFS_DA_LOGRANGE(leaf1, name_rmt, sizeof(*name_rmt)));
    3070             :         }
    3071             : 
    3072    36988903 :         entry2->flags |= XFS_ATTR_INCOMPLETE;
    3073    36988903 :         xfs_trans_log_buf(args->trans, bp2,
    3074    36988903 :                           XFS_DA_LOGRANGE(leaf2, entry2, sizeof(*entry2)));
    3075    36990253 :         if ((entry2->flags & XFS_ATTR_LOCAL) == 0) {
    3076           4 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf2, args->index2);
    3077           4 :                 name_rmt->valueblk = 0;
    3078           4 :                 name_rmt->valuelen = 0;
    3079           4 :                 xfs_trans_log_buf(args->trans, bp2,
    3080           4 :                          XFS_DA_LOGRANGE(leaf2, name_rmt, sizeof(*name_rmt)));
    3081             :         }
    3082             : 
    3083             :         return 0;
    3084             : }

Generated by: LCOV version 1.14