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-rc3-acha @ Mon Jul 31 20:08:06 PDT 2023 Lines: 1319 1450 91.0 %
Date: 2023-07-31 20:08:07 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  1806297204 : 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  1806297204 :         struct xfs_attr3_leaf_hdr       *hdr3;
     101             : 
     102  1806297204 :         if (from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)) {
     103  1806297204 :                 hdr3 = (struct xfs_attr3_leaf_hdr *) from;
     104  1806297204 :                 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  1806297204 :         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  1806297204 : }
     120             : 
     121             : static void
     122   148052938 : 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   148052938 :         struct xfs_attr3_leaf_hdr       *hdr3;
     128   148052938 :         uint32_t                        firstused;
     129             : 
     130             :         /* magic value should only be seen on disk */
     131   148052938 :         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   148052938 :         firstused = from->firstused;
     139   148052938 :         if (firstused > USHRT_MAX) {
     140           1 :                 ASSERT(from->firstused == geo->blksize);
     141             :                 firstused = XFS_ATTR3_LEAF_NULLOFF;
     142             :         }
     143             : 
     144   148052938 :         if (from->magic == XFS_ATTR3_LEAF_MAGIC) {
     145   148052938 :                 hdr3 = (struct xfs_attr3_leaf_hdr *) to;
     146   148052938 :                 hdr3->firstused = cpu_to_be16(firstused);
     147             :         } else {
     148           0 :                 to->hdr.firstused = cpu_to_be16(firstused);
     149             :         }
     150   148052938 : }
     151             : 
     152             : void
     153  1805923571 : 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  1805923571 :         int     i;
     159             : 
     160  1805923571 :         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  1805923571 :         if (from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)) {
     164  1805923571 :                 struct xfs_attr3_leaf_hdr *hdr3 = (struct xfs_attr3_leaf_hdr *)from;
     165             : 
     166  1805923571 :                 to->forw = be32_to_cpu(hdr3->info.hdr.forw);
     167  1805923571 :                 to->back = be32_to_cpu(hdr3->info.hdr.back);
     168  1805923571 :                 to->magic = be16_to_cpu(hdr3->info.hdr.magic);
     169  1805923571 :                 to->count = be16_to_cpu(hdr3->count);
     170  1805923571 :                 to->usedbytes = be16_to_cpu(hdr3->usedbytes);
     171  1805923571 :                 xfs_attr3_leaf_firstused_from_disk(geo, to, from);
     172  1806335281 :                 to->holes = hdr3->holes;
     173             : 
     174  7219966033 :                 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
     175  5413630752 :                         to->freemap[i].base = be16_to_cpu(hdr3->freemap[i].base);
     176 10827261504 :                         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   148043153 : 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   148043153 :         int                             i;
     201             : 
     202   148043153 :         ASSERT(from->magic == XFS_ATTR_LEAF_MAGIC ||
     203             :                from->magic == XFS_ATTR3_LEAF_MAGIC);
     204             : 
     205   148043153 :         if (from->magic == XFS_ATTR3_LEAF_MAGIC) {
     206   148043153 :                 struct xfs_attr3_leaf_hdr *hdr3 = (struct xfs_attr3_leaf_hdr *)to;
     207             : 
     208   148043153 :                 hdr3->info.hdr.forw = cpu_to_be32(from->forw);
     209   148043153 :                 hdr3->info.hdr.back = cpu_to_be32(from->back);
     210   148043153 :                 hdr3->info.hdr.magic = cpu_to_be16(from->magic);
     211   148043153 :                 hdr3->count = cpu_to_be16(from->count);
     212   148043153 :                 hdr3->usedbytes = cpu_to_be16(from->usedbytes);
     213   148043153 :                 xfs_attr3_leaf_firstused_to_disk(geo, to, from);
     214   148068505 :                 hdr3->holes = from->holes;
     215   148068505 :                 hdr3->pad1 = 0;
     216             : 
     217   592220303 :                 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
     218   444151798 :                         hdr3->freemap[i].base = cpu_to_be16(from->freemap[i].base);
     219   888303596 :                         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   445865274 : 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   445865274 :         struct xfs_attr_leaf_name_local         *lentry;
     249   445865274 :         struct xfs_attr_leaf_name_remote        *rentry;
     250   445865274 :         char                                    *name_end;
     251   445865274 :         unsigned int                            nameidx;
     252   445865274 :         unsigned int                            namesize;
     253   445865274 :         __u32                                   hashval;
     254             : 
     255             :         /* hash order check */
     256   445865274 :         hashval = be32_to_cpu(ent->hashval);
     257   445865274 :         if (hashval < *last_hashval)
     258           0 :                 return __this_address;
     259   445865274 :         *last_hashval = hashval;
     260             : 
     261   445865274 :         nameidx = be16_to_cpu(ent->nameidx);
     262   445865274 :         if (nameidx < leafhdr->firstused || nameidx >= mp->m_attr_geo->blksize)
     263           7 :                 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   445867671 :         if (ent->flags & XFS_ATTR_LOCAL) {
     270   445866716 :                 lentry = xfs_attr3_leaf_name_local(leaf, idx);
     271   445866716 :                 namesize = xfs_attr_leaf_entsize_local(lentry->namelen,
     272   445866716 :                                 be16_to_cpu(lentry->valuelen));
     273   445866716 :                 name_end = (char *)lentry + namesize;
     274   445866716 :                 if (lentry->namelen == 0)
     275           0 :                         return __this_address;
     276             :         } else {
     277         955 :                 rentry = xfs_attr3_leaf_name_remote(leaf, idx);
     278         955 :                 namesize = xfs_attr_leaf_entsize_remote(rentry->namelen);
     279         955 :                 name_end = (char *)rentry + namesize;
     280         955 :                 if (rentry->namelen == 0)
     281           0 :                         return __this_address;
     282         955 :                 if (!(ent->flags & XFS_ATTR_INCOMPLETE) &&
     283         955 :                     rentry->valueblk == 0)
     284           0 :                         return __this_address;
     285             :         }
     286             : 
     287   445867671 :         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    23760255 : xfs_attr3_leaf_verify(
     312             :         struct xfs_buf                  *bp)
     313             : {
     314    23760255 :         struct xfs_attr3_icleaf_hdr     ichdr;
     315    23760255 :         struct xfs_mount                *mp = bp->b_mount;
     316    23760255 :         struct xfs_attr_leafblock       *leaf = bp->b_addr;
     317    23760255 :         struct xfs_attr_leaf_entry      *entries;
     318    23760255 :         struct xfs_attr_leaf_entry      *ent;
     319    23760255 :         char                            *buf_end;
     320    23760255 :         uint32_t                        end;    /* must be 32bit - see below */
     321    23760255 :         __u32                           last_hashval = 0;
     322    23760255 :         int                             i;
     323    23760255 :         xfs_failaddr_t                  fa;
     324             : 
     325    23760255 :         xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
     326             : 
     327    23760199 :         fa = xfs_da3_blkinfo_verify(bp, bp->b_addr);
     328    23760320 :         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    23760324 :         if (ichdr.firstused > mp->m_attr_geo->blksize)
     336           0 :                 return __this_address;
     337    47520645 :         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    23760324 :         entries = xfs_attr3_leaf_entryp(bp->b_addr);
     342    23760324 :         if ((char *)&entries[ichdr.count] >
     343    23760324 :             (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    23760324 :         buf_end = (char *)bp->b_addr + mp->m_attr_geo->blksize;
     354   469637562 :         for (i = 0, ent = entries; i < ichdr.count; ent++, i++) {
     355   445877300 :                 fa = xfs_attr3_leaf_verify_entry(mp, buf_end, leaf, &ichdr,
     356             :                                 ent, i, &last_hashval);
     357   445877238 :                 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    95040940 :         for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
     371    71280678 :                 if (ichdr.freemap[i].base > mp->m_attr_geo->blksize)
     372           0 :                         return __this_address;
     373    71280678 :                 if (ichdr.freemap[i].base & 0x3)
     374           0 :                         return __this_address;
     375    71280678 :                 if (ichdr.freemap[i].size > mp->m_attr_geo->blksize)
     376           0 :                         return __this_address;
     377    71280678 :                 if (ichdr.freemap[i].size & 0x3)
     378           0 :                         return __this_address;
     379             : 
     380             :                 /* be care of 16 bit overflows here */
     381    71280678 :                 end = (uint32_t)ichdr.freemap[i].base + ichdr.freemap[i].size;
     382    71280678 :                 if (end < ichdr.freemap[i].base)
     383           0 :                         return __this_address;
     384    71280678 :                 if (end > mp->m_attr_geo->blksize)
     385           0 :                         return __this_address;
     386             :         }
     387             : 
     388             :         return NULL;
     389             : }
     390             : 
     391             : xfs_failaddr_t
     392   936640151 : xfs_attr3_leaf_header_check(
     393             :         struct xfs_buf          *bp,
     394             :         xfs_ino_t               owner)
     395             : {
     396   936640151 :         struct xfs_mount        *mp = bp->b_mount;
     397             : 
     398   936640151 :         if (xfs_has_crc(mp)) {
     399   936640151 :                 struct xfs_attr3_leafblock *hdr3 = bp->b_addr;
     400             : 
     401   936640151 :                 ASSERT(hdr3->hdr.info.hdr.magic ==
     402             :                                 cpu_to_be16(XFS_ATTR3_LEAF_MAGIC));
     403             : 
     404   936640151 :                 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    22057448 : xfs_attr3_leaf_write_verify(
     413             :         struct xfs_buf  *bp)
     414             : {
     415    22057448 :         struct xfs_mount        *mp = bp->b_mount;
     416    22057448 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     417    22057448 :         struct xfs_attr3_leaf_hdr *hdr3 = bp->b_addr;
     418    22057448 :         xfs_failaddr_t          fa;
     419             : 
     420    22057448 :         fa = xfs_attr3_leaf_verify(bp);
     421    22057448 :         if (fa) {
     422           0 :                 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
     423           0 :                 return;
     424             :         }
     425             : 
     426    22057448 :         if (!xfs_has_crc(mp))
     427             :                 return;
     428             : 
     429    22057448 :         if (bip)
     430    22057448 :                 hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
     431             : 
     432    22057448 :         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      241831 : xfs_attr3_leaf_read_verify(
     443             :         struct xfs_buf          *bp)
     444             : {
     445      241831 :         struct xfs_mount        *mp = bp->b_mount;
     446      241831 :         xfs_failaddr_t          fa;
     447             : 
     448      483662 :         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      241627 :                 fa = xfs_attr3_leaf_verify(bp);
     453      241627 :                 if (fa)
     454           0 :                         xfs_verifier_error(bp, -EFSCORRUPTED, fa);
     455             :         }
     456      241831 : }
     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   625975039 : 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   625975039 :         xfs_failaddr_t          fa;
     476   625975039 :         int                     err;
     477             : 
     478   625975039 :         err = xfs_da_read_buf(tp, dp, bno, 0, bpp, XFS_ATTR_FORK,
     479             :                         &xfs_attr3_leaf_buf_ops);
     480   626242826 :         if (err || !(*bpp))
     481             :                 return err;
     482             : 
     483   626242763 :         fa = xfs_attr3_leaf_header_check(*bpp, owner);
     484   626156469 :         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   626156469 :         if (tp)
     493   261902739 :                 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  5371341766 : 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  5371341766 :         if (args->namelen != namelen)
     520             :                 return false;
     521 10321508928 :         if (memcmp(args->name, name, namelen) != 0)
     522             :                 return false;
     523             : 
     524   341997947 :         if (args->op_flags & XFS_DA_OP_NVLOOKUP) {
     525   206468446 :                 if (args->valuelen != valuelen)
     526             :                         return false;
     527   206421042 :                 if (args->valuelen && !value) {
     528             :                         /* not implemented for remote values */
     529           0 :                         ASSERT(0);
     530           0 :                         return false;
     531             :                 }
     532   206421042 :                 if (valuelen && !args->value) {
     533             :                         /* caller gave us valuelen > 0 but no value?? */
     534           0 :                         ASSERT(0);
     535           0 :                         return false;
     536             :                 }
     537   412842084 :                 if (valuelen > 0 && memcmp(args->value, value, valuelen) != 0)
     538             :                         return false;
     539             :         }
     540             : 
     541             :         /* Recovery ignores the INCOMPLETE flag. */
     542   336704549 :         if ((args->op_flags & XFS_DA_OP_RECOVERY) &&
     543          71 :             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   336704492 :         if (args->attr_filter !=
     548   336704492 :             (flags & (XFS_ATTR_NSP_ONDISK_MASK | XFS_ATTR_INCOMPLETE)))
     549      347977 :                 return false;
     550             :         return true;
     551             : }
     552             : 
     553             : static int
     554   134909641 : 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   134909641 :         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    12193473 :         if (!args->valuelen) {
     567     6127118 :                 args->valuelen = valuelen;
     568     6127118 :                 return 0;
     569             :         }
     570             : 
     571             :         /*
     572             :          * No copy if the length of the existing buffer is too small
     573             :          */
     574     6066355 :         if (args->valuelen < valuelen) {
     575           0 :                 args->valuelen = valuelen;
     576           0 :                 return -ERANGE;
     577             :         }
     578             : 
     579     6066355 :         if (!args->value) {
     580         146 :                 args->value = kvmalloc(valuelen, GFP_KERNEL | __GFP_NOLOCKDEP);
     581         146 :                 if (!args->value)
     582             :                         return -ENOMEM;
     583             :         }
     584     6066355 :         args->valuelen = valuelen;
     585             : 
     586             :         /* remote block xattr requires IO for copy-in */
     587     6066355 :         if (args->rmtblkno)
     588         436 :                 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     6065919 :         if (!value)
     597             :                 return -EINVAL;
     598    12131838 :         memcpy(args->value, value, valuelen);
     599     6065919 :         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   266784359 : xfs_attr_shortform_bytesfit(
     618             :         struct xfs_inode        *dp,
     619             :         int                     bytes)
     620             : {
     621   266784359 :         struct xfs_mount        *mp = dp->i_mount;
     622   266784359 :         int64_t                 dsize;
     623   266784359 :         int                     minforkoff;
     624   266784359 :         int                     maxforkoff;
     625   266784359 :         int                     offset;
     626             : 
     627             :         /*
     628             :          * Check if the new size could fit at all first:
     629             :          */
     630   266784369 :         if (bytes > XFS_LITINO(mp))
     631             :                 return 0;
     632             : 
     633             :         /* rounded down */
     634   225441077 :         offset = (XFS_LITINO(mp) - bytes) >> 3;
     635             : 
     636   225441077 :         if (dp->i_df.if_format == XFS_DINODE_FMT_DEV) {
     637    25891383 :                 minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
     638    25891383 :                 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   199549694 :         if (bytes <= xfs_inode_attr_fork_size(dp))
     652   182892535 :                 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    16657159 :         if (!xfs_has_attr2(mp))
     660             :                 return 0;
     661             : 
     662    16657159 :         dsize = dp->i_df.if_bytes;
     663             : 
     664    16657159 :         switch (dp->i_df.if_format) {
     665    16397497 :         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    16397497 :                 if (!dp->i_forkoff && dp->i_df.if_bytes >
     674      197694 :                     xfs_default_attroffset(dp))
     675          42 :                         dsize = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
     676             :                 break;
     677      121109 :         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      121109 :                 if (dp->i_forkoff) {
     685      121098 :                         if (offset < dp->i_forkoff)
     686             :                                 return 0;
     687           0 :                         return dp->i_forkoff;
     688             :                 }
     689          11 :                 dsize = XFS_BMAP_BROOT_SPACE(mp, dp->i_df.if_broot);
     690          11 :                 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    16536053 :         minforkoff = max_t(int64_t, dsize, XFS_BMDR_SPACE_CALC(MINDBTPTRS));
     698    16536053 :         minforkoff = roundup(minforkoff, 8) >> 3;
     699             : 
     700             :         /* attr fork btree root can have at least this many key/ptr pairs */
     701    16536053 :         maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
     702    16536053 :         maxforkoff = maxforkoff >> 3;     /* rounded down */
     703             : 
     704    16536053 :         if (offset >= maxforkoff)
     705             :                 return maxforkoff;
     706    16374956 :         if (offset >= minforkoff)
     707    10284114 :                 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   228875898 : xfs_sbversion_add_attr2(
     719             :         struct xfs_mount        *mp,
     720             :         struct xfs_trans        *tp)
     721             : {
     722   228875898 :         if (xfs_has_noattr2(mp))
     723             :                 return;
     724   228875898 :         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    62741990 : xfs_attr_shortform_create(
     740             :         struct xfs_da_args      *args)
     741             : {
     742    62741990 :         struct xfs_inode        *dp = args->dp;
     743    62741990 :         struct xfs_ifork        *ifp = &dp->i_af;
     744    62741990 :         struct xfs_attr_sf_hdr  *hdr;
     745             : 
     746    62741990 :         trace_xfs_attr_sf_create(args);
     747             : 
     748    62745570 :         ASSERT(ifp->if_bytes == 0);
     749    62745570 :         if (ifp->if_format == XFS_DINODE_FMT_EXTENTS)
     750    62744868 :                 ifp->if_format = XFS_DINODE_FMT_LOCAL;
     751    62745570 :         xfs_idata_realloc(dp, sizeof(*hdr), XFS_ATTR_FORK);
     752    62744658 :         hdr = (struct xfs_attr_sf_hdr *)ifp->if_u1.if_data;
     753    62744658 :         memset(hdr, 0, sizeof(*hdr));
     754    62744658 :         hdr->totsize = cpu_to_be16(sizeof(*hdr));
     755    62744658 :         xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
     756    62746800 : }
     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   274426678 : xfs_attr_sf_findname(
     769             :         struct xfs_da_args       *args,
     770             :         struct xfs_attr_sf_entry **sfep,
     771             :         unsigned int             *basep)
     772             : {
     773   274426678 :         struct xfs_attr_shortform *sf;
     774   274426678 :         struct xfs_attr_sf_entry *sfe;
     775   274426678 :         unsigned int            base = sizeof(struct xfs_attr_sf_hdr);
     776   274426678 :         int                     size = 0;
     777   274426678 :         int                     end;
     778   274426678 :         int                     i;
     779             : 
     780   274426678 :         sf = (struct xfs_attr_shortform *)args->dp->i_af.if_u1.if_data;
     781   274426678 :         sfe = &sf->list[0];
     782   274426678 :         end = sf->hdr.count;
     783   563317512 :         for (i = 0; i < end; sfe = xfs_attr_sf_nextentry(sfe),
     784   288890834 :                              base += size, i++) {
     785   391762639 :                 size = xfs_attr_sf_entsize(sfe);
     786   391789496 :                 if (!xfs_attr_match(args, sfe->namelen, sfe->nameval,
     787   391762639 :                                     sfe->valuelen, &sfe->nameval[sfe->namelen],
     788   391762639 :                                     sfe->flags))
     789   288890834 :                         continue;
     790             :                 break;
     791             :         }
     792             : 
     793   274453535 :         if (sfep != NULL)
     794   228878591 :                 *sfep = sfe;
     795             : 
     796   274453535 :         if (basep != NULL)
     797    89656778 :                 *basep = base;
     798             : 
     799   274453535 :         if (i == end)
     800   171553535 :                 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   139226345 : xfs_attr_shortform_add(
     810             :         struct xfs_da_args              *args,
     811             :         int                             forkoff)
     812             : {
     813   139226345 :         struct xfs_attr_shortform       *sf;
     814   139226345 :         struct xfs_attr_sf_entry        *sfe;
     815   139226345 :         int                             offset, size;
     816   139226345 :         struct xfs_mount                *mp;
     817   139226345 :         struct xfs_inode                *dp;
     818   139226345 :         struct xfs_ifork                *ifp;
     819             : 
     820   139226345 :         trace_xfs_attr_sf_add(args);
     821             : 
     822   139228661 :         dp = args->dp;
     823   139228661 :         mp = dp->i_mount;
     824   139228661 :         dp->i_forkoff = forkoff;
     825             : 
     826   139228661 :         ifp = &dp->i_af;
     827   139228661 :         ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
     828   139228661 :         sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
     829   139228661 :         if (xfs_attr_sf_findname(args, &sfe, NULL) == -EEXIST)
     830           0 :                 ASSERT(0);
     831             : 
     832   139227675 :         offset = (char *)sfe - (char *)sf;
     833   139227675 :         size = xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
     834   139227675 :         xfs_idata_realloc(dp, size, XFS_ATTR_FORK);
     835   139228318 :         sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
     836   139228318 :         sfe = (struct xfs_attr_sf_entry *)((char *)sf + offset);
     837             : 
     838   139228318 :         sfe->namelen = args->namelen;
     839   139228318 :         sfe->valuelen = args->valuelen;
     840   139228318 :         sfe->flags = args->attr_filter;
     841   278456636 :         memcpy(sfe->nameval, args->name, args->namelen);
     842   278456636 :         memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
     843   139228318 :         sf->hdr.count++;
     844   139228318 :         be16_add_cpu(&sf->hdr.totsize, size);
     845   139227715 :         xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
     846             : 
     847   139233490 :         xfs_sbversion_add_attr2(mp, args->trans);
     848   139233209 : }
     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    39661140 : xfs_attr_fork_remove(
     856             :         struct xfs_inode        *ip,
     857             :         struct xfs_trans        *tp)
     858             : {
     859    39661140 :         ASSERT(ip->i_af.if_nextents == 0);
     860             : 
     861    39661140 :         xfs_ifork_zap_attr(ip);
     862    39667313 :         ip->i_forkoff = 0;
     863    39667313 :         xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
     864    39672558 : }
     865             : 
     866             : /*
     867             :  * Remove an attribute from the shortform attribute list structure.
     868             :  */
     869             : int
     870    89650700 : xfs_attr_sf_removename(
     871             :         struct xfs_da_args              *args)
     872             : {
     873    89650700 :         struct xfs_attr_shortform       *sf;
     874    89650700 :         struct xfs_attr_sf_entry        *sfe;
     875    89650700 :         int                             size = 0, end, totsize;
     876    89650700 :         unsigned int                    base;
     877    89650700 :         struct xfs_mount                *mp;
     878    89650700 :         struct xfs_inode                *dp;
     879    89650700 :         int                             error;
     880             : 
     881    89650700 :         trace_xfs_attr_sf_remove(args);
     882             : 
     883    89653046 :         dp = args->dp;
     884    89653046 :         mp = dp->i_mount;
     885    89653046 :         sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data;
     886             : 
     887    89653046 :         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    89651466 :         if (error == -ENOATTR && (args->op_flags & XFS_DA_OP_RECOVERY))
     895             :                 return 0;
     896    89651458 :         if (error != -EEXIST)
     897             :                 return error;
     898    89651458 :         size = xfs_attr_sf_entsize(sfe);
     899             : 
     900             :         /*
     901             :          * Fix up the attribute fork data, covering the hole
     902             :          */
     903    89651458 :         end = base + size;
     904    89651458 :         totsize = be16_to_cpu(sf->hdr.totsize);
     905    89651458 :         if (end != totsize)
     906    30776766 :                 memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end);
     907    89651458 :         sf->hdr.count--;
     908    89651458 :         be16_add_cpu(&sf->hdr.totsize, -size);
     909             : 
     910             :         /*
     911             :          * Fix up the start offset of the attribute fork
     912             :          */
     913    89652644 :         totsize -= size;
     914    89652644 :         if (totsize == sizeof(xfs_attr_sf_hdr_t) && xfs_has_attr2(mp) &&
     915    62858605 :             (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) &&
     916    62697353 :             !(args->op_flags & (XFS_DA_OP_ADDNAME | XFS_DA_OP_REPLACE)) &&
     917             :             !xfs_has_parent(mp)) {
     918         114 :                 xfs_attr_fork_remove(dp, args->trans);
     919             :         } else {
     920    89652530 :                 xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
     921    89650847 :                 dp->i_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
     922    89652208 :                 ASSERT(dp->i_forkoff);
     923    89652208 :                 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    89652208 :                 xfs_trans_log_inode(args->trans, dp,
     929             :                                         XFS_ILOG_CORE | XFS_ILOG_ADATA);
     930             :         }
     931             : 
     932    89653554 :         xfs_sbversion_add_attr2(mp, args->trans);
     933             : 
     934    89653554 :         return 0;
     935             : }
     936             : 
     937             : /*
     938             :  * Look up a name in a shortform attribute list structure.
     939             :  */
     940             : /*ARGSUSED*/
     941             : int
     942   131248092 : xfs_attr_shortform_lookup(xfs_da_args_t *args)
     943             : {
     944   131248092 :         struct xfs_attr_shortform *sf;
     945   131248092 :         struct xfs_attr_sf_entry *sfe;
     946   131248092 :         int i;
     947   131248092 :         struct xfs_ifork *ifp;
     948             : 
     949   131248092 :         trace_xfs_attr_sf_lookup(args);
     950             : 
     951   131251072 :         ifp = &args->dp->i_af;
     952   131251072 :         ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
     953   131251072 :         sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
     954   131251072 :         sfe = &sf->list[0];
     955   246356058 :         for (i = 0; i < sf->hdr.count;
     956   115104986 :                                 sfe = xfs_attr_sf_nextentry(sfe), i++) {
     957   121765281 :                 if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
     958   121764400 :                                 sfe->valuelen, &sfe->nameval[sfe->namelen],
     959   121764400 :                                 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   154735577 : xfs_attr_shortform_getvalue(
     974             :         struct xfs_da_args      *args)
     975             : {
     976   154735577 :         struct xfs_attr_shortform *sf;
     977   154735577 :         struct xfs_attr_sf_entry *sfe;
     978   154735577 :         int                     i;
     979             : 
     980   154735577 :         ASSERT(args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL);
     981   154735577 :         sf = (struct xfs_attr_shortform *)args->dp->i_af.if_u1.if_data;
     982   154735577 :         sfe = &sf->list[0];
     983   216792207 :         for (i = 0; i < sf->hdr.count;
     984    62056630 :                                 sfe = xfs_attr_sf_nextentry(sfe), i++) {
     985   186333677 :                 if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
     986   186384915 :                                 sfe->valuelen, &sfe->nameval[sfe->namelen],
     987   186384915 :                                 sfe->flags))
     988   124277047 :                         return xfs_attr_copy_value(args,
     989   124277047 :                                 &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     4263428 : xfs_attr_shortform_to_leaf(
     997             :         struct xfs_da_args              *args)
     998             : {
     999     4263428 :         struct xfs_inode                *dp;
    1000     4263428 :         struct xfs_attr_shortform       *sf;
    1001     4263428 :         struct xfs_attr_sf_entry        *sfe;
    1002     4263428 :         struct xfs_da_args              nargs;
    1003     4263428 :         char                            *tmpbuffer;
    1004     4263428 :         int                             error, i, size;
    1005     4263428 :         xfs_dablk_t                     blkno;
    1006     4263428 :         struct xfs_buf                  *bp;
    1007     4263428 :         struct xfs_ifork                *ifp;
    1008             : 
    1009     4263428 :         trace_xfs_attr_sf_to_leaf(args);
    1010             : 
    1011     4263484 :         dp = args->dp;
    1012     4263484 :         ifp = &dp->i_af;
    1013     4263484 :         sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
    1014     4263484 :         size = be16_to_cpu(sf->hdr.totsize);
    1015     4263484 :         tmpbuffer = kmem_alloc(size, 0);
    1016     4263446 :         ASSERT(tmpbuffer != NULL);
    1017     8526892 :         memcpy(tmpbuffer, ifp->if_u1.if_data, size);
    1018     4263446 :         sf = (struct xfs_attr_shortform *)tmpbuffer;
    1019             : 
    1020     4263446 :         xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
    1021     4263424 :         xfs_bmap_local_to_extents_empty(args->trans, dp, XFS_ATTR_FORK);
    1022             : 
    1023     4263473 :         bp = NULL;
    1024     4263473 :         error = xfs_da_grow_inode(args, &blkno);
    1025     4262426 :         if (error)
    1026           2 :                 goto out;
    1027             : 
    1028     4262424 :         ASSERT(blkno == 0);
    1029     4262424 :         error = xfs_attr3_leaf_create(args, blkno, &bp);
    1030     4263291 :         if (error)
    1031           0 :                 goto out;
    1032             : 
    1033     4263291 :         memset((char *)&nargs, 0, sizeof(nargs));
    1034     4263291 :         nargs.dp = dp;
    1035     4263291 :         nargs.geo = args->geo;
    1036     4263291 :         nargs.total = args->total;
    1037     4263291 :         nargs.whichfork = XFS_ATTR_FORK;
    1038     4263291 :         nargs.trans = args->trans;
    1039     4263291 :         nargs.op_flags = XFS_DA_OP_OKNOENT | XFS_DA_OP_NVLOOKUP;
    1040     4263291 :         nargs.owner = args->owner;
    1041             : 
    1042     4263291 :         sfe = &sf->list[0];
    1043    26309317 :         for (i = 0; i < sf->hdr.count; i++) {
    1044    22045916 :                 nargs.name = sfe->nameval;
    1045    22045916 :                 nargs.namelen = sfe->namelen;
    1046    22045916 :                 nargs.value = &sfe->nameval[nargs.namelen];
    1047    22045916 :                 nargs.valuelen = sfe->valuelen;
    1048    44090932 :                 nargs.hashval = xfs_da_hashname(sfe->nameval,
    1049    22045916 :                                                 sfe->namelen);
    1050    22045016 :                 nargs.attr_filter = sfe->flags & XFS_ATTR_NSP_ONDISK_MASK;
    1051    22045016 :                 error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */
    1052    22045176 :                 ASSERT(error == -ENOATTR);
    1053    22045176 :                 error = xfs_attr3_leaf_add(bp, &nargs);
    1054    22046026 :                 ASSERT(error != -ENOSPC);
    1055    22046026 :                 if (error)
    1056           0 :                         goto out;
    1057    22046026 :                 sfe = xfs_attr_sf_nextentry(sfe);
    1058             :         }
    1059             :         error = 0;
    1060     4263403 : out:
    1061     4263403 :         kmem_free(tmpbuffer);
    1062     4263417 :         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    45541421 : xfs_attr_shortform_allfit(
    1071             :         struct xfs_buf          *bp,
    1072             :         struct xfs_inode        *dp)
    1073             : {
    1074    45541421 :         struct xfs_attr_leafblock *leaf;
    1075    45541421 :         struct xfs_attr_leaf_entry *entry;
    1076    45541421 :         xfs_attr_leaf_name_local_t *name_loc;
    1077    45541421 :         struct xfs_attr3_icleaf_hdr leafhdr;
    1078    45541421 :         int                     bytes;
    1079    45541421 :         int                     i;
    1080    45541421 :         struct xfs_mount        *mp = bp->b_mount;
    1081             : 
    1082    45541421 :         leaf = bp->b_addr;
    1083    45541421 :         xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
    1084    45539669 :         entry = xfs_attr3_leaf_entryp(leaf);
    1085             : 
    1086             :         bytes = sizeof(struct xfs_attr_sf_hdr);
    1087   865735562 :         for (i = 0; i < leafhdr.count; entry++, i++) {
    1088   820197104 :                 if (entry->flags & XFS_ATTR_INCOMPLETE)
    1089           0 :                         continue;               /* don't copy partial entries */
    1090   820197104 :                 if (!(entry->flags & XFS_ATTR_LOCAL))
    1091             :                         return 0;
    1092   820197104 :                 name_loc = xfs_attr3_leaf_name_local(leaf, i);
    1093   820197104 :                 if (name_loc->namelen >= XFS_ATTR_SF_ENTSIZE_MAX)
    1094             :                         return 0;
    1095   820197104 :                 if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX)
    1096             :                         return 0;
    1097   820195893 :                 bytes += xfs_attr_sf_entsize_byname(name_loc->namelen,
    1098           0 :                                         be16_to_cpu(name_loc->valuelen));
    1099             :         }
    1100    45538458 :         if (xfs_has_attr2(dp->i_mount) &&
    1101    45538458 :             (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) &&
    1102             :             (bytes == sizeof(struct xfs_attr_sf_hdr)))
    1103             :                 return -1;
    1104    45538430 :         return xfs_attr_shortform_bytesfit(dp, bytes);
    1105             : }
    1106             : 
    1107             : /* Verify the consistency of a raw inline attribute fork. */
    1108             : xfs_failaddr_t
    1109   567703563 : xfs_attr_shortform_verify_struct(
    1110             :         struct xfs_attr_shortform       *sfp,
    1111             :         size_t                          size)
    1112             : {
    1113   567703563 :         struct xfs_attr_sf_entry        *sfep;
    1114   567703563 :         struct xfs_attr_sf_entry        *next_sfep;
    1115   567703563 :         char                            *endp;
    1116   567703563 :         int                             i;
    1117             : 
    1118             :         /*
    1119             :          * Give up if the attribute is way too short.
    1120             :          */
    1121   567703563 :         if (size < sizeof(struct xfs_attr_sf_hdr))
    1122           0 :                 return __this_address;
    1123             : 
    1124   567703563 :         endp = (char *)sfp + size;
    1125             : 
    1126             :         /* Check all reported entries */
    1127   567703563 :         sfep = &sfp->list[0];
    1128  1284986550 :         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   717263703 :                 if (((char *)sfep + sizeof(*sfep)) >= endp)
    1137           0 :                         return __this_address;
    1138             : 
    1139             :                 /* Don't allow names with known bad length. */
    1140   717263703 :                 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   717263703 :                 next_sfep = xfs_attr_sf_nextentry(sfep);
    1149   717263703 :                 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   717263703 :                 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  1434546690 :                 if (hweight8(sfep->flags & XFS_ATTR_NSP_ONDISK_MASK) > 1)
    1166           0 :                         return __this_address;
    1167             : 
    1168   717282987 :                 sfep = next_sfep;
    1169             :         }
    1170   567722847 :         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   567700222 : xfs_attr_shortform_verify(
    1179             :         struct xfs_inode                *ip)
    1180             : {
    1181   567700222 :         struct xfs_attr_shortform       *sfp;
    1182   567700222 :         struct xfs_ifork                *ifp;
    1183   567700222 :         int64_t                         size;
    1184             : 
    1185   567700222 :         ASSERT(ip->i_af.if_format == XFS_DINODE_FMT_LOCAL);
    1186   567700222 :         ifp = xfs_ifork_ptr(ip, XFS_ATTR_FORK);
    1187   567700222 :         sfp = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
    1188   567700222 :         size = ifp->if_bytes;
    1189             : 
    1190   567700222 :         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     2243276 : xfs_attr3_leaf_to_shortform(
    1198             :         struct xfs_buf          *bp,
    1199             :         struct xfs_da_args      *args,
    1200             :         int                     forkoff)
    1201             : {
    1202     2243276 :         struct xfs_attr_leafblock *leaf;
    1203     2243276 :         struct xfs_attr3_icleaf_hdr ichdr;
    1204     2243276 :         struct xfs_attr_leaf_entry *entry;
    1205     2243276 :         struct xfs_attr_leaf_name_local *name_loc;
    1206     2243276 :         struct xfs_da_args      nargs;
    1207     2243276 :         struct xfs_inode        *dp = args->dp;
    1208     2243276 :         char                    *tmpbuffer;
    1209     2243276 :         int                     error;
    1210     2243276 :         int                     i;
    1211             : 
    1212     2243276 :         trace_xfs_attr_leaf_to_sf(args);
    1213             : 
    1214     2243297 :         tmpbuffer = kmem_alloc(args->geo->blksize, 0);
    1215     2243274 :         if (!tmpbuffer)
    1216             :                 return -ENOMEM;
    1217             : 
    1218     4486548 :         memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
    1219             : 
    1220     2243274 :         leaf = (xfs_attr_leafblock_t *)tmpbuffer;
    1221     2243274 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    1222     2243285 :         entry = xfs_attr3_leaf_entryp(leaf);
    1223             : 
    1224             :         /* XXX (dgc): buffer is about to be marked stale - why zero it? */
    1225     2243285 :         memset(bp->b_addr, 0, args->geo->blksize);
    1226             : 
    1227             :         /*
    1228             :          * Clean out the prior contents of the attribute list.
    1229             :          */
    1230     2243285 :         error = xfs_da_shrink_inode(args, 0, bp);
    1231     2243281 :         if (error)
    1232           0 :                 goto out;
    1233             : 
    1234     2243281 :         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          28 :                 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          28 :                 goto out;
    1247             :         }
    1248             : 
    1249     2243253 :         xfs_attr_shortform_create(args);
    1250             : 
    1251             :         /*
    1252             :          * Copy the attributes
    1253             :          */
    1254     2243254 :         memset((char *)&nargs, 0, sizeof(nargs));
    1255     2243254 :         nargs.geo = args->geo;
    1256     2243254 :         nargs.dp = dp;
    1257     2243254 :         nargs.total = args->total;
    1258     2243254 :         nargs.whichfork = XFS_ATTR_FORK;
    1259     2243254 :         nargs.trans = args->trans;
    1260     2243254 :         nargs.op_flags = XFS_DA_OP_OKNOENT | XFS_DA_OP_NVLOOKUP;
    1261     2243254 :         nargs.owner = args->owner;
    1262             : 
    1263    14487204 :         for (i = 0; i < ichdr.count; entry++, i++) {
    1264    12243938 :                 if (entry->flags & XFS_ATTR_INCOMPLETE)
    1265           0 :                         continue;       /* don't copy partial entries */
    1266    12243938 :                 if (!entry->nameidx)
    1267           0 :                         continue;
    1268    12243938 :                 ASSERT(entry->flags & XFS_ATTR_LOCAL);
    1269    12243938 :                 name_loc = xfs_attr3_leaf_name_local(leaf, i);
    1270    12243938 :                 nargs.name = name_loc->nameval;
    1271    12243938 :                 nargs.namelen = name_loc->namelen;
    1272    12243938 :                 nargs.value = &name_loc->nameval[nargs.namelen];
    1273    12243938 :                 nargs.valuelen = be16_to_cpu(name_loc->valuelen);
    1274    12243938 :                 nargs.hashval = be32_to_cpu(entry->hashval);
    1275    12243938 :                 nargs.attr_filter = entry->flags & XFS_ATTR_NSP_ONDISK_MASK;
    1276    12243938 :                 xfs_attr_shortform_add(&nargs, forkoff);
    1277             :         }
    1278             :         error = 0;
    1279             : 
    1280     2243294 : out:
    1281     2243294 :         kmem_free(tmpbuffer);
    1282     2243294 :         return error;
    1283             : }
    1284             : 
    1285             : /*
    1286             :  * Convert from using a single leaf to a root node and a leaf.
    1287             :  */
    1288             : int
    1289       38363 : xfs_attr3_leaf_to_node(
    1290             :         struct xfs_da_args      *args)
    1291             : {
    1292       38363 :         struct xfs_attr_leafblock *leaf;
    1293       38363 :         struct xfs_attr3_icleaf_hdr icleafhdr;
    1294       38363 :         struct xfs_attr_leaf_entry *entries;
    1295       38363 :         struct xfs_da3_icnode_hdr icnodehdr;
    1296       38363 :         struct xfs_da_intnode   *node;
    1297       38363 :         struct xfs_inode        *dp = args->dp;
    1298       38363 :         struct xfs_mount        *mp = dp->i_mount;
    1299       38363 :         struct xfs_buf          *bp1 = NULL;
    1300       38363 :         struct xfs_buf          *bp2 = NULL;
    1301       38363 :         xfs_dablk_t             blkno;
    1302       38363 :         int                     error;
    1303             : 
    1304       38363 :         trace_xfs_attr_leaf_to_node(args);
    1305             : 
    1306       38363 :         if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_ATTR_LEAF_TO_NODE)) {
    1307           2 :                 error = -EIO;
    1308           2 :                 goto out;
    1309             :         }
    1310             : 
    1311       38361 :         error = xfs_da_grow_inode(args, &blkno);
    1312       38361 :         if (error)
    1313           0 :                 goto out;
    1314       38361 :         error = xfs_attr3_leaf_read(args->trans, dp, args->owner, 0, &bp1);
    1315       38361 :         if (error)
    1316           0 :                 goto out;
    1317             : 
    1318       38361 :         error = xfs_da_get_buf(args->trans, dp, blkno, &bp2, XFS_ATTR_FORK);
    1319       38361 :         if (error)
    1320           0 :                 goto out;
    1321             : 
    1322             :         /* copy leaf to new buffer, update identifiers */
    1323       38361 :         xfs_trans_buf_set_type(args->trans, bp2, XFS_BLFT_ATTR_LEAF_BUF);
    1324       38361 :         bp2->b_ops = bp1->b_ops;
    1325       76722 :         memcpy(bp2->b_addr, bp1->b_addr, args->geo->blksize);
    1326       38361 :         if (xfs_has_crc(mp)) {
    1327       38361 :                 struct xfs_da3_blkinfo *hdr3 = bp2->b_addr;
    1328       38361 :                 hdr3->blkno = cpu_to_be64(xfs_buf_daddr(bp2));
    1329             :         }
    1330       38361 :         xfs_trans_log_buf(args->trans, bp2, 0, args->geo->blksize - 1);
    1331             : 
    1332             :         /*
    1333             :          * Set up the new root node.
    1334             :          */
    1335       38361 :         error = xfs_da3_node_create(args, 0, 1, &bp1, XFS_ATTR_FORK);
    1336       38361 :         if (error)
    1337           0 :                 goto out;
    1338       38361 :         node = bp1->b_addr;
    1339       38361 :         xfs_da3_node_hdr_from_disk(mp, &icnodehdr, node);
    1340             : 
    1341       38361 :         leaf = bp2->b_addr;
    1342       38361 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &icleafhdr, leaf);
    1343       38361 :         entries = xfs_attr3_leaf_entryp(leaf);
    1344             : 
    1345             :         /* both on-disk, don't endian-flip twice */
    1346       38361 :         icnodehdr.btree[0].hashval = entries[icleafhdr.count - 1].hashval;
    1347       38361 :         icnodehdr.btree[0].before = cpu_to_be32(blkno);
    1348       38361 :         icnodehdr.count = 1;
    1349       38361 :         xfs_da3_node_hdr_to_disk(dp->i_mount, node, &icnodehdr);
    1350       38361 :         xfs_trans_log_buf(args->trans, bp1, 0, args->geo->blksize - 1);
    1351       38361 :         error = 0;
    1352       38363 : out:
    1353       38363 :         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     4323209 : xfs_attr3_leaf_create(
    1366             :         struct xfs_da_args      *args,
    1367             :         xfs_dablk_t             blkno,
    1368             :         struct xfs_buf          **bpp)
    1369             : {
    1370     4323209 :         struct xfs_attr_leafblock *leaf;
    1371     4323209 :         struct xfs_attr3_icleaf_hdr ichdr;
    1372     4323209 :         struct xfs_inode        *dp = args->dp;
    1373     4323209 :         struct xfs_mount        *mp = dp->i_mount;
    1374     4323209 :         struct xfs_buf          *bp;
    1375     4323209 :         int                     error;
    1376             : 
    1377     4323209 :         trace_xfs_attr_leaf_create(args);
    1378             : 
    1379     4323237 :         error = xfs_da_get_buf(args->trans, args->dp, blkno, &bp,
    1380             :                                             XFS_ATTR_FORK);
    1381     4323653 :         if (error)
    1382             :                 return error;
    1383     4323664 :         bp->b_ops = &xfs_attr3_leaf_buf_ops;
    1384     4323664 :         xfs_trans_buf_set_type(args->trans, bp, XFS_BLFT_ATTR_LEAF_BUF);
    1385     4323614 :         leaf = bp->b_addr;
    1386     4323614 :         memset(leaf, 0, args->geo->blksize);
    1387             : 
    1388     4323614 :         memset(&ichdr, 0, sizeof(ichdr));
    1389     4323614 :         ichdr.firstused = args->geo->blksize;
    1390             : 
    1391     4323614 :         if (xfs_has_crc(mp)) {
    1392     4323614 :                 struct xfs_da3_blkinfo *hdr3 = bp->b_addr;
    1393             : 
    1394     4323614 :                 ichdr.magic = XFS_ATTR3_LEAF_MAGIC;
    1395             : 
    1396     4323614 :                 hdr3->blkno = cpu_to_be64(xfs_buf_daddr(bp));
    1397     4323614 :                 hdr3->owner = cpu_to_be64(args->owner);
    1398     4323614 :                 uuid_copy(&hdr3->uuid, &mp->m_sb.sb_meta_uuid);
    1399             : 
    1400     4323597 :                 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     4323597 :         ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base;
    1406             : 
    1407     4323597 :         xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr);
    1408     4323558 :         xfs_trans_log_buf(args->trans, bp, 0, args->geo->blksize - 1);
    1409             : 
    1410     4323612 :         *bpp = bp;
    1411     4323612 :         return 0;
    1412             : }
    1413             : 
    1414             : /*
    1415             :  * Split the leaf node, rebalance, then add the new entry.
    1416             :  */
    1417             : int
    1418       60323 : 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       60323 :         xfs_dablk_t blkno;
    1424       60323 :         int error;
    1425             : 
    1426       60323 :         trace_xfs_attr_leaf_split(state->args);
    1427             : 
    1428             :         /*
    1429             :          * Allocate space for a new leaf node.
    1430             :          */
    1431       60323 :         ASSERT(oldblk->magic == XFS_ATTR_LEAF_MAGIC);
    1432       60323 :         error = xfs_da_grow_inode(state->args, &blkno);
    1433       60323 :         if (error)
    1434             :                 return error;
    1435       60323 :         error = xfs_attr3_leaf_create(state->args, blkno, &newblk->bp);
    1436       60323 :         if (error)
    1437             :                 return error;
    1438       60323 :         newblk->blkno = blkno;
    1439       60323 :         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       60323 :         xfs_attr3_leaf_rebalance(state, oldblk, newblk);
    1446       60323 :         error = xfs_da3_blk_link(state, oldblk, newblk);
    1447       60322 :         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       60322 :         if (state->inleaf) {
    1458       11666 :                 trace_xfs_attr_leaf_add_old(state->args);
    1459       11666 :                 error = xfs_attr3_leaf_add(oldblk->bp, state->args);
    1460             :         } else {
    1461       48656 :                 trace_xfs_attr_leaf_add_new(state->args);
    1462       48656 :                 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       60323 :         oldblk->hashval = xfs_attr_leaf_lasthash(oldblk->bp, NULL);
    1469       60323 :         newblk->hashval = xfs_attr_leaf_lasthash(newblk->bp, NULL);
    1470       60323 :         return error;
    1471             : }
    1472             : 
    1473             : /*
    1474             :  * Add a name to the leaf attribute list structure.
    1475             :  */
    1476             : int
    1477    96936423 : xfs_attr3_leaf_add(
    1478             :         struct xfs_buf          *bp,
    1479             :         struct xfs_da_args      *args)
    1480             : {
    1481    96936423 :         struct xfs_attr_leafblock *leaf;
    1482    96936423 :         struct xfs_attr3_icleaf_hdr ichdr;
    1483    96936423 :         int                     tablesize;
    1484    96936423 :         int                     entsize;
    1485    96936423 :         int                     sum;
    1486    96936423 :         int                     tmp;
    1487    96936423 :         int                     i;
    1488             : 
    1489    96936423 :         trace_xfs_attr_leaf_add(args);
    1490             : 
    1491    96950814 :         leaf = bp->b_addr;
    1492    96950814 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    1493    96949676 :         ASSERT(args->index >= 0 && args->index <= ichdr.count);
    1494    96949676 :         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    96952621 :         tablesize = (ichdr.count + 1) * sizeof(xfs_attr_leaf_entry_t)
    1501    96952621 :                                         + xfs_attr3_leaf_hdr_size(leaf);
    1502   236659770 :         for (sum = 0, i = XFS_ATTR_LEAF_MAPSIZE - 1; i >= 0; i--) {
    1503   236294259 :                 if (tablesize > ichdr.firstused) {
    1504       87000 :                         sum += ichdr.freemap[i].size;
    1505       87000 :                         continue;
    1506             :                 }
    1507   236207259 :                 if (!ichdr.freemap[i].size)
    1508    79328076 :                         continue;       /* no space in this map */
    1509   156879183 :                 tmp = entsize;
    1510   156879183 :                 if (ichdr.freemap[i].base < ichdr.firstused)
    1511    62902524 :                         tmp += sizeof(xfs_attr_leaf_entry_t);
    1512   156879183 :                 if (ichdr.freemap[i].size >= tmp) {
    1513    96587110 :                         tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, i);
    1514    96587506 :                         goto out_log_hdr;
    1515             :                 }
    1516    60292073 :                 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      365511 :         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      294663 :         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      294664 :         if (ichdr.freemap[0].size < (entsize + sizeof(xfs_attr_leaf_entry_t))) {
    1538       27840 :                 tmp = -ENOSPC;
    1539       27840 :                 goto out_log_hdr;
    1540             :         }
    1541             : 
    1542      266824 :         tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, 0);
    1543             : 
    1544    96882170 : out_log_hdr:
    1545    96882170 :         xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr);
    1546    96877104 :         xfs_trans_log_buf(args->trans, bp,
    1547    96877104 :                 XFS_DA_LOGRANGE(leaf, &leaf->hdr,
    1548             :                                 xfs_attr3_leaf_hdr_size(leaf)));
    1549    96877104 :         return tmp;
    1550             : }
    1551             : 
    1552             : /*
    1553             :  * Add a name to a leaf attribute list structure.
    1554             :  */
    1555             : STATIC int
    1556    96842503 : 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    96842503 :         struct xfs_attr_leafblock *leaf;
    1563    96842503 :         struct xfs_attr_leaf_entry *entry;
    1564    96842503 :         struct xfs_attr_leaf_name_local *name_loc;
    1565    96842503 :         struct xfs_attr_leaf_name_remote *name_rmt;
    1566    96842503 :         struct xfs_mount        *mp;
    1567    96842503 :         int                     tmp;
    1568    96842503 :         int                     i;
    1569             : 
    1570    96842503 :         trace_xfs_attr_leaf_add_work(args);
    1571             : 
    1572    96850103 :         leaf = bp->b_addr;
    1573    96850103 :         ASSERT(mapindex >= 0 && mapindex < XFS_ATTR_LEAF_MAPSIZE);
    1574    96850103 :         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    96850103 :         entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
    1580    96850103 :         if (args->index < ichdr->count) {
    1581    83555166 :                 tmp  = ichdr->count - args->index;
    1582    83555166 :                 tmp *= sizeof(xfs_attr_leaf_entry_t);
    1583   167110332 :                 memmove(entry + 1, entry, tmp);
    1584    83555166 :                 xfs_trans_log_buf(args->trans, bp,
    1585    83555166 :                     XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
    1586             :         }
    1587    96848311 :         ichdr->count++;
    1588             : 
    1589             :         /*
    1590             :          * Allocate space for the new string (at the end of the run).
    1591             :          */
    1592    96848311 :         mp = args->trans->t_mountp;
    1593    96848311 :         ASSERT(ichdr->freemap[mapindex].base < args->geo->blksize);
    1594    96848311 :         ASSERT((ichdr->freemap[mapindex].base & 0x3) == 0);
    1595    96848311 :         ASSERT(ichdr->freemap[mapindex].size >=
    1596             :                 xfs_attr_leaf_newentsize(args, NULL));
    1597    96852394 :         ASSERT(ichdr->freemap[mapindex].size < args->geo->blksize);
    1598    96852394 :         ASSERT((ichdr->freemap[mapindex].size & 0x3) == 0);
    1599             : 
    1600    96852394 :         ichdr->freemap[mapindex].size -= xfs_attr_leaf_newentsize(args, &tmp);
    1601             : 
    1602    96845704 :         entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base +
    1603             :                                      ichdr->freemap[mapindex].size);
    1604    96845704 :         entry->hashval = cpu_to_be32(args->hashval);
    1605    96845704 :         entry->flags = args->attr_filter;
    1606    96845704 :         if (tmp)
    1607    96850469 :                 entry->flags |= XFS_ATTR_LOCAL;
    1608    96845704 :         if (args->op_flags & XFS_DA_OP_REPLACE) {
    1609    17397042 :                 if (!(args->op_flags & XFS_DA_OP_LOGGED))
    1610    17397331 :                         entry->flags |= XFS_ATTR_INCOMPLETE;
    1611    17397042 :                 if ((args->blkno2 == args->blkno) &&
    1612    17397111 :                     (args->index2 <= args->index)) {
    1613    17396797 :                         args->index2++;
    1614             :                 }
    1615             :         }
    1616    96845704 :         xfs_trans_log_buf(args->trans, bp,
    1617    96845704 :                           XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
    1618   270527619 :         ASSERT((args->index == 0) ||
    1619             :                (be32_to_cpu(entry->hashval) >= be32_to_cpu((entry-1)->hashval)));
    1620   263957065 :         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    96849689 :         if (entry->flags & XFS_ATTR_LOCAL) {
    1631    96849162 :                 name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
    1632    96849162 :                 name_loc->namelen = args->namelen;
    1633    96849162 :                 name_loc->valuelen = cpu_to_be16(args->valuelen);
    1634   193698324 :                 memcpy((char *)name_loc->nameval, args->name, args->namelen);
    1635   193698324 :                 memcpy((char *)&name_loc->nameval[args->namelen], args->value,
    1636             :                                    be16_to_cpu(name_loc->valuelen));
    1637             :         } else {
    1638         527 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
    1639         527 :                 name_rmt->namelen = args->namelen;
    1640        1054 :                 memcpy((char *)name_rmt->name, args->name, args->namelen);
    1641         527 :                 entry->flags |= XFS_ATTR_INCOMPLETE;
    1642             :                 /* just in case */
    1643         527 :                 name_rmt->valuelen = 0;
    1644         527 :                 name_rmt->valueblk = 0;
    1645         527 :                 args->rmtblkno = 1;
    1646         527 :                 args->rmtblkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen);
    1647         527 :                 args->rmtvaluelen = args->valuelen;
    1648             :         }
    1649    96849689 :         xfs_trans_log_buf(args->trans, bp,
    1650    96849689 :              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    96841971 :         if (be16_to_cpu(entry->nameidx) < ichdr->firstused)
    1657    62816660 :                 ichdr->firstused = be16_to_cpu(entry->nameidx);
    1658             : 
    1659   193694265 :         ASSERT(ichdr->firstused >= ichdr->count * sizeof(xfs_attr_leaf_entry_t)
    1660             :                                         + xfs_attr3_leaf_hdr_size(leaf));
    1661   193683942 :         tmp = (ichdr->count - 1) * sizeof(xfs_attr_leaf_entry_t)
    1662    96841971 :                                         + xfs_attr3_leaf_hdr_size(leaf);
    1663             : 
    1664   387359775 :         for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
    1665   290517804 :                 if (ichdr->freemap[i].base == tmp) {
    1666    96814932 :                         ichdr->freemap[i].base += sizeof(xfs_attr_leaf_entry_t);
    1667    96814932 :                         ichdr->freemap[i].size -=
    1668    96814932 :                                 min_t(uint16_t, ichdr->freemap[i].size,
    1669             :                                                 sizeof(xfs_attr_leaf_entry_t));
    1670             :                 }
    1671             :         }
    1672    96841971 :         ichdr->usedbytes += xfs_attr_leaf_entsize(leaf, args->index);
    1673    96841971 :         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      294665 : 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      294665 :         struct xfs_attr_leafblock *leaf_src;
    1686      294665 :         struct xfs_attr_leafblock *leaf_dst;
    1687      294665 :         struct xfs_attr3_icleaf_hdr ichdr_src;
    1688      294665 :         struct xfs_trans        *trans = args->trans;
    1689      294665 :         char                    *tmpbuffer;
    1690             : 
    1691      294665 :         trace_xfs_attr_leaf_compact(args);
    1692             : 
    1693      294664 :         tmpbuffer = kmem_alloc(args->geo->blksize, 0);
    1694      589330 :         memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
    1695      294665 :         memset(bp->b_addr, 0, args->geo->blksize);
    1696      294665 :         leaf_src = (xfs_attr_leafblock_t *)tmpbuffer;
    1697      294665 :         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      883995 :         memcpy(bp->b_addr, tmpbuffer, xfs_attr3_leaf_hdr_size(leaf_src));
    1705             : 
    1706             :         /* Initialise the incore headers */
    1707      294665 :         ichdr_src = *ichdr_dst; /* struct copy */
    1708      294665 :         ichdr_dst->firstused = args->geo->blksize;
    1709      294665 :         ichdr_dst->usedbytes = 0;
    1710      294665 :         ichdr_dst->count = 0;
    1711      294665 :         ichdr_dst->holes = 0;
    1712      294665 :         ichdr_dst->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_src);
    1713      294665 :         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      294665 :         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      294664 :         xfs_attr3_leaf_moveents(args, leaf_src, &ichdr_src, 0,
    1724      294664 :                                 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      294663 :         xfs_trans_log_buf(trans, bp, 0, args->geo->blksize - 1);
    1730             : 
    1731      294664 :         kmem_free(tmpbuffer);
    1732      294663 : }
    1733             : 
    1734             : /*
    1735             :  * Compare two leaf blocks "order".
    1736             :  * Return 0 unless leaf2 should go before leaf1.
    1737             :  */
    1738             : static int
    1739      121413 : 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      121413 :         struct xfs_attr_leaf_entry *entries1;
    1746      121413 :         struct xfs_attr_leaf_entry *entries2;
    1747             : 
    1748      121413 :         entries1 = xfs_attr3_leaf_entryp(leaf1_bp->b_addr);
    1749      121413 :         entries2 = xfs_attr3_leaf_entryp(leaf2_bp->b_addr);
    1750      182503 :         if (leaf1hdr->count > 0 && leaf2hdr->count > 0 &&
    1751       61090 :             ((be32_to_cpu(entries2[0].hashval) <
    1752      122061 :               be32_to_cpu(entries1[0].hashval)) ||
    1753       60971 :              (be32_to_cpu(entries2[leaf2hdr->count - 1].hashval) <
    1754       60971 :               be32_to_cpu(entries1[leaf1hdr->count - 1].hashval)))) {
    1755         119 :                 return 1;
    1756             :         }
    1757             :         return 0;
    1758             : }
    1759             : 
    1760             : int
    1761       60323 : xfs_attr_leaf_order(
    1762             :         struct xfs_buf  *leaf1_bp,
    1763             :         struct xfs_buf  *leaf2_bp)
    1764             : {
    1765       60323 :         struct xfs_attr3_icleaf_hdr ichdr1;
    1766       60323 :         struct xfs_attr3_icleaf_hdr ichdr2;
    1767       60323 :         struct xfs_mount *mp = leaf1_bp->b_mount;
    1768             : 
    1769       60323 :         xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr1, leaf1_bp->b_addr);
    1770       60322 :         xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr2, leaf2_bp->b_addr);
    1771       60323 :         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       60323 : 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       60323 :         struct xfs_da_args      *args;
    1793       60323 :         struct xfs_attr_leafblock *leaf1;
    1794       60323 :         struct xfs_attr_leafblock *leaf2;
    1795       60323 :         struct xfs_attr3_icleaf_hdr ichdr1;
    1796       60323 :         struct xfs_attr3_icleaf_hdr ichdr2;
    1797       60323 :         struct xfs_attr_leaf_entry *entries1;
    1798       60323 :         struct xfs_attr_leaf_entry *entries2;
    1799       60323 :         int                     count;
    1800       60323 :         int                     totallen;
    1801       60323 :         int                     max;
    1802       60323 :         int                     space;
    1803       60323 :         int                     swap;
    1804             : 
    1805             :         /*
    1806             :          * Set up environment.
    1807             :          */
    1808       60323 :         ASSERT(blk1->magic == XFS_ATTR_LEAF_MAGIC);
    1809       60323 :         ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC);
    1810       60323 :         leaf1 = blk1->bp->b_addr;
    1811       60323 :         leaf2 = blk2->bp->b_addr;
    1812       60323 :         xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr1, leaf1);
    1813       60323 :         xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr2, leaf2);
    1814       60323 :         ASSERT(ichdr2.count == 0);
    1815       60323 :         args = state->args;
    1816             : 
    1817       60323 :         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       60323 :         swap = 0;
    1826       60323 :         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       60323 :         state->inleaf = xfs_attr3_leaf_figure_balance(state, blk1, &ichdr1,
    1846             :                                                       blk2, &ichdr2,
    1847             :                                                       &count, &totallen);
    1848       60323 :         if (swap)
    1849           0 :                 state->inleaf = !state->inleaf;
    1850             : 
    1851             :         /*
    1852             :          * Move any entries required from leaf to leaf:
    1853             :          */
    1854       60323 :         if (count < ichdr1.count) {
    1855             :                 /*
    1856             :                  * Figure the total bytes to be added to the destination leaf.
    1857             :                  */
    1858             :                 /* number entries being moved */
    1859       60323 :                 count = ichdr1.count - count;
    1860       60323 :                 space  = ichdr1.usedbytes - totallen;
    1861       60323 :                 space += count * sizeof(xfs_attr_leaf_entry_t);
    1862             : 
    1863             :                 /*
    1864             :                  * leaf2 is the destination, compact it if it looks tight.
    1865             :                  */
    1866       60323 :                 max  = ichdr2.firstused - xfs_attr3_leaf_hdr_size(leaf1);
    1867       60323 :                 max -= ichdr2.count * sizeof(xfs_attr_leaf_entry_t);
    1868       60323 :                 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       60323 :                 xfs_attr3_leaf_moveents(args, leaf1, &ichdr1,
    1875       60323 :                                 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       60323 :         xfs_attr3_leaf_hdr_to_disk(state->args->geo, leaf1, &ichdr1);
    1908       60323 :         xfs_attr3_leaf_hdr_to_disk(state->args->geo, leaf2, &ichdr2);
    1909       60323 :         xfs_trans_log_buf(args->trans, blk1->bp, 0, args->geo->blksize - 1);
    1910       60323 :         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       60323 :         entries1 = xfs_attr3_leaf_entryp(leaf1);
    1916       60323 :         entries2 = xfs_attr3_leaf_entryp(leaf2);
    1917       60323 :         blk1->hashval = be32_to_cpu(entries1[ichdr1.count - 1].hashval);
    1918       60323 :         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       60323 :         if (blk1->index > ichdr1.count) {
    1933       46796 :                 ASSERT(state->inleaf == 0);
    1934       46796 :                 blk2->index = blk1->index - ichdr1.count;
    1935       46796 :                 args->index = args->index2 = blk2->index;
    1936       46796 :                 args->blkno = args->blkno2 = blk2->blkno;
    1937       13527 :         } else if (blk1->index == ichdr1.count) {
    1938        2787 :                 if (state->inleaf) {
    1939         926 :                         args->index = blk1->index;
    1940         926 :                         args->blkno = blk1->blkno;
    1941         926 :                         args->index2 = 0;
    1942         926 :                         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        1861 :                         blk2->index = blk1->index - ichdr1.count;
    1950        1861 :                         args->index = blk2->index;
    1951        1861 :                         args->blkno = blk2->blkno;
    1952        1861 :                         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        1861 :                                 args->index2 = blk2->index;
    1959        1861 :                                 args->blkno2 = blk2->blkno;
    1960             :                         }
    1961             :                 }
    1962             :         } else {
    1963       10740 :                 ASSERT(state->inleaf == 1);
    1964       10740 :                 args->index = args->index2 = blk1->index;
    1965       10740 :                 args->blkno = args->blkno2 = blk1->blkno;
    1966             :         }
    1967       60323 : }
    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       60323 : 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       60323 :         struct xfs_attr_leafblock       *leaf1 = blk1->bp->b_addr;
    1987       60323 :         struct xfs_attr_leafblock       *leaf2 = blk2->bp->b_addr;
    1988       60323 :         struct xfs_attr_leaf_entry      *entry;
    1989       60323 :         int                             count;
    1990       60323 :         int                             max;
    1991       60323 :         int                             index;
    1992       60323 :         int                             totallen = 0;
    1993       60323 :         int                             half;
    1994       60323 :         int                             lastdelta;
    1995       60323 :         int                             foundit = 0;
    1996       60323 :         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       60323 :         max = ichdr1->count + ichdr2->count;
    2003       60323 :         half = (max + 1) * sizeof(*entry);
    2004      120646 :         half += ichdr1->usedbytes + ichdr2->usedbytes +
    2005       60323 :                         xfs_attr_leaf_newentsize(state->args, NULL);
    2006       60323 :         half /= 2;
    2007       60323 :         lastdelta = state->args->geo->blksize;
    2008       60323 :         entry = xfs_attr3_leaf_entryp(leaf1);
    2009     1593917 :         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     1593917 :                 if (count == blk1->index) {
    2016       27054 :                         tmp = totallen + sizeof(*entry) +
    2017       13527 :                                 xfs_attr_leaf_newentsize(state->args, NULL);
    2018       13527 :                         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     1592056 :                 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     1592056 :                 tmp = totallen + sizeof(*entry) + xfs_attr_leaf_entsize(leaf1,
    2038             :                                                                         index);
    2039     1592056 :                 if (XFS_ATTR_ABS(half - tmp) > lastdelta)
    2040             :                         break;
    2041     1533594 :                 lastdelta = XFS_ATTR_ABS(half - tmp);
    2042     1533594 :                 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       60323 :         totallen -= count * sizeof(*entry);
    2051       60323 :         if (foundit) {
    2052       23332 :                 totallen -= sizeof(*entry) +
    2053       11666 :                                 xfs_attr_leaf_newentsize(state->args, NULL);
    2054             :         }
    2055             : 
    2056       60323 :         *countarg = count;
    2057       60323 :         *usedbytesarg = totallen;
    2058       60323 :         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      947004 : xfs_attr3_leaf_toosmall(
    2078             :         struct xfs_da_state     *state,
    2079             :         int                     *action)
    2080             : {
    2081      947004 :         struct xfs_attr_leafblock *leaf;
    2082      947004 :         struct xfs_da_state_blk *blk;
    2083      947004 :         struct xfs_attr3_icleaf_hdr ichdr;
    2084      947004 :         struct xfs_buf          *bp;
    2085      947004 :         xfs_dablk_t             blkno;
    2086      947004 :         int                     bytes;
    2087      947004 :         int                     forward;
    2088      947004 :         int                     error;
    2089      947004 :         int                     retval;
    2090      947004 :         int                     i;
    2091             : 
    2092      947004 :         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      947011 :         blk = &state->path.blk[ state->path.active-1 ];
    2100      947011 :         leaf = blk->bp->b_addr;
    2101      947011 :         xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr, leaf);
    2102      947011 :         bytes = xfs_attr3_leaf_hdr_size(leaf) +
    2103      947011 :                 ichdr.count * sizeof(xfs_attr_leaf_entry_t) +
    2104      947011 :                 ichdr.usedbytes;
    2105      947011 :         if (bytes > (state->args->geo->blksize >> 1)) {
    2106      633886 :                 *action = 0;    /* blk over 50%, don't try to join */
    2107      633886 :                 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      313125 :         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      313125 :         forward = ichdr.forw < ichdr.back;
    2144      938220 :         for (i = 0; i < 2; forward = !forward, i++) {
    2145      625865 :                 struct xfs_attr3_icleaf_hdr ichdr2;
    2146      625865 :                 if (forward)
    2147             :                         blkno = ichdr.forw;
    2148             :                 else
    2149      313075 :                         blkno = ichdr.back;
    2150      625865 :                 if (blkno == 0)
    2151      283432 :                         continue;
    2152      342433 :                 error = xfs_attr3_leaf_read(state->args->trans, state->args->dp,
    2153             :                                         state->args->owner, blkno, &bp);
    2154      342432 :                 if (error)
    2155           2 :                         return error;
    2156             : 
    2157      342430 :                 xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr2, bp->b_addr);
    2158             : 
    2159      684860 :                 bytes = state->args->geo->blksize -
    2160      342430 :                         (state->args->geo->blksize >> 2) -
    2161      342430 :                         ichdr.usedbytes - ichdr2.usedbytes -
    2162      342430 :                         ((ichdr.count + ichdr2.count) *
    2163      342430 :                                         sizeof(xfs_attr_leaf_entry_t)) -
    2164      342430 :                         xfs_attr3_leaf_hdr_size(leaf);
    2165             : 
    2166      342430 :                 xfs_trans_brelse(state->args->trans, bp);
    2167      342431 :                 if (bytes >= 0)
    2168             :                         break;  /* fits with at least 25% to spare */
    2169             :         }
    2170      313123 :         if (i >= 2) {
    2171      312355 :                 *action = 0;
    2172      312355 :                 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        1536 :         memcpy(&state->altpath, &state->path, sizeof(state->path));
    2180         768 :         if (blkno < blk->blkno) {
    2181         381 :                 error = xfs_da3_path_shift(state, &state->altpath, forward,
    2182             :                                                  0, &retval);
    2183             :         } else {
    2184         387 :                 error = xfs_da3_path_shift(state, &state->path, forward,
    2185             :                                                  0, &retval);
    2186             :         }
    2187         768 :         if (error)
    2188             :                 return error;
    2189         768 :         if (retval) {
    2190           0 :                 *action = 0;
    2191             :         } else {
    2192         768 :                 *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    46451714 : xfs_attr3_leaf_remove(
    2205             :         struct xfs_buf          *bp,
    2206             :         struct xfs_da_args      *args)
    2207             : {
    2208    46451714 :         struct xfs_attr_leafblock *leaf;
    2209    46451714 :         struct xfs_attr3_icleaf_hdr ichdr;
    2210    46451714 :         struct xfs_attr_leaf_entry *entry;
    2211    46451714 :         int                     before;
    2212    46451714 :         int                     after;
    2213    46451714 :         int                     smallest;
    2214    46451714 :         int                     entsize;
    2215    46451714 :         int                     tablesize;
    2216    46451714 :         int                     tmp;
    2217    46451714 :         int                     i;
    2218             : 
    2219    46451714 :         trace_xfs_attr_leaf_remove(args);
    2220             : 
    2221    46452065 :         leaf = bp->b_addr;
    2222    46452065 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    2223             : 
    2224    46451877 :         ASSERT(ichdr.count > 0 && ichdr.count < args->geo->blksize / 8);
    2225    46451877 :         ASSERT(args->index >= 0 && args->index < ichdr.count);
    2226    92899856 :         ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) +
    2227             :                                         xfs_attr3_leaf_hdr_size(leaf));
    2228             : 
    2229    46451877 :         entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
    2230             : 
    2231    46451877 :         ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
    2232    46451877 :         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    46451877 :         tablesize = ichdr.count * sizeof(xfs_attr_leaf_entry_t)
    2241    46451877 :                                         + xfs_attr3_leaf_hdr_size(leaf);
    2242    46451877 :         tmp = ichdr.freemap[0].size;
    2243    46451877 :         before = after = -1;
    2244    46451877 :         smallest = XFS_ATTR_LEAF_MAPSIZE - 1;
    2245    46451877 :         entsize = xfs_attr_leaf_entsize(leaf, args->index);
    2246   185807239 :         for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
    2247   139355776 :                 ASSERT(ichdr.freemap[i].base < args->geo->blksize);
    2248   139355776 :                 ASSERT(ichdr.freemap[i].size < args->geo->blksize);
    2249   139355362 :                 if (ichdr.freemap[i].base == tablesize) {
    2250    46381761 :                         ichdr.freemap[i].base -= sizeof(xfs_attr_leaf_entry_t);
    2251    46381761 :                         ichdr.freemap[i].size += sizeof(xfs_attr_leaf_entry_t);
    2252             :                 }
    2253             : 
    2254   139355362 :                 if (ichdr.freemap[i].base + ichdr.freemap[i].size ==
    2255   139355362 :                                 be16_to_cpu(entry->nameidx)) {
    2256             :                         before = i;
    2257   132048094 :                 } else if (ichdr.freemap[i].base ==
    2258   132048094 :                                 (be16_to_cpu(entry->nameidx) + entsize)) {
    2259             :                         after = i;
    2260   127541895 :                 } else if (ichdr.freemap[i].size < tmp) {
    2261    65856501 :                         tmp = ichdr.freemap[i].size;
    2262    65856501 :                         smallest = i;
    2263             :                 }
    2264             :         }
    2265             : 
    2266             :         /*
    2267             :          * Coalesce adjacent freemap regions,
    2268             :          * or replace the smallest region.
    2269             :          */
    2270    46451463 :         if ((before >= 0) || (after >= 0)) {
    2271    11226162 :                 if ((before >= 0) && (after >= 0)) {
    2272      588676 :                         ichdr.freemap[before].size += entsize;
    2273      588676 :                         ichdr.freemap[before].size += ichdr.freemap[after].size;
    2274      588676 :                         ichdr.freemap[after].base = 0;
    2275      588676 :                         ichdr.freemap[after].size = 0;
    2276    10637486 :                 } else if (before >= 0) {
    2277     6720004 :                         ichdr.freemap[before].size += entsize;
    2278             :                 } else {
    2279     3917482 :                         ichdr.freemap[after].base = be16_to_cpu(entry->nameidx);
    2280     3917482 :                         ichdr.freemap[after].size += entsize;
    2281             :                 }
    2282             :         } else {
    2283             :                 /*
    2284             :                  * Replace smallest region (if it is smaller than free'd entry)
    2285             :                  */
    2286    35225301 :                 if (ichdr.freemap[smallest].size < entsize) {
    2287    29062228 :                         ichdr.freemap[smallest].base = be16_to_cpu(entry->nameidx);
    2288    29062228 :                         ichdr.freemap[smallest].size = entsize;
    2289             :                 }
    2290             :         }
    2291             : 
    2292             :         /*
    2293             :          * Did we remove the first entry?
    2294             :          */
    2295    46451463 :         if (be16_to_cpu(entry->nameidx) == ichdr.firstused)
    2296             :                 smallest = 1;
    2297             :         else
    2298    43358030 :                 smallest = 0;
    2299             : 
    2300             :         /*
    2301             :          * Compress the remaining entries and zero out the removed stuff.
    2302             :          */
    2303    46451463 :         memset(xfs_attr3_leaf_name(leaf, args->index), 0, entsize);
    2304    46451463 :         ichdr.usedbytes -= entsize;
    2305    46451463 :         xfs_trans_log_buf(args->trans, bp,
    2306    46451463 :              XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index),
    2307             :                                    entsize));
    2308             : 
    2309    46451930 :         tmp = (ichdr.count - args->index) * sizeof(xfs_attr_leaf_entry_t);
    2310    92903860 :         memmove(entry, entry + 1, tmp);
    2311    46451930 :         ichdr.count--;
    2312    46451930 :         xfs_trans_log_buf(args->trans, bp,
    2313    46451930 :             XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(xfs_attr_leaf_entry_t)));
    2314             : 
    2315    46452060 :         entry = &xfs_attr3_leaf_entryp(leaf)[ichdr.count];
    2316    46452060 :         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    46452060 :         if (smallest) {
    2325     3093588 :                 tmp = args->geo->blksize;
    2326     3093588 :                 entry = xfs_attr3_leaf_entryp(leaf);
    2327    41675364 :                 for (i = ichdr.count - 1; i >= 0; entry++, i--) {
    2328    38581818 :                         ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
    2329    38581818 :                         ASSERT(be16_to_cpu(entry->nameidx) < args->geo->blksize);
    2330             : 
    2331    38581776 :                         if (be16_to_cpu(entry->nameidx) < tmp)
    2332             :                                 tmp = be16_to_cpu(entry->nameidx);
    2333             :                 }
    2334     3093546 :                 ichdr.firstused = tmp;
    2335     3093546 :                 ASSERT(ichdr.firstused != 0);
    2336             :         } else {
    2337    43358472 :                 ichdr.holes = 1;        /* mark as needing compaction */
    2338             :         }
    2339    46452018 :         xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr);
    2340    46450807 :         xfs_trans_log_buf(args->trans, bp,
    2341    46450807 :                           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    46450595 :         tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) +
    2349    46450595 :               ichdr.count * sizeof(xfs_attr_leaf_entry_t);
    2350             : 
    2351    46450595 :         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         768 : 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         768 :         struct xfs_attr_leafblock *drop_leaf = drop_blk->bp->b_addr;
    2364         768 :         struct xfs_attr_leafblock *save_leaf = save_blk->bp->b_addr;
    2365         768 :         struct xfs_attr3_icleaf_hdr drophdr;
    2366         768 :         struct xfs_attr3_icleaf_hdr savehdr;
    2367         768 :         struct xfs_attr_leaf_entry *entry;
    2368             : 
    2369         768 :         trace_xfs_attr_leaf_unbalance(state->args);
    2370             : 
    2371         768 :         xfs_attr3_leaf_hdr_from_disk(state->args->geo, &drophdr, drop_leaf);
    2372         768 :         xfs_attr3_leaf_hdr_from_disk(state->args->geo, &savehdr, save_leaf);
    2373         768 :         entry = xfs_attr3_leaf_entryp(drop_leaf);
    2374             : 
    2375             :         /*
    2376             :          * Save last hashval from dying block for later Btree fixup.
    2377             :          */
    2378         768 :         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         768 :         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           1 :                 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           0 :                         xfs_attr3_leaf_moveents(state->args,
    2398             :                                                 drop_leaf, &drophdr, 0,
    2399             :                                                 save_leaf, &savehdr,
    2400           0 :                                                 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         767 :                 struct xfs_attr_leafblock *tmp_leaf;
    2408         767 :                 struct xfs_attr3_icleaf_hdr tmphdr;
    2409             : 
    2410         767 :                 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        2301 :                 memcpy(tmp_leaf, save_leaf, xfs_attr3_leaf_hdr_size(save_leaf));
    2418             : 
    2419         767 :                 memset(&tmphdr, 0, sizeof(tmphdr));
    2420         767 :                 tmphdr.magic = savehdr.magic;
    2421         767 :                 tmphdr.forw = savehdr.forw;
    2422         767 :                 tmphdr.back = savehdr.back;
    2423         767 :                 tmphdr.firstused = state->args->geo->blksize;
    2424             : 
    2425             :                 /* write the header to the temp buffer to initialise it */
    2426         767 :                 xfs_attr3_leaf_hdr_to_disk(state->args->geo, tmp_leaf, &tmphdr);
    2427             : 
    2428         767 :                 if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
    2429             :                                          drop_blk->bp, &drophdr)) {
    2430         118 :                         xfs_attr3_leaf_moveents(state->args,
    2431             :                                                 drop_leaf, &drophdr, 0,
    2432             :                                                 tmp_leaf, &tmphdr, 0,
    2433         118 :                                                 drophdr.count);
    2434         118 :                         xfs_attr3_leaf_moveents(state->args,
    2435             :                                                 save_leaf, &savehdr, 0,
    2436         118 :                                                 tmp_leaf, &tmphdr, tmphdr.count,
    2437         118 :                                                 savehdr.count);
    2438             :                 } else {
    2439         649 :                         xfs_attr3_leaf_moveents(state->args,
    2440             :                                                 save_leaf, &savehdr, 0,
    2441             :                                                 tmp_leaf, &tmphdr, 0,
    2442         649 :                                                 savehdr.count);
    2443         649 :                         xfs_attr3_leaf_moveents(state->args,
    2444             :                                                 drop_leaf, &drophdr, 0,
    2445         649 :                                                 tmp_leaf, &tmphdr, tmphdr.count,
    2446         649 :                                                 drophdr.count);
    2447             :                 }
    2448        1534 :                 memcpy(save_leaf, tmp_leaf, state->args->geo->blksize);
    2449         767 :                 savehdr = tmphdr; /* struct copy */
    2450         767 :                 kmem_free(tmp_leaf);
    2451             :         }
    2452             : 
    2453         768 :         xfs_attr3_leaf_hdr_to_disk(state->args->geo, save_leaf, &savehdr);
    2454         768 :         xfs_trans_log_buf(state->args->trans, save_blk->bp, 0,
    2455         768 :                                            state->args->geo->blksize - 1);
    2456             : 
    2457             :         /*
    2458             :          * Copy out last hashval in each block for B-tree code.
    2459             :          */
    2460         768 :         entry = xfs_attr3_leaf_entryp(save_leaf);
    2461         768 :         save_blk->hashval = be32_to_cpu(entry[savehdr.count - 1].hashval);
    2462         768 : }
    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   565000107 : xfs_attr3_leaf_lookup_int(
    2483             :         struct xfs_buf          *bp,
    2484             :         struct xfs_da_args      *args)
    2485             : {
    2486   565000107 :         struct xfs_attr_leafblock *leaf;
    2487   565000107 :         struct xfs_attr3_icleaf_hdr ichdr;
    2488   565000107 :         struct xfs_attr_leaf_entry *entry;
    2489   565000107 :         struct xfs_attr_leaf_entry *entries;
    2490   565000107 :         struct xfs_attr_leaf_name_local *name_loc;
    2491   565000107 :         struct xfs_attr_leaf_name_remote *name_rmt;
    2492   565000107 :         xfs_dahash_t            hashval;
    2493   565000107 :         int                     probe;
    2494   565000107 :         int                     span;
    2495             : 
    2496   565000107 :         trace_xfs_attr_leaf_lookup(args);
    2497             : 
    2498   565027842 :         leaf = bp->b_addr;
    2499   565027842 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    2500   565275061 :         entries = xfs_attr3_leaf_entryp(leaf);
    2501   565275061 :         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   565275061 :         hashval = args->hashval;
    2511   565275061 :         probe = span = ichdr.count / 2;
    2512   843711970 :         for (entry = &entries[probe]; span > 4; entry = &entries[probe]) {
    2513   555263407 :                 span /= 2;
    2514  1110526814 :                 if (be32_to_cpu(entry->hashval) < hashval)
    2515   174008286 :                         probe += span;
    2516   381255121 :                 else if (be32_to_cpu(entry->hashval) > hashval)
    2517   104428623 :                         probe -= span;
    2518             :                 else
    2519             :                         break;
    2520             :         }
    2521   565275061 :         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   567102347 :         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  5827282101 :         while (probe > 0 && be32_to_cpu(entry->hashval) >= hashval) {
    2537  2517932931 :                 entry--;
    2538  2517932931 :                 probe--;
    2539             :         }
    2540  2078206943 :         while (probe < ichdr.count &&
    2541  1032021015 :                be32_to_cpu(entry->hashval) < hashval) {
    2542   480910867 :                 entry++;
    2543   480910867 :                 probe++;
    2544             :         }
    2545  1116410352 :         if (probe == ichdr.count || be32_to_cpu(entry->hashval) != hashval) {
    2546   160335154 :                 args->index = probe;
    2547   160335154 :                 return -ENOATTR;
    2548             :         }
    2549             : 
    2550             :         /*
    2551             :          * Duplicate keys may be present, so search all of them for a match.
    2552             :          */
    2553  9646149442 :         for (; probe < ichdr.count && (be32_to_cpu(entry->hashval) == hashval);
    2554  4569300536 :                         entry++, probe++) {
    2555             : /*
    2556             :  * GROT: Add code to remove incomplete entries.
    2557             :  */
    2558  4671835008 :                 if (entry->flags & XFS_ATTR_LOCAL) {
    2559  4671834569 :                         name_loc = xfs_attr3_leaf_name_local(leaf, probe);
    2560  9343663771 :                         if (!xfs_attr_match(args, name_loc->namelen,
    2561  4671834569 :                                         name_loc->nameval,
    2562  4671834569 :                                         be16_to_cpu(name_loc->valuelen),
    2563  4671834569 :                                         &name_loc->nameval[name_loc->namelen],
    2564             :                                         entry->flags))
    2565  4569300534 :                                 continue;
    2566   102528668 :                         args->index = probe;
    2567   102528668 :                         return -EEXIST;
    2568             :                 } else {
    2569         439 :                         name_rmt = xfs_attr3_leaf_name_remote(leaf, probe);
    2570         439 :                         if (!xfs_attr_match(args, name_rmt->namelen,
    2571         439 :                                         name_rmt->name, 0, NULL, entry->flags))
    2572           2 :                                 continue;
    2573         437 :                         args->index = probe;
    2574         437 :                         args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
    2575         437 :                         args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
    2576         874 :                         args->rmtblkcnt = xfs_attr3_rmt_blocks(
    2577         437 :                                                         args->dp->i_mount,
    2578             :                                                         args->rmtvaluelen);
    2579         437 :                         return -EEXIST;
    2580             :                 }
    2581             :         }
    2582   302405435 :         args->index = probe;
    2583   302405435 :         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    10559947 : xfs_attr3_leaf_getvalue(
    2596             :         struct xfs_buf          *bp,
    2597             :         struct xfs_da_args      *args)
    2598             : {
    2599    10559947 :         struct xfs_attr_leafblock *leaf;
    2600    10559947 :         struct xfs_attr3_icleaf_hdr ichdr;
    2601    10559947 :         struct xfs_attr_leaf_entry *entry;
    2602    10559947 :         struct xfs_attr_leaf_name_local *name_loc;
    2603    10559947 :         struct xfs_attr_leaf_name_remote *name_rmt;
    2604             : 
    2605    10559947 :         leaf = bp->b_addr;
    2606    10559947 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    2607    10560057 :         ASSERT(ichdr.count < args->geo->blksize / 8);
    2608    10560057 :         ASSERT(args->index < ichdr.count);
    2609             : 
    2610    10560057 :         entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
    2611    10560057 :         if (entry->flags & XFS_ATTR_LOCAL) {
    2612    10559593 :                 name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
    2613    10559593 :                 ASSERT(name_loc->namelen == args->namelen);
    2614    21119186 :                 ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0);
    2615    10559593 :                 return xfs_attr_copy_value(args,
    2616    10559593 :                                         &name_loc->nameval[args->namelen],
    2617    10559593 :                                         be16_to_cpu(name_loc->valuelen));
    2618             :         }
    2619             : 
    2620         464 :         name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
    2621         464 :         ASSERT(name_rmt->namelen == args->namelen);
    2622         928 :         ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0);
    2623         464 :         args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
    2624         464 :         args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
    2625         464 :         args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount,
    2626             :                                                args->rmtvaluelen);
    2627         464 :         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      356522 : 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      356522 :         struct xfs_attr_leaf_entry      *entry_s;
    2651      356522 :         struct xfs_attr_leaf_entry      *entry_d;
    2652      356522 :         int                             desti;
    2653      356522 :         int                             tmp;
    2654      356522 :         int                             i;
    2655             : 
    2656             :         /*
    2657             :          * Check for nothing to do.
    2658             :          */
    2659      356522 :         if (count == 0)
    2660             :                 return;
    2661             : 
    2662             :         /*
    2663             :          * Set up environment.
    2664             :          */
    2665      356522 :         ASSERT(ichdr_s->magic == XFS_ATTR_LEAF_MAGIC ||
    2666             :                ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC);
    2667      356522 :         ASSERT(ichdr_s->magic == ichdr_d->magic);
    2668      356522 :         ASSERT(ichdr_s->count > 0 && ichdr_s->count < args->geo->blksize / 8);
    2669      713044 :         ASSERT(ichdr_s->firstused >= (ichdr_s->count * sizeof(*entry_s))
    2670             :                                         + xfs_attr3_leaf_hdr_size(leaf_s));
    2671      356522 :         ASSERT(ichdr_d->count < args->geo->blksize / 8);
    2672      713044 :         ASSERT(ichdr_d->firstused >= (ichdr_d->count * sizeof(*entry_d))
    2673             :                                         + xfs_attr3_leaf_hdr_size(leaf_d));
    2674             : 
    2675      356522 :         ASSERT(start_s < ichdr_s->count);
    2676      356522 :         ASSERT(start_d <= ichdr_d->count);
    2677      356522 :         ASSERT(count <= ichdr_s->count);
    2678             : 
    2679             : 
    2680             :         /*
    2681             :          * Move the entries in the destination leaf up to make a hole?
    2682             :          */
    2683      356522 :         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      356522 :         entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
    2696      356522 :         entry_d = &xfs_attr3_leaf_entryp(leaf_d)[start_d];
    2697      356522 :         desti = start_d;
    2698    16264470 :         for (i = 0; i < count; entry_s++, entry_d++, desti++, i++) {
    2699    15907947 :                 ASSERT(be16_to_cpu(entry_s->nameidx) >= ichdr_s->firstused);
    2700    15907947 :                 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    15907947 :                         ichdr_d->firstused -= tmp;
    2718             :                         /* both on-disk, don't endian flip twice */
    2719    15907947 :                         entry_d->hashval = entry_s->hashval;
    2720    15907947 :                         entry_d->nameidx = cpu_to_be16(ichdr_d->firstused);
    2721    15907947 :                         entry_d->flags = entry_s->flags;
    2722    15907947 :                         ASSERT(be16_to_cpu(entry_d->nameidx) + tmp
    2723             :                                                         <= args->geo->blksize);
    2724    15907947 :                         memmove(xfs_attr3_leaf_name(leaf_d, desti),
    2725             :                                 xfs_attr3_leaf_name(leaf_s, start_s + i), tmp);
    2726    15907947 :                         ASSERT(be16_to_cpu(entry_s->nameidx) + tmp
    2727             :                                                         <= args->geo->blksize);
    2728    15907947 :                         memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp);
    2729    15907947 :                         ichdr_s->usedbytes -= tmp;
    2730    15907947 :                         ichdr_d->usedbytes += tmp;
    2731    15907947 :                         ichdr_s->count -= 1;
    2732    15907947 :                         ichdr_d->count += 1;
    2733    15907947 :                         tmp = ichdr_d->count * sizeof(xfs_attr_leaf_entry_t)
    2734    15907947 :                                         + xfs_attr3_leaf_hdr_size(leaf_d);
    2735    15907947 :                         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      356523 :         if (start_s == ichdr_s->count) {
    2745      356523 :                 tmp = count * sizeof(xfs_attr_leaf_entry_t);
    2746      356523 :                 entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
    2747      356523 :                 ASSERT(((char *)entry_s + tmp) <=
    2748             :                        ((char *)leaf_s + args->geo->blksize));
    2749      713046 :                 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      356523 :         ichdr_d->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_d);
    2771      356523 :         ichdr_d->freemap[0].base += ichdr_d->count * sizeof(xfs_attr_leaf_entry_t);
    2772      356523 :         ichdr_d->freemap[0].size = ichdr_d->firstused - ichdr_d->freemap[0].base;
    2773      356523 :         ichdr_d->freemap[1].base = 0;
    2774      356523 :         ichdr_d->freemap[2].base = 0;
    2775      356523 :         ichdr_d->freemap[1].size = 0;
    2776      356523 :         ichdr_d->freemap[2].size = 0;
    2777      356523 :         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   312440462 : xfs_attr_leaf_lasthash(
    2785             :         struct xfs_buf  *bp,
    2786             :         int             *count)
    2787             : {
    2788   312440462 :         struct xfs_attr3_icleaf_hdr ichdr;
    2789   312440462 :         struct xfs_attr_leaf_entry *entries;
    2790   312440462 :         struct xfs_mount *mp = bp->b_mount;
    2791             : 
    2792   312440462 :         xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, bp->b_addr);
    2793   312440427 :         entries = xfs_attr3_leaf_entryp(bp->b_addr);
    2794   312440427 :         if (count)
    2795     3869985 :                 *count = ichdr.count;
    2796   312440427 :         if (!ichdr.count)
    2797             :                 return 0;
    2798   312440421 :         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   257573562 : xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
    2807             : {
    2808   257573562 :         struct xfs_attr_leaf_entry *entries;
    2809   257573562 :         xfs_attr_leaf_name_local_t *name_loc;
    2810   257573562 :         xfs_attr_leaf_name_remote_t *name_rmt;
    2811   257573562 :         int size;
    2812             : 
    2813   257573562 :         entries = xfs_attr3_leaf_entryp(leaf);
    2814   257573562 :         if (entries[index].flags & XFS_ATTR_LOCAL) {
    2815   257572492 :                 name_loc = xfs_attr3_leaf_name_local(leaf, index);
    2816   257572492 :                 size = xfs_attr_leaf_entsize_local(name_loc->namelen,
    2817   257572492 :                                                    be16_to_cpu(name_loc->valuelen));
    2818             :         } else {
    2819        1070 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf, index);
    2820        1070 :                 size = xfs_attr_leaf_entsize_remote(name_rmt->namelen);
    2821             :         }
    2822   257573562 :         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   404251346 : xfs_attr_leaf_newentsize(
    2833             :         struct xfs_da_args      *args,
    2834             :         int                     *local)
    2835             : {
    2836   404251346 :         int                     size;
    2837             : 
    2838   404251346 :         size = xfs_attr_leaf_entsize_local(args->namelen, args->valuelen);
    2839   404251346 :         if (size < xfs_attr_leaf_entsize_local_max(args->geo->blksize)) {
    2840   404249108 :                 if (local)
    2841   210400663 :                         *local = 1;
    2842   404249108 :                 return size;
    2843             :         }
    2844        2238 :         if (local)
    2845        1184 :                 *local = 0;
    2846        2238 :         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         525 : xfs_attr3_leaf_clearflag(
    2859             :         struct xfs_da_args      *args)
    2860             : {
    2861         525 :         struct xfs_attr_leafblock *leaf;
    2862         525 :         struct xfs_attr_leaf_entry *entry;
    2863         525 :         struct xfs_attr_leaf_name_remote *name_rmt;
    2864         525 :         struct xfs_buf          *bp;
    2865         525 :         int                     error;
    2866             : #ifdef DEBUG
    2867         525 :         struct xfs_attr3_icleaf_hdr ichdr;
    2868         525 :         xfs_attr_leaf_name_local_t *name_loc;
    2869         525 :         int namelen;
    2870         525 :         char *name;
    2871             : #endif /* DEBUG */
    2872             : 
    2873         525 :         trace_xfs_attr_leaf_clearflag(args);
    2874             :         /*
    2875             :          * Set up the operation.
    2876             :          */
    2877         525 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
    2878             :                         args->blkno, &bp);
    2879         525 :         if (error)
    2880             :                 return error;
    2881             : 
    2882         525 :         leaf = bp->b_addr;
    2883         525 :         entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
    2884         525 :         ASSERT(entry->flags & XFS_ATTR_INCOMPLETE);
    2885             : 
    2886             : #ifdef DEBUG
    2887         525 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    2888         525 :         ASSERT(args->index < ichdr.count);
    2889         525 :         ASSERT(args->index >= 0);
    2890             : 
    2891         525 :         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         525 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
    2897         525 :                 namelen = name_rmt->namelen;
    2898         525 :                 name = (char *)name_rmt->name;
    2899             :         }
    2900        1050 :         ASSERT(be32_to_cpu(entry->hashval) == args->hashval);
    2901         525 :         ASSERT(namelen == args->namelen);
    2902        1050 :         ASSERT(memcmp(name, args->name, namelen) == 0);
    2903             : #endif /* DEBUG */
    2904             : 
    2905         525 :         entry->flags &= ~XFS_ATTR_INCOMPLETE;
    2906         525 :         xfs_trans_log_buf(args->trans, bp,
    2907         525 :                          XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
    2908             : 
    2909         525 :         if (args->rmtblkno) {
    2910         525 :                 ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0);
    2911         525 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
    2912         525 :                 name_rmt->valueblk = cpu_to_be32(args->rmtblkno);
    2913         525 :                 name_rmt->valuelen = cpu_to_be32(args->rmtvaluelen);
    2914         525 :                 xfs_trans_log_buf(args->trans, bp,
    2915         525 :                          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      600436 : xfs_attr3_leaf_setflag(
    2926             :         struct xfs_da_args      *args)
    2927             : {
    2928      600436 :         struct xfs_attr_leafblock *leaf;
    2929      600436 :         struct xfs_attr_leaf_entry *entry;
    2930      600436 :         struct xfs_attr_leaf_name_remote *name_rmt;
    2931      600436 :         struct xfs_buf          *bp;
    2932      600436 :         int error;
    2933             : #ifdef DEBUG
    2934      600436 :         struct xfs_attr3_icleaf_hdr ichdr;
    2935             : #endif
    2936             : 
    2937      600436 :         trace_xfs_attr_leaf_setflag(args);
    2938             : 
    2939             :         /*
    2940             :          * Set up the operation.
    2941             :          */
    2942      600437 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
    2943             :                         args->blkno, &bp);
    2944      600437 :         if (error)
    2945             :                 return error;
    2946             : 
    2947      600437 :         leaf = bp->b_addr;
    2948             : #ifdef DEBUG
    2949      600437 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    2950      600436 :         ASSERT(args->index < ichdr.count);
    2951      600436 :         ASSERT(args->index >= 0);
    2952             : #endif
    2953      600436 :         entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
    2954             : 
    2955      600436 :         ASSERT((entry->flags & XFS_ATTR_INCOMPLETE) == 0);
    2956      600436 :         entry->flags |= XFS_ATTR_INCOMPLETE;
    2957      600436 :         xfs_trans_log_buf(args->trans, bp,
    2958      600436 :                         XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
    2959      600437 :         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    17396390 : xfs_attr3_leaf_flipflags(
    2979             :         struct xfs_da_args      *args)
    2980             : {
    2981    17396390 :         struct xfs_attr_leafblock *leaf1;
    2982    17396390 :         struct xfs_attr_leafblock *leaf2;
    2983    17396390 :         struct xfs_attr_leaf_entry *entry1;
    2984    17396390 :         struct xfs_attr_leaf_entry *entry2;
    2985    17396390 :         struct xfs_attr_leaf_name_remote *name_rmt;
    2986    17396390 :         struct xfs_buf          *bp1;
    2987    17396390 :         struct xfs_buf          *bp2;
    2988    17396390 :         int error;
    2989             : #ifdef DEBUG
    2990    17396390 :         struct xfs_attr3_icleaf_hdr ichdr1;
    2991    17396390 :         struct xfs_attr3_icleaf_hdr ichdr2;
    2992    17396390 :         xfs_attr_leaf_name_local_t *name_loc;
    2993    17396390 :         int namelen1, namelen2;
    2994    17396390 :         char *name1, *name2;
    2995             : #endif /* DEBUG */
    2996             : 
    2997    17396390 :         trace_xfs_attr_leaf_flipflags(args);
    2998             : 
    2999             :         /*
    3000             :          * Read the block containing the "old" attr
    3001             :          */
    3002    17397366 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
    3003             :                         args->blkno, &bp1);
    3004    17397306 :         if (error)
    3005             :                 return error;
    3006             : 
    3007             :         /*
    3008             :          * Read the block containing the "new" attr, if it is different
    3009             :          */
    3010    17397306 :         if (args->blkno2 != args->blkno) {
    3011         189 :                 error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
    3012             :                                 args->blkno2, &bp2);
    3013         189 :                 if (error)
    3014             :                         return error;
    3015             :         } else {
    3016    17397117 :                 bp2 = bp1;
    3017             :         }
    3018             : 
    3019    17397306 :         leaf1 = bp1->b_addr;
    3020    17397306 :         entry1 = &xfs_attr3_leaf_entryp(leaf1)[args->index];
    3021             : 
    3022    17397306 :         leaf2 = bp2->b_addr;
    3023    17397306 :         entry2 = &xfs_attr3_leaf_entryp(leaf2)[args->index2];
    3024             : 
    3025             : #ifdef DEBUG
    3026    17397306 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr1, leaf1);
    3027    17397378 :         ASSERT(args->index < ichdr1.count);
    3028    17397378 :         ASSERT(args->index >= 0);
    3029             : 
    3030    17397378 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr2, leaf2);
    3031    17396651 :         ASSERT(args->index2 < ichdr2.count);
    3032    17396651 :         ASSERT(args->index2 >= 0);
    3033             : 
    3034    17396651 :         if (entry1->flags & XFS_ATTR_LOCAL) {
    3035    17396649 :                 name_loc = xfs_attr3_leaf_name_local(leaf1, args->index);
    3036    17396649 :                 namelen1 = name_loc->namelen;
    3037    17396649 :                 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    17396651 :         if (entry2->flags & XFS_ATTR_LOCAL) {
    3044    17397380 :                 name_loc = xfs_attr3_leaf_name_local(leaf2, args->index2);
    3045    17397380 :                 namelen2 = name_loc->namelen;
    3046    17397380 :                 name2 = (char *)name_loc->nameval;
    3047             :         } else {
    3048           6 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf2, args->index2);
    3049           6 :                 namelen2 = name_rmt->namelen;
    3050           6 :                 name2 = (char *)name_rmt->name;
    3051             :         }
    3052    52189953 :         ASSERT(be32_to_cpu(entry1->hashval) == be32_to_cpu(entry2->hashval));
    3053    17396651 :         ASSERT(namelen1 == namelen2);
    3054    34793302 :         ASSERT(memcmp(name1, name2, namelen1) == 0);
    3055             : #endif /* DEBUG */
    3056             : 
    3057    17396651 :         ASSERT(entry1->flags & XFS_ATTR_INCOMPLETE);
    3058    17396651 :         ASSERT((entry2->flags & XFS_ATTR_INCOMPLETE) == 0);
    3059             : 
    3060    17396651 :         entry1->flags &= ~XFS_ATTR_INCOMPLETE;
    3061    17396651 :         xfs_trans_log_buf(args->trans, bp1,
    3062    17396651 :                           XFS_DA_LOGRANGE(leaf1, entry1, sizeof(*entry1)));
    3063    17396708 :         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    17396708 :         entry2->flags |= XFS_ATTR_INCOMPLETE;
    3073    17396708 :         xfs_trans_log_buf(args->trans, bp2,
    3074    17396708 :                           XFS_DA_LOGRANGE(leaf2, entry2, sizeof(*entry2)));
    3075    17397210 :         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