LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_attr_leaf.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsx @ Mon Jul 31 20:08:34 PDT 2023 Lines: 1305 1447 90.2 %
Date: 2023-07-31 20:08:34 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  3484327923 : 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  3484327923 :         struct xfs_attr3_leaf_hdr       *hdr3;
     101             : 
     102  3484327923 :         if (from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)) {
     103  3484327923 :                 hdr3 = (struct xfs_attr3_leaf_hdr *) from;
     104  3484327923 :                 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  3484327923 :         if (to->firstused == XFS_ATTR3_LEAF_NULLOFF) {
     115           0 :                 ASSERT(!to->count && !to->usedbytes);
     116           0 :                 ASSERT(geo->blksize > USHRT_MAX);
     117           0 :                 to->firstused = geo->blksize;
     118             :         }
     119  3484327923 : }
     120             : 
     121             : static void
     122   284192050 : 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   284192050 :         struct xfs_attr3_leaf_hdr       *hdr3;
     128   284192050 :         uint32_t                        firstused;
     129             : 
     130             :         /* magic value should only be seen on disk */
     131   284192050 :         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   284192050 :         firstused = from->firstused;
     139   284192050 :         if (firstused > USHRT_MAX) {
     140           0 :                 ASSERT(from->firstused == geo->blksize);
     141             :                 firstused = XFS_ATTR3_LEAF_NULLOFF;
     142             :         }
     143             : 
     144   284192050 :         if (from->magic == XFS_ATTR3_LEAF_MAGIC) {
     145   284192050 :                 hdr3 = (struct xfs_attr3_leaf_hdr *) to;
     146   284192050 :                 hdr3->firstused = cpu_to_be16(firstused);
     147             :         } else {
     148           0 :                 to->hdr.firstused = cpu_to_be16(firstused);
     149             :         }
     150   284192050 : }
     151             : 
     152             : void
     153  3484681891 : 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  3484681891 :         int     i;
     159             : 
     160  3484681891 :         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  3484681891 :         if (from->hdr.info.magic == cpu_to_be16(XFS_ATTR3_LEAF_MAGIC)) {
     164  3484681891 :                 struct xfs_attr3_leaf_hdr *hdr3 = (struct xfs_attr3_leaf_hdr *)from;
     165             : 
     166  3484681891 :                 to->forw = be32_to_cpu(hdr3->info.hdr.forw);
     167  3484681891 :                 to->back = be32_to_cpu(hdr3->info.hdr.back);
     168  3484681891 :                 to->magic = be16_to_cpu(hdr3->info.hdr.magic);
     169  3484681891 :                 to->count = be16_to_cpu(hdr3->count);
     170  3484681891 :                 to->usedbytes = be16_to_cpu(hdr3->usedbytes);
     171  3484681891 :                 xfs_attr3_leaf_firstused_from_disk(geo, to, from);
     172  3484682307 :                 to->holes = hdr3->holes;
     173             : 
     174 13932442441 :                 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
     175 10449189383 :                         to->freemap[i].base = be16_to_cpu(hdr3->freemap[i].base);
     176 10447942493 :                         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   284312891 : 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   284312891 :         int                             i;
     201             : 
     202   284312891 :         ASSERT(from->magic == XFS_ATTR_LEAF_MAGIC ||
     203             :                from->magic == XFS_ATTR3_LEAF_MAGIC);
     204             : 
     205   284312891 :         if (from->magic == XFS_ATTR3_LEAF_MAGIC) {
     206   284312891 :                 struct xfs_attr3_leaf_hdr *hdr3 = (struct xfs_attr3_leaf_hdr *)to;
     207             : 
     208   284312891 :                 hdr3->info.hdr.forw = cpu_to_be32(from->forw);
     209   284312891 :                 hdr3->info.hdr.back = cpu_to_be32(from->back);
     210   284312891 :                 hdr3->info.hdr.magic = cpu_to_be16(from->magic);
     211   284312891 :                 hdr3->count = cpu_to_be16(from->count);
     212   284312891 :                 hdr3->usedbytes = cpu_to_be16(from->usedbytes);
     213   284312891 :                 xfs_attr3_leaf_firstused_to_disk(geo, to, from);
     214   284293089 :                 hdr3->holes = from->holes;
     215   284293089 :                 hdr3->pad1 = 0;
     216             : 
     217  1135702688 :                 for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
     218   851871098 :                         hdr3->freemap[i].base = cpu_to_be16(from->freemap[i].base);
     219   851657872 :                         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   848704048 : 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   848704048 :         struct xfs_attr_leaf_name_local         *lentry;
     249   848704048 :         struct xfs_attr_leaf_name_remote        *rentry;
     250   848704048 :         char                                    *name_end;
     251   848704048 :         unsigned int                            nameidx;
     252   848704048 :         unsigned int                            namesize;
     253   848704048 :         __u32                                   hashval;
     254             : 
     255             :         /* hash order check */
     256   848704048 :         hashval = be32_to_cpu(ent->hashval);
     257   848704048 :         if (hashval < *last_hashval)
     258           0 :                 return __this_address;
     259   848704048 :         *last_hashval = hashval;
     260             : 
     261   848704048 :         nameidx = be16_to_cpu(ent->nameidx);
     262   848704048 :         if (nameidx < leafhdr->firstused || nameidx >= mp->m_attr_geo->blksize)
     263           0 :                 return __this_address;
     264             : 
     265             :         /*
     266             :          * Check the name information.  The namelen fields are u8 so we can't
     267             :          * possibly exceed the maximum name length of 255 bytes.
     268             :          */
     269   848704048 :         if (ent->flags & XFS_ATTR_LOCAL) {
     270   848699369 :                 lentry = xfs_attr3_leaf_name_local(leaf, idx);
     271   848699369 :                 namesize = xfs_attr_leaf_entsize_local(lentry->namelen,
     272   848699369 :                                 be16_to_cpu(lentry->valuelen));
     273   848699369 :                 name_end = (char *)lentry + namesize;
     274   848699369 :                 if (lentry->namelen == 0)
     275           0 :                         return __this_address;
     276             :         } else {
     277        4679 :                 rentry = xfs_attr3_leaf_name_remote(leaf, idx);
     278        4679 :                 namesize = xfs_attr_leaf_entsize_remote(rentry->namelen);
     279        4679 :                 name_end = (char *)rentry + namesize;
     280        4679 :                 if (rentry->namelen == 0)
     281           0 :                         return __this_address;
     282        4679 :                 if (!(ent->flags & XFS_ATTR_INCOMPLETE) &&
     283        4675 :                     rentry->valueblk == 0)
     284           0 :                         return __this_address;
     285             :         }
     286             : 
     287   848704048 :         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    45126067 : xfs_attr3_leaf_verify(
     312             :         struct xfs_buf                  *bp)
     313             : {
     314    45126067 :         struct xfs_attr3_icleaf_hdr     ichdr;
     315    45126067 :         struct xfs_mount                *mp = bp->b_mount;
     316    45126067 :         struct xfs_attr_leafblock       *leaf = bp->b_addr;
     317    45126067 :         struct xfs_attr_leaf_entry      *entries;
     318    45126067 :         struct xfs_attr_leaf_entry      *ent;
     319    45126067 :         char                            *buf_end;
     320    45126067 :         uint32_t                        end;    /* must be 32bit - see below */
     321    45126067 :         __u32                           last_hashval = 0;
     322    45126067 :         int                             i;
     323    45126067 :         xfs_failaddr_t                  fa;
     324             : 
     325    45126067 :         xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
     326             : 
     327    45128698 :         fa = xfs_da3_blkinfo_verify(bp, bp->b_addr);
     328    45119315 :         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    45115865 :         if (ichdr.firstused > mp->m_attr_geo->blksize)
     336           0 :                 return __this_address;
     337    90234216 :         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    45115865 :         entries = xfs_attr3_leaf_entryp(bp->b_addr);
     342    45115865 :         if ((char *)&entries[ichdr.count] >
     343    45115865 :             (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    45115865 :         buf_end = (char *)bp->b_addr + mp->m_attr_geo->blksize;
     354   893814059 :         for (i = 0, ent = entries; i < ichdr.count; ent++, i++) {
     355   848674144 :                 fa = xfs_attr3_leaf_verify_entry(mp, buf_end, leaf, &ichdr,
     356             :                                 ent, i, &last_hashval);
     357   848698194 :                 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   180556283 :         for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
     371   135416477 :                 if (ichdr.freemap[i].base > mp->m_attr_geo->blksize)
     372           0 :                         return __this_address;
     373   135417005 :                 if (ichdr.freemap[i].base & 0x3)
     374           0 :                         return __this_address;
     375   135416959 :                 if (ichdr.freemap[i].size > mp->m_attr_geo->blksize)
     376           0 :                         return __this_address;
     377   135416959 :                 if (ichdr.freemap[i].size & 0x3)
     378           0 :                         return __this_address;
     379             : 
     380             :                 /* be care of 16 bit overflows here */
     381   135416670 :                 end = (uint32_t)ichdr.freemap[i].base + ichdr.freemap[i].size;
     382   135416610 :                 if (end < ichdr.freemap[i].base)
     383           0 :                         return __this_address;
     384   135416368 :                 if (end > mp->m_attr_geo->blksize)
     385           0 :                         return __this_address;
     386             :         }
     387             : 
     388             :         return NULL;
     389             : }
     390             : 
     391             : xfs_failaddr_t
     392  1927869015 : xfs_attr3_leaf_header_check(
     393             :         struct xfs_buf          *bp,
     394             :         xfs_ino_t               owner)
     395             : {
     396  1927869015 :         struct xfs_mount        *mp = bp->b_mount;
     397             : 
     398  1927869015 :         if (xfs_has_crc(mp)) {
     399  1927869015 :                 struct xfs_attr3_leafblock *hdr3 = bp->b_addr;
     400             : 
     401  1927869015 :                 ASSERT(hdr3->hdr.info.hdr.magic ==
     402             :                                 cpu_to_be16(XFS_ATTR3_LEAF_MAGIC));
     403             : 
     404  1927869015 :                 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    42096876 : xfs_attr3_leaf_write_verify(
     413             :         struct xfs_buf  *bp)
     414             : {
     415    42096876 :         struct xfs_mount        *mp = bp->b_mount;
     416    42096876 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     417    42096876 :         struct xfs_attr3_leaf_hdr *hdr3 = bp->b_addr;
     418    42096876 :         xfs_failaddr_t          fa;
     419             : 
     420    42096876 :         fa = xfs_attr3_leaf_verify(bp);
     421    42096876 :         if (fa) {
     422           0 :                 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
     423           0 :                 return;
     424             :         }
     425             : 
     426    42096876 :         if (!xfs_has_crc(mp))
     427             :                 return;
     428             : 
     429    42096876 :         if (bip)
     430    42096876 :                 hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
     431             : 
     432    42096876 :         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      106682 : xfs_attr3_leaf_read_verify(
     443             :         struct xfs_buf          *bp)
     444             : {
     445      106682 :         struct xfs_mount        *mp = bp->b_mount;
     446      106682 :         xfs_failaddr_t          fa;
     447             : 
     448      213364 :         if (xfs_has_crc(mp) &&
     449             :              !xfs_buf_verify_cksum(bp, XFS_ATTR3_LEAF_CRC_OFF))
     450          21 :                 xfs_verifier_error(bp, -EFSBADCRC, __this_address);
     451             :         else {
     452      106661 :                 fa = xfs_attr3_leaf_verify(bp);
     453      106661 :                 if (fa)
     454           0 :                         xfs_verifier_error(bp, -EFSCORRUPTED, fa);
     455             :         }
     456      106682 : }
     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  1334978236 : 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  1334978236 :         xfs_failaddr_t          fa;
     476  1334978236 :         int                     err;
     477             : 
     478  1334978236 :         err = xfs_da_read_buf(tp, dp, bno, 0, bpp, XFS_ATTR_FORK,
     479             :                         &xfs_attr3_leaf_buf_ops);
     480  1335267823 :         if (err || !(*bpp))
     481             :                 return err;
     482             : 
     483  1335267740 :         fa = xfs_attr3_leaf_header_check(*bpp, owner);
     484  1335476637 :         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  1335476637 :         if (tp)
     493   740728494 :                 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  6021980533 : 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  6021980533 :         if (args->namelen != namelen)
     520             :                 return false;
     521 11240887678 :         if (memcmp(args->name, name, namelen) != 0)
     522             :                 return false;
     523             : 
     524   584845953 :         if (args->op_flags & XFS_DA_OP_NVLOOKUP) {
     525   322440476 :                 if (args->valuelen != valuelen)
     526             :                         return false;
     527   322331229 :                 if (args->valuelen && !value) {
     528             :                         /* not implemented for remote values */
     529           0 :                         ASSERT(0);
     530           0 :                         return false;
     531             :                 }
     532   322331229 :                 if (valuelen && !args->value) {
     533             :                         /* caller gave us valuelen > 0 but no value?? */
     534           0 :                         ASSERT(0);
     535           0 :                         return false;
     536             :                 }
     537   644662458 :                 if (valuelen > 0 && memcmp(args->value, value, valuelen) != 0)
     538             :                         return false;
     539             :         }
     540             : 
     541             :         /* Recovery ignores the INCOMPLETE flag. */
     542   546899750 :         if ((args->op_flags & XFS_DA_OP_RECOVERY) &&
     543         294 :             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   546899533 :         if (args->attr_filter !=
     548   546899533 :             (flags & (XFS_ATTR_NSP_ONDISK_MASK | XFS_ATTR_INCOMPLETE)))
     549      701931 :                 return false;
     550             :         return true;
     551             : }
     552             : 
     553             : static int
     554   183468825 : 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   183468825 :         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    23710217 :         if (!args->valuelen) {
     567    11912718 :                 args->valuelen = valuelen;
     568    11912718 :                 return 0;
     569             :         }
     570             : 
     571             :         /*
     572             :          * No copy if the length of the existing buffer is too small
     573             :          */
     574    11797499 :         if (args->valuelen < valuelen) {
     575           0 :                 args->valuelen = valuelen;
     576           0 :                 return -ERANGE;
     577             :         }
     578             : 
     579    11797499 :         if (!args->value) {
     580        1233 :                 args->value = kvmalloc(valuelen, GFP_KERNEL | __GFP_NOLOCKDEP);
     581        1233 :                 if (!args->value)
     582             :                         return -ENOMEM;
     583             :         }
     584    11797499 :         args->valuelen = valuelen;
     585             : 
     586             :         /* remote block xattr requires IO for copy-in */
     587    11797499 :         if (args->rmtblkno)
     588        1773 :                 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    11795726 :         if (!value)
     597             :                 return -EINVAL;
     598    23591452 :         memcpy(args->value, value, valuelen);
     599    11795726 :         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   479788708 : xfs_attr_shortform_bytesfit(
     618             :         struct xfs_inode        *dp,
     619             :         int                     bytes)
     620             : {
     621   479788708 :         struct xfs_mount        *mp = dp->i_mount;
     622   479788708 :         int64_t                 dsize;
     623   479788708 :         int                     minforkoff;
     624   479788708 :         int                     maxforkoff;
     625   479788708 :         int                     offset;
     626             : 
     627             :         /*
     628             :          * Check if the new size could fit at all first:
     629             :          */
     630   479788763 :         if (bytes > XFS_LITINO(mp))
     631             :                 return 0;
     632             : 
     633             :         /* rounded down */
     634   400472833 :         offset = (XFS_LITINO(mp) - bytes) >> 3;
     635             : 
     636   400472833 :         if (dp->i_df.if_format == XFS_DINODE_FMT_DEV) {
     637    50656861 :                 minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
     638    50656861 :                 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   349815972 :         if (bytes <= xfs_inode_attr_fork_size(dp))
     652   312503243 :                 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    37312729 :         if (!xfs_has_attr2(mp))
     660             :                 return 0;
     661             : 
     662    37312729 :         dsize = dp->i_df.if_bytes;
     663             : 
     664    37312729 :         switch (dp->i_df.if_format) {
     665    36310956 :         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    36310956 :                 if (!dp->i_forkoff && dp->i_df.if_bytes >
     674     4694241 :                     xfs_default_attroffset(dp))
     675        4614 :                         dsize = xfs_bmdr_space_calc(MINDBTPTRS);
     676             :                 break;
     677      266072 :         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      266072 :                 if (dp->i_forkoff) {
     685      263837 :                         if (offset < dp->i_forkoff)
     686             :                                 return 0;
     687           0 :                         return dp->i_forkoff;
     688             :                 }
     689        2235 :                 dsize = xfs_bmap_bmdr_space(dp->i_df.if_broot);
     690        2235 :                 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    37047604 :         minforkoff = max_t(int64_t, dsize, xfs_bmdr_space_calc(MINDBTPTRS));
     698    37047604 :         minforkoff = roundup(minforkoff, 8) >> 3;
     699             : 
     700             :         /* attr fork btree root can have at least this many key/ptr pairs */
     701    37047604 :         maxforkoff = XFS_LITINO(mp) - xfs_bmdr_space_calc(MINABTPTRS);
     702    37047604 :         maxforkoff = maxforkoff >> 3;     /* rounded down */
     703             : 
     704    37047604 :         if (offset >= maxforkoff)
     705             :                 return maxforkoff;
     706    32924538 :         if (offset >= minforkoff)
     707    21286833 :                 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   398328987 : xfs_sbversion_add_attr2(
     719             :         struct xfs_mount        *mp,
     720             :         struct xfs_trans        *tp)
     721             : {
     722   398328987 :         if (xfs_has_noattr2(mp))
     723             :                 return;
     724   398328987 :         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   112263843 : xfs_attr_shortform_create(
     740             :         struct xfs_da_args      *args)
     741             : {
     742   112263843 :         struct xfs_inode        *dp = args->dp;
     743   112263843 :         struct xfs_ifork        *ifp = &dp->i_af;
     744   112263843 :         struct xfs_attr_sf_hdr  *hdr;
     745             : 
     746   112263843 :         trace_xfs_attr_sf_create(args);
     747             : 
     748   112240889 :         ASSERT(ifp->if_bytes == 0);
     749   112240889 :         if (ifp->if_format == XFS_DINODE_FMT_EXTENTS)
     750   112240879 :                 ifp->if_format = XFS_DINODE_FMT_LOCAL;
     751   112240889 :         xfs_idata_realloc(dp, sizeof(*hdr), XFS_ATTR_FORK);
     752   112258880 :         hdr = (struct xfs_attr_sf_hdr *)ifp->if_u1.if_data;
     753   112258880 :         memset(hdr, 0, sizeof(*hdr));
     754   112258880 :         hdr->totsize = cpu_to_be16(sizeof(*hdr));
     755   112258880 :         xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
     756   112291175 : }
     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   493580284 : xfs_attr_sf_findname(
     769             :         struct xfs_da_args       *args,
     770             :         struct xfs_attr_sf_entry **sfep,
     771             :         unsigned int             *basep)
     772             : {
     773   493580284 :         struct xfs_attr_shortform *sf;
     774   493580284 :         struct xfs_attr_sf_entry *sfe;
     775   493580284 :         unsigned int            base = sizeof(struct xfs_attr_sf_hdr);
     776   493580284 :         int                     size = 0;
     777   493580284 :         int                     end;
     778   493580284 :         int                     i;
     779             : 
     780   493580284 :         sf = (struct xfs_attr_shortform *)args->dp->i_af.if_u1.if_data;
     781   493580284 :         sfe = &sf->list[0];
     782   493580284 :         end = sf->hdr.count;
     783  1050424027 :         for (i = 0; i < end; sfe = xfs_attr_sf_nextentry(sfe),
     784   556843743 :                              base += size, i++) {
     785   729372180 :                 size = xfs_attr_sf_entsize(sfe);
     786   729345900 :                 if (!xfs_attr_match(args, sfe->namelen, sfe->nameval,
     787   729372180 :                                     sfe->valuelen, &sfe->nameval[sfe->namelen],
     788   729372180 :                                     sfe->flags))
     789   556843743 :                         continue;
     790             :                 break;
     791             :         }
     792             : 
     793   493554004 :         if (sfep != NULL)
     794   398259756 :                 *sfep = sfe;
     795             : 
     796   493554004 :         if (basep != NULL)
     797   146675741 :                 *basep = base;
     798             : 
     799   493554004 :         if (i == end)
     800   321019905 :                 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   251640165 : xfs_attr_shortform_add(
     810             :         struct xfs_da_args              *args,
     811             :         int                             forkoff)
     812             : {
     813   251640165 :         struct xfs_attr_shortform       *sf;
     814   251640165 :         struct xfs_attr_sf_entry        *sfe;
     815   251640165 :         int                             offset, size;
     816   251640165 :         struct xfs_mount                *mp;
     817   251640165 :         struct xfs_inode                *dp;
     818   251640165 :         struct xfs_ifork                *ifp;
     819             : 
     820   251640165 :         trace_xfs_attr_sf_add(args);
     821             : 
     822   251606151 :         dp = args->dp;
     823   251606151 :         mp = dp->i_mount;
     824   251606151 :         dp->i_forkoff = forkoff;
     825             : 
     826   251606151 :         ifp = &dp->i_af;
     827   251606151 :         ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
     828   251606151 :         sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
     829   251606151 :         if (xfs_attr_sf_findname(args, &sfe, NULL) == -EEXIST)
     830           0 :                 ASSERT(0);
     831             : 
     832   251637639 :         offset = (char *)sfe - (char *)sf;
     833   251637639 :         size = xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
     834   251637639 :         xfs_idata_realloc(dp, size, XFS_ATTR_FORK);
     835   251665880 :         sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
     836   251665880 :         sfe = (struct xfs_attr_sf_entry *)((char *)sf + offset);
     837             : 
     838   251665880 :         sfe->namelen = args->namelen;
     839   251665880 :         sfe->valuelen = args->valuelen;
     840   251665880 :         sfe->flags = args->attr_filter;
     841   503331760 :         memcpy(sfe->nameval, args->name, args->namelen);
     842   503331760 :         memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
     843   251665880 :         sf->hdr.count++;
     844   251665880 :         be16_add_cpu(&sf->hdr.totsize, size);
     845   251665880 :         xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_ADATA);
     846             : 
     847   251697202 :         xfs_sbversion_add_attr2(mp, args->trans);
     848   251680351 : }
     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    68752405 : xfs_attr_fork_remove(
     856             :         struct xfs_inode        *ip,
     857             :         struct xfs_trans        *tp)
     858             : {
     859    68752405 :         ASSERT(ip->i_af.if_nextents == 0);
     860             : 
     861    68752405 :         xfs_ifork_zap_attr(ip);
     862    68766042 :         ip->i_forkoff = 0;
     863    68766042 :         xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
     864    68871892 : }
     865             : 
     866             : /*
     867             :  * Remove an attribute from the shortform attribute list structure.
     868             :  */
     869             : int
     870   146644909 : xfs_attr_sf_removename(
     871             :         struct xfs_da_args              *args)
     872             : {
     873   146644909 :         struct xfs_attr_shortform       *sf;
     874   146644909 :         struct xfs_attr_sf_entry        *sfe;
     875   146644909 :         int                             size = 0, end, totsize;
     876   146644909 :         unsigned int                    base;
     877   146644909 :         struct xfs_mount                *mp;
     878   146644909 :         struct xfs_inode                *dp;
     879   146644909 :         int                             error;
     880             : 
     881   146644909 :         trace_xfs_attr_sf_remove(args);
     882             : 
     883   146640987 :         dp = args->dp;
     884   146640987 :         mp = dp->i_mount;
     885   146640987 :         sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data;
     886             : 
     887   146640987 :         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   146651220 :         if (error == -ENOATTR && (args->op_flags & XFS_DA_OP_RECOVERY))
     895             :                 return 0;
     896   146651182 :         if (error != -EEXIST)
     897             :                 return error;
     898   146651182 :         size = xfs_attr_sf_entsize(sfe);
     899             : 
     900             :         /*
     901             :          * Fix up the attribute fork data, covering the hole
     902             :          */
     903   146651182 :         end = base + size;
     904   146651182 :         totsize = be16_to_cpu(sf->hdr.totsize);
     905   146651182 :         if (end != totsize)
     906    59265910 :                 memmove(&((char *)sf)[base], &((char *)sf)[end], totsize - end);
     907   146651182 :         sf->hdr.count--;
     908   146651182 :         be16_add_cpu(&sf->hdr.totsize, -size);
     909             : 
     910             :         /*
     911             :          * Fix up the start offset of the attribute fork
     912             :          */
     913   146651182 :         totsize -= size;
     914   146651182 :         if (totsize == sizeof(xfs_attr_sf_hdr_t) && xfs_has_attr2(mp) &&
     915    95897547 :             (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) &&
     916    95277617 :             !(args->op_flags & (XFS_DA_OP_ADDNAME | XFS_DA_OP_REPLACE)) &&
     917             :             !xfs_has_parent(mp)) {
     918       32047 :                 xfs_attr_fork_remove(dp, args->trans);
     919             :         } else {
     920   146619135 :                 xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
     921   146617826 :                 dp->i_forkoff = xfs_attr_shortform_bytesfit(dp, totsize);
     922   146614253 :                 ASSERT(dp->i_forkoff);
     923   146614253 :                 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   146614253 :                 xfs_trans_log_inode(args->trans, dp,
     929             :                                         XFS_ILOG_CORE | XFS_ILOG_ADATA);
     930             :         }
     931             : 
     932   146655677 :         xfs_sbversion_add_attr2(mp, args->trans);
     933             : 
     934   146655677 :         return 0;
     935             : }
     936             : 
     937             : /*
     938             :  * Look up a name in a shortform attribute list structure.
     939             :  */
     940             : /*ARGSUSED*/
     941             : int
     942   236611521 : xfs_attr_shortform_lookup(xfs_da_args_t *args)
     943             : {
     944   236611521 :         struct xfs_attr_shortform *sf;
     945   236611521 :         struct xfs_attr_sf_entry *sfe;
     946   236611521 :         int i;
     947   236611521 :         struct xfs_ifork *ifp;
     948             : 
     949   236611521 :         trace_xfs_attr_sf_lookup(args);
     950             : 
     951   236602069 :         ifp = &args->dp->i_af;
     952   236602069 :         ASSERT(ifp->if_format == XFS_DINODE_FMT_LOCAL);
     953   236602069 :         sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
     954   236602069 :         sfe = &sf->list[0];
     955   455388397 :         for (i = 0; i < sf->hdr.count;
     956   218786328 :                                 sfe = xfs_attr_sf_nextentry(sfe), i++) {
     957   231664587 :                 if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
     958   231592083 :                                 sfe->valuelen, &sfe->nameval[sfe->namelen],
     959   231592083 :                                 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   218676972 : xfs_attr_shortform_getvalue(
     974             :         struct xfs_da_args      *args)
     975             : {
     976   218676972 :         struct xfs_attr_shortform *sf;
     977   218676972 :         struct xfs_attr_sf_entry *sfe;
     978   218676972 :         int                     i;
     979             : 
     980   218676972 :         ASSERT(args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL);
     981   218676972 :         sf = (struct xfs_attr_shortform *)args->dp->i_af.if_u1.if_data;
     982   218676972 :         sfe = &sf->list[0];
     983   317296494 :         for (i = 0; i < sf->hdr.count;
     984    98619522 :                                 sfe = xfs_attr_sf_nextentry(sfe), i++) {
     985   262433646 :                 if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
     986   262657473 :                                 sfe->valuelen, &sfe->nameval[sfe->namelen],
     987   262657473 :                                 sfe->flags))
     988   163814124 :                         return xfs_attr_copy_value(args,
     989   163814124 :                                 &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     8236798 : xfs_attr_shortform_to_leaf(
     997             :         struct xfs_da_args              *args)
     998             : {
     999     8236798 :         struct xfs_inode                *dp;
    1000     8236798 :         struct xfs_attr_shortform       *sf;
    1001     8236798 :         struct xfs_attr_sf_entry        *sfe;
    1002     8236798 :         struct xfs_da_args              nargs;
    1003     8236798 :         char                            *tmpbuffer;
    1004     8236798 :         int                             error, i, size;
    1005     8236798 :         xfs_dablk_t                     blkno;
    1006     8236798 :         struct xfs_buf                  *bp;
    1007     8236798 :         struct xfs_ifork                *ifp;
    1008             : 
    1009     8236798 :         trace_xfs_attr_sf_to_leaf(args);
    1010             : 
    1011     8236363 :         dp = args->dp;
    1012     8236363 :         ifp = &dp->i_af;
    1013     8236363 :         sf = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
    1014     8236363 :         size = be16_to_cpu(sf->hdr.totsize);
    1015     8236363 :         tmpbuffer = kmem_alloc(size, 0);
    1016     8237270 :         ASSERT(tmpbuffer != NULL);
    1017    16474540 :         memcpy(tmpbuffer, ifp->if_u1.if_data, size);
    1018     8237270 :         sf = (struct xfs_attr_shortform *)tmpbuffer;
    1019             : 
    1020     8237270 :         xfs_idata_realloc(dp, -size, XFS_ATTR_FORK);
    1021     8237418 :         xfs_bmap_local_to_extents_empty(args->trans, dp, XFS_ATTR_FORK);
    1022             : 
    1023     8237495 :         bp = NULL;
    1024     8237495 :         error = xfs_da_grow_inode(args, &blkno);
    1025     8232094 :         if (error)
    1026           4 :                 goto out;
    1027             : 
    1028     8232090 :         ASSERT(blkno == 0);
    1029     8232090 :         error = xfs_attr3_leaf_create(args, blkno, &bp);
    1030     8231100 :         if (error)
    1031           0 :                 goto out;
    1032             : 
    1033     8231100 :         memset((char *)&nargs, 0, sizeof(nargs));
    1034     8231100 :         nargs.dp = dp;
    1035     8231100 :         nargs.geo = args->geo;
    1036     8231100 :         nargs.total = args->total;
    1037     8231100 :         nargs.whichfork = XFS_ATTR_FORK;
    1038     8231100 :         nargs.trans = args->trans;
    1039     8231100 :         nargs.op_flags = XFS_DA_OP_OKNOENT | XFS_DA_OP_NVLOOKUP;
    1040     8231100 :         nargs.owner = args->owner;
    1041             : 
    1042     8231100 :         sfe = &sf->list[0];
    1043    50427158 :         for (i = 0; i < sf->hdr.count; i++) {
    1044    42189511 :                 nargs.name = sfe->nameval;
    1045    42189511 :                 nargs.namelen = sfe->namelen;
    1046    42189511 :                 nargs.value = &sfe->nameval[nargs.namelen];
    1047    42189511 :                 nargs.valuelen = sfe->valuelen;
    1048    84373860 :                 nargs.hashval = xfs_da_hashname(sfe->nameval,
    1049    42189511 :                                                 sfe->namelen);
    1050    42184349 :                 nargs.attr_filter = sfe->flags & XFS_ATTR_NSP_ONDISK_MASK;
    1051    42184349 :                 error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */
    1052    42173036 :                 ASSERT(error == -ENOATTR);
    1053    42173036 :                 error = xfs_attr3_leaf_add(bp, &nargs);
    1054    42196058 :                 ASSERT(error != -ENOSPC);
    1055    42196058 :                 if (error)
    1056           0 :                         goto out;
    1057    42196058 :                 sfe = xfs_attr_sf_nextentry(sfe);
    1058             :         }
    1059             :         error = 0;
    1060     8237651 : out:
    1061     8237651 :         kmem_free(tmpbuffer);
    1062     8236740 :         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    87287650 : xfs_attr_shortform_allfit(
    1071             :         struct xfs_buf          *bp,
    1072             :         struct xfs_inode        *dp)
    1073             : {
    1074    87287650 :         struct xfs_attr_leafblock *leaf;
    1075    87287650 :         struct xfs_attr_leaf_entry *entry;
    1076    87287650 :         xfs_attr_leaf_name_local_t *name_loc;
    1077    87287650 :         struct xfs_attr3_icleaf_hdr leafhdr;
    1078    87287650 :         int                     bytes;
    1079    87287650 :         int                     i;
    1080    87287650 :         struct xfs_mount        *mp = bp->b_mount;
    1081             : 
    1082    87287650 :         leaf = bp->b_addr;
    1083    87287650 :         xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
    1084    87332121 :         entry = xfs_attr3_leaf_entryp(leaf);
    1085             : 
    1086    87332121 :         bytes = sizeof(struct xfs_attr_sf_hdr);
    1087  1656423843 :         for (i = 0; i < leafhdr.count; entry++, i++) {
    1088  1569097805 :                 if (entry->flags & XFS_ATTR_INCOMPLETE)
    1089           0 :                         continue;               /* don't copy partial entries */
    1090  1569097805 :                 if (!(entry->flags & XFS_ATTR_LOCAL))
    1091             :                         return 0;
    1092  1569097805 :                 name_loc = xfs_attr3_leaf_name_local(leaf, i);
    1093  1569097805 :                 if (name_loc->namelen >= XFS_ATTR_SF_ENTSIZE_MAX)
    1094             :                         return 0;
    1095  1569097805 :                 if (be16_to_cpu(name_loc->valuelen) >= XFS_ATTR_SF_ENTSIZE_MAX)
    1096             :                         return 0;
    1097  1569091722 :                 bytes += xfs_attr_sf_entsize_byname(name_loc->namelen,
    1098             :                                         be16_to_cpu(name_loc->valuelen));
    1099             :         }
    1100    87326038 :         if (xfs_has_attr2(dp->i_mount) &&
    1101    87326038 :             (dp->i_df.if_format != XFS_DINODE_FMT_BTREE) &&
    1102             :             (bytes == sizeof(struct xfs_attr_sf_hdr)))
    1103             :                 return -1;
    1104    87325927 :         return xfs_attr_shortform_bytesfit(dp, bytes);
    1105             : }
    1106             : 
    1107             : /* Verify the consistency of a raw inline attribute fork. */
    1108             : xfs_failaddr_t
    1109   633210903 : xfs_attr_shortform_verify_struct(
    1110             :         struct xfs_attr_shortform       *sfp,
    1111             :         size_t                          size)
    1112             : {
    1113   633210903 :         struct xfs_attr_sf_entry        *sfep;
    1114   633210903 :         struct xfs_attr_sf_entry        *next_sfep;
    1115   633210903 :         char                            *endp;
    1116   633210903 :         int                             i;
    1117             : 
    1118             :         /*
    1119             :          * Give up if the attribute is way too short.
    1120             :          */
    1121   633210903 :         if (size < sizeof(struct xfs_attr_sf_hdr))
    1122           0 :                 return __this_address;
    1123             : 
    1124   633210903 :         endp = (char *)sfp + size;
    1125             : 
    1126             :         /* Check all reported entries */
    1127   633210903 :         sfep = &sfp->list[0];
    1128  1469116996 :         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   835906093 :                 if (((char *)sfep + sizeof(*sfep)) >= endp)
    1137           0 :                         return __this_address;
    1138             : 
    1139             :                 /* Don't allow names with known bad length. */
    1140   835906093 :                 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   835906093 :                 next_sfep = xfs_attr_sf_nextentry(sfep);
    1149   835906093 :                 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   835906093 :                 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   835906093 :                 if (hweight8(sfep->flags & XFS_ATTR_NSP_ONDISK_MASK) > 1)
    1166           0 :                         return __this_address;
    1167             : 
    1168   835906093 :                 sfep = next_sfep;
    1169             :         }
    1170   633210903 :         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   633215973 : xfs_attr_shortform_verify(
    1179             :         struct xfs_inode                *ip)
    1180             : {
    1181   633215973 :         struct xfs_attr_shortform       *sfp;
    1182   633215973 :         struct xfs_ifork                *ifp;
    1183   633215973 :         int64_t                         size;
    1184             : 
    1185   633215973 :         ASSERT(ip->i_af.if_format == XFS_DINODE_FMT_LOCAL);
    1186   633215973 :         ifp = xfs_ifork_ptr(ip, XFS_ATTR_FORK);
    1187   633215973 :         sfp = (struct xfs_attr_shortform *)ifp->if_u1.if_data;
    1188   633215973 :         size = ifp->if_bytes;
    1189             : 
    1190   633215973 :         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     4307966 : xfs_attr3_leaf_to_shortform(
    1198             :         struct xfs_buf          *bp,
    1199             :         struct xfs_da_args      *args,
    1200             :         int                     forkoff)
    1201             : {
    1202     4307966 :         struct xfs_attr_leafblock *leaf;
    1203     4307966 :         struct xfs_attr3_icleaf_hdr ichdr;
    1204     4307966 :         struct xfs_attr_leaf_entry *entry;
    1205     4307966 :         struct xfs_attr_leaf_name_local *name_loc;
    1206     4307966 :         struct xfs_da_args      nargs;
    1207     4307966 :         struct xfs_inode        *dp = args->dp;
    1208     4307966 :         char                    *tmpbuffer;
    1209     4307966 :         int                     error;
    1210     4307966 :         int                     i;
    1211             : 
    1212     4307966 :         trace_xfs_attr_leaf_to_sf(args);
    1213             : 
    1214     4307693 :         tmpbuffer = kmem_alloc(args->geo->blksize, 0);
    1215     4308179 :         if (!tmpbuffer)
    1216             :                 return -ENOMEM;
    1217             : 
    1218     8616358 :         memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
    1219             : 
    1220     4308179 :         leaf = (xfs_attr_leafblock_t *)tmpbuffer;
    1221     4308179 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    1222     4308173 :         entry = xfs_attr3_leaf_entryp(leaf);
    1223             : 
    1224             :         /* XXX (dgc): buffer is about to be marked stale - why zero it? */
    1225     4308173 :         memset(bp->b_addr, 0, args->geo->blksize);
    1226             : 
    1227             :         /*
    1228             :          * Clean out the prior contents of the attribute list.
    1229             :          */
    1230     4308173 :         error = xfs_da_shrink_inode(args, 0, bp);
    1231     4308115 :         if (error)
    1232           0 :                 goto out;
    1233             : 
    1234     4308115 :         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         111 :                 if (!(args->op_flags & XFS_DA_OP_REPLACE)) {
    1242          79 :                         ASSERT(xfs_has_attr2(dp->i_mount));
    1243          79 :                         ASSERT(dp->i_df.if_format != XFS_DINODE_FMT_BTREE);
    1244          79 :                         xfs_attr_fork_remove(dp, args->trans);
    1245             :                 }
    1246         111 :                 goto out;
    1247             :         }
    1248             : 
    1249     4308004 :         xfs_attr_shortform_create(args);
    1250             : 
    1251             :         /*
    1252             :          * Copy the attributes
    1253             :          */
    1254     4307919 :         memset((char *)&nargs, 0, sizeof(nargs));
    1255     4307919 :         nargs.geo = args->geo;
    1256     4307919 :         nargs.dp = dp;
    1257     4307919 :         nargs.total = args->total;
    1258     4307919 :         nargs.whichfork = XFS_ATTR_FORK;
    1259     4307919 :         nargs.trans = args->trans;
    1260     4307919 :         nargs.op_flags = XFS_DA_OP_OKNOENT | XFS_DA_OP_NVLOOKUP;
    1261     4307919 :         nargs.owner = args->owner;
    1262             : 
    1263    27532258 :         for (i = 0; i < ichdr.count; entry++, i++) {
    1264    23224017 :                 if (entry->flags & XFS_ATTR_INCOMPLETE)
    1265           0 :                         continue;       /* don't copy partial entries */
    1266    23224017 :                 if (!entry->nameidx)
    1267           0 :                         continue;
    1268    23224017 :                 ASSERT(entry->flags & XFS_ATTR_LOCAL);
    1269    23224017 :                 name_loc = xfs_attr3_leaf_name_local(leaf, i);
    1270    23224017 :                 nargs.name = name_loc->nameval;
    1271    23224017 :                 nargs.namelen = name_loc->namelen;
    1272    23224017 :                 nargs.value = &name_loc->nameval[nargs.namelen];
    1273    23224017 :                 nargs.valuelen = be16_to_cpu(name_loc->valuelen);
    1274    23224017 :                 nargs.hashval = be32_to_cpu(entry->hashval);
    1275    23224017 :                 nargs.attr_filter = entry->flags & XFS_ATTR_NSP_ONDISK_MASK;
    1276    23224017 :                 xfs_attr_shortform_add(&nargs, forkoff);
    1277             :         }
    1278             :         error = 0;
    1279             : 
    1280     4308352 : out:
    1281     4308352 :         kmem_free(tmpbuffer);
    1282     4308352 :         return error;
    1283             : }
    1284             : 
    1285             : /*
    1286             :  * Convert from using a single leaf to a root node and a leaf.
    1287             :  */
    1288             : int
    1289       75031 : xfs_attr3_leaf_to_node(
    1290             :         struct xfs_da_args      *args)
    1291             : {
    1292       75031 :         struct xfs_attr_leafblock *leaf;
    1293       75031 :         struct xfs_attr3_icleaf_hdr icleafhdr;
    1294       75031 :         struct xfs_attr_leaf_entry *entries;
    1295       75031 :         struct xfs_da3_icnode_hdr icnodehdr;
    1296       75031 :         struct xfs_da_intnode   *node;
    1297       75031 :         struct xfs_inode        *dp = args->dp;
    1298       75031 :         struct xfs_mount        *mp = dp->i_mount;
    1299       75031 :         struct xfs_buf          *bp1 = NULL;
    1300       75031 :         struct xfs_buf          *bp2 = NULL;
    1301       75031 :         xfs_dablk_t             blkno;
    1302       75031 :         int                     error;
    1303             : 
    1304       75031 :         trace_xfs_attr_leaf_to_node(args);
    1305             : 
    1306       75030 :         if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_ATTR_LEAF_TO_NODE)) {
    1307          11 :                 error = -EIO;
    1308          11 :                 goto out;
    1309             :         }
    1310             : 
    1311       75019 :         error = xfs_da_grow_inode(args, &blkno);
    1312       75020 :         if (error)
    1313           0 :                 goto out;
    1314       75020 :         error = xfs_attr3_leaf_read(args->trans, dp, args->owner, 0, &bp1);
    1315       75020 :         if (error)
    1316           0 :                 goto out;
    1317             : 
    1318       75020 :         error = xfs_da_get_buf(args->trans, dp, blkno, &bp2, XFS_ATTR_FORK);
    1319       75020 :         if (error)
    1320           0 :                 goto out;
    1321             : 
    1322             :         /* copy leaf to new buffer, update identifiers */
    1323       75020 :         xfs_trans_buf_set_type(args->trans, bp2, XFS_BLFT_ATTR_LEAF_BUF);
    1324       75020 :         bp2->b_ops = bp1->b_ops;
    1325      150040 :         memcpy(bp2->b_addr, bp1->b_addr, args->geo->blksize);
    1326       75020 :         if (xfs_has_crc(mp)) {
    1327       75020 :                 struct xfs_da3_blkinfo *hdr3 = bp2->b_addr;
    1328       75020 :                 hdr3->blkno = cpu_to_be64(xfs_buf_daddr(bp2));
    1329             :         }
    1330       75020 :         xfs_trans_log_buf(args->trans, bp2, 0, args->geo->blksize - 1);
    1331             : 
    1332             :         /*
    1333             :          * Set up the new root node.
    1334             :          */
    1335       75020 :         error = xfs_da3_node_create(args, 0, 1, &bp1, XFS_ATTR_FORK);
    1336       75020 :         if (error)
    1337           0 :                 goto out;
    1338       75020 :         node = bp1->b_addr;
    1339       75020 :         xfs_da3_node_hdr_from_disk(mp, &icnodehdr, node);
    1340             : 
    1341       75019 :         leaf = bp2->b_addr;
    1342       75019 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &icleafhdr, leaf);
    1343       75020 :         entries = xfs_attr3_leaf_entryp(leaf);
    1344             : 
    1345             :         /* both on-disk, don't endian-flip twice */
    1346       75020 :         icnodehdr.btree[0].hashval = entries[icleafhdr.count - 1].hashval;
    1347       75020 :         icnodehdr.btree[0].before = cpu_to_be32(blkno);
    1348       75020 :         icnodehdr.count = 1;
    1349       75020 :         xfs_da3_node_hdr_to_disk(dp->i_mount, node, &icnodehdr);
    1350       75019 :         xfs_trans_log_buf(args->trans, bp1, 0, args->geo->blksize - 1);
    1351       75019 :         error = 0;
    1352       75031 : out:
    1353       75031 :         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     8426317 : xfs_attr3_leaf_create(
    1366             :         struct xfs_da_args      *args,
    1367             :         xfs_dablk_t             blkno,
    1368             :         struct xfs_buf          **bpp)
    1369             : {
    1370     8426317 :         struct xfs_attr_leafblock *leaf;
    1371     8426317 :         struct xfs_attr3_icleaf_hdr ichdr;
    1372     8426317 :         struct xfs_inode        *dp = args->dp;
    1373     8426317 :         struct xfs_mount        *mp = dp->i_mount;
    1374     8426317 :         struct xfs_buf          *bp;
    1375     8426317 :         int                     error;
    1376             : 
    1377     8426317 :         trace_xfs_attr_leaf_create(args);
    1378             : 
    1379     8420573 :         error = xfs_da_get_buf(args->trans, args->dp, blkno, &bp,
    1380             :                                             XFS_ATTR_FORK);
    1381     8426185 :         if (error)
    1382             :                 return error;
    1383     8423713 :         bp->b_ops = &xfs_attr3_leaf_buf_ops;
    1384     8423713 :         xfs_trans_buf_set_type(args->trans, bp, XFS_BLFT_ATTR_LEAF_BUF);
    1385     8428008 :         leaf = bp->b_addr;
    1386     8428008 :         memset(leaf, 0, args->geo->blksize);
    1387             : 
    1388     8428008 :         memset(&ichdr, 0, sizeof(ichdr));
    1389     8428008 :         ichdr.firstused = args->geo->blksize;
    1390             : 
    1391     8428008 :         if (xfs_has_crc(mp)) {
    1392     8428008 :                 struct xfs_da3_blkinfo *hdr3 = bp->b_addr;
    1393             : 
    1394     8428008 :                 ichdr.magic = XFS_ATTR3_LEAF_MAGIC;
    1395             : 
    1396     8428008 :                 hdr3->blkno = cpu_to_be64(xfs_buf_daddr(bp));
    1397     8428008 :                 hdr3->owner = cpu_to_be64(args->owner);
    1398     8428008 :                 uuid_copy(&hdr3->uuid, &mp->m_sb.sb_meta_uuid);
    1399             : 
    1400     8420633 :                 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     8420633 :         ichdr.freemap[0].size = ichdr.firstused - ichdr.freemap[0].base;
    1406             : 
    1407     8420633 :         xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr);
    1408     8417581 :         xfs_trans_log_buf(args->trans, bp, 0, args->geo->blksize - 1);
    1409             : 
    1410     8421903 :         *bpp = bp;
    1411     8421903 :         return 0;
    1412             : }
    1413             : 
    1414             : /*
    1415             :  * Split the leaf node, rebalance, then add the new entry.
    1416             :  */
    1417             : int
    1418      195153 : 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      195153 :         xfs_dablk_t blkno;
    1424      195153 :         int error;
    1425             : 
    1426      195153 :         trace_xfs_attr_leaf_split(state->args);
    1427             : 
    1428             :         /*
    1429             :          * Allocate space for a new leaf node.
    1430             :          */
    1431      195153 :         ASSERT(oldblk->magic == XFS_ATTR_LEAF_MAGIC);
    1432      195153 :         error = xfs_da_grow_inode(state->args, &blkno);
    1433      195153 :         if (error)
    1434             :                 return error;
    1435      195153 :         error = xfs_attr3_leaf_create(state->args, blkno, &newblk->bp);
    1436      195153 :         if (error)
    1437             :                 return error;
    1438      195153 :         newblk->blkno = blkno;
    1439      195153 :         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      195153 :         xfs_attr3_leaf_rebalance(state, oldblk, newblk);
    1446      195152 :         error = xfs_da3_blk_link(state, oldblk, newblk);
    1447      195153 :         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      195153 :         if (state->inleaf) {
    1458       33422 :                 trace_xfs_attr_leaf_add_old(state->args);
    1459       33422 :                 error = xfs_attr3_leaf_add(oldblk->bp, state->args);
    1460             :         } else {
    1461      161731 :                 trace_xfs_attr_leaf_add_new(state->args);
    1462      161730 :                 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      195153 :         oldblk->hashval = xfs_attr_leaf_lasthash(oldblk->bp, NULL);
    1469      195153 :         newblk->hashval = xfs_attr_leaf_lasthash(newblk->bp, NULL);
    1470      195153 :         return error;
    1471             : }
    1472             : 
    1473             : /*
    1474             :  * Add a name to the leaf attribute list structure.
    1475             :  */
    1476             : int
    1477   186160104 : xfs_attr3_leaf_add(
    1478             :         struct xfs_buf          *bp,
    1479             :         struct xfs_da_args      *args)
    1480             : {
    1481   186160104 :         struct xfs_attr_leafblock *leaf;
    1482   186160104 :         struct xfs_attr3_icleaf_hdr ichdr;
    1483   186160104 :         int                     tablesize;
    1484   186160104 :         int                     entsize;
    1485   186160104 :         int                     sum;
    1486   186160104 :         int                     tmp;
    1487   186160104 :         int                     i;
    1488             : 
    1489   186160104 :         trace_xfs_attr_leaf_add(args);
    1490             : 
    1491   186025881 :         leaf = bp->b_addr;
    1492   186025881 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    1493   186044119 :         ASSERT(args->index >= 0 && args->index <= ichdr.count);
    1494   186044119 :         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   186003695 :         tablesize = (ichdr.count + 1) * sizeof(xfs_attr_leaf_entry_t)
    1501   186003695 :                                         + xfs_attr3_leaf_hdr_size(leaf);
    1502   454578641 :         for (sum = 0, i = XFS_ATTR_LEAF_MAPSIZE - 1; i >= 0; i--) {
    1503   453769965 :                 if (tablesize > ichdr.firstused) {
    1504      169827 :                         sum += ichdr.freemap[i].size;
    1505      169827 :                         continue;
    1506             :                 }
    1507   453600138 :                 if (!ichdr.freemap[i].size)
    1508   152325636 :                         continue;       /* no space in this map */
    1509   301186744 :                 tmp = entsize;
    1510   301186744 :                 if (ichdr.freemap[i].base < ichdr.firstused)
    1511   121044035 :                         tmp += sizeof(xfs_attr_leaf_entry_t);
    1512   301183992 :                 if (ichdr.freemap[i].size >= tmp) {
    1513   185279722 :                         tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, i);
    1514   185271909 :                         goto out_log_hdr;
    1515             :                 }
    1516   116076967 :                 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      808676 :         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      592053 :         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      592054 :         if (ichdr.freemap[0].size < (entsize + sizeof(xfs_attr_leaf_entry_t))) {
    1538       53571 :                 tmp = -ENOSPC;
    1539       53571 :                 goto out_log_hdr;
    1540             :         }
    1541             : 
    1542      538483 :         tmp = xfs_attr3_leaf_add_work(bp, &ichdr, args, 0);
    1543             : 
    1544   185863965 : out_log_hdr:
    1545   185863965 :         xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr);
    1546   185519185 :         xfs_trans_log_buf(args->trans, bp,
    1547   185519185 :                 XFS_DA_LOGRANGE(leaf, &leaf->hdr,
    1548             :                                 xfs_attr3_leaf_hdr_size(leaf)));
    1549   185519185 :         return tmp;
    1550             : }
    1551             : 
    1552             : /*
    1553             :  * Add a name to a leaf attribute list structure.
    1554             :  */
    1555             : STATIC int
    1556   185822843 : 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   185822843 :         struct xfs_attr_leafblock *leaf;
    1563   185822843 :         struct xfs_attr_leaf_entry *entry;
    1564   185822843 :         struct xfs_attr_leaf_name_local *name_loc;
    1565   185822843 :         struct xfs_attr_leaf_name_remote *name_rmt;
    1566   185822843 :         struct xfs_mount        *mp;
    1567   185822843 :         int                     tmp;
    1568   185822843 :         int                     i;
    1569             : 
    1570   185822843 :         trace_xfs_attr_leaf_add_work(args);
    1571             : 
    1572   185741615 :         leaf = bp->b_addr;
    1573   185741615 :         ASSERT(mapindex >= 0 && mapindex < XFS_ATTR_LEAF_MAPSIZE);
    1574   185741615 :         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   185741615 :         entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
    1580   185741615 :         if (args->index < ichdr->count) {
    1581   160419028 :                 tmp  = ichdr->count - args->index;
    1582   160419028 :                 tmp *= sizeof(xfs_attr_leaf_entry_t);
    1583   320838056 :                 memmove(entry + 1, entry, tmp);
    1584   160419028 :                 xfs_trans_log_buf(args->trans, bp,
    1585   160419028 :                     XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(*entry)));
    1586             :         }
    1587   185835621 :         ichdr->count++;
    1588             : 
    1589             :         /*
    1590             :          * Allocate space for the new string (at the end of the run).
    1591             :          */
    1592   185835621 :         mp = args->trans->t_mountp;
    1593   185835621 :         ASSERT(ichdr->freemap[mapindex].base < args->geo->blksize);
    1594   185858673 :         ASSERT((ichdr->freemap[mapindex].base & 0x3) == 0);
    1595   185857639 :         ASSERT(ichdr->freemap[mapindex].size >=
    1596             :                 xfs_attr_leaf_newentsize(args, NULL));
    1597   185818191 :         ASSERT(ichdr->freemap[mapindex].size < args->geo->blksize);
    1598   185815884 :         ASSERT((ichdr->freemap[mapindex].size & 0x3) == 0);
    1599             : 
    1600   185818877 :         ichdr->freemap[mapindex].size -= xfs_attr_leaf_newentsize(args, &tmp);
    1601             : 
    1602   185846980 :         entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base +
    1603             :                                      ichdr->freemap[mapindex].size);
    1604   185838658 :         entry->hashval = cpu_to_be32(args->hashval);
    1605   185838658 :         entry->flags = args->attr_filter;
    1606   185838658 :         if (tmp)
    1607   185822219 :                 entry->flags |= XFS_ATTR_LOCAL;
    1608   185838658 :         if (args->op_flags & XFS_DA_OP_REPLACE) {
    1609    33328809 :                 if (!(args->op_flags & XFS_DA_OP_LOGGED))
    1610    33328554 :                         entry->flags |= XFS_ATTR_INCOMPLETE;
    1611    33328809 :                 if ((args->blkno2 == args->blkno) &&
    1612    33327027 :                     (args->index2 <= args->index)) {
    1613    33327914 :                         args->index2++;
    1614             :                 }
    1615             :         }
    1616   185838658 :         xfs_trans_log_buf(args->trans, bp,
    1617   185838658 :                           XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
    1618   185737923 :         ASSERT((args->index == 0) ||
    1619             :                (be32_to_cpu(entry->hashval) >= be32_to_cpu((entry-1)->hashval)));
    1620   185737923 :         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   185737923 :         if (entry->flags & XFS_ATTR_LOCAL) {
    1631   185734761 :                 name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
    1632   185734761 :                 name_loc->namelen = args->namelen;
    1633   185734761 :                 name_loc->valuelen = cpu_to_be16(args->valuelen);
    1634   371469522 :                 memcpy((char *)name_loc->nameval, args->name, args->namelen);
    1635   371469522 :                 memcpy((char *)&name_loc->nameval[args->namelen], args->value,
    1636             :                                    be16_to_cpu(name_loc->valuelen));
    1637             :         } else {
    1638        3162 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
    1639        3162 :                 name_rmt->namelen = args->namelen;
    1640        6324 :                 memcpy((char *)name_rmt->name, args->name, args->namelen);
    1641        3162 :                 entry->flags |= XFS_ATTR_INCOMPLETE;
    1642             :                 /* just in case */
    1643        3162 :                 name_rmt->valuelen = 0;
    1644        3162 :                 name_rmt->valueblk = 0;
    1645        3162 :                 args->rmtblkno = 1;
    1646        3162 :                 args->rmtblkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen);
    1647        3162 :                 args->rmtvaluelen = args->valuelen;
    1648             :         }
    1649   371475846 :         xfs_trans_log_buf(args->trans, bp,
    1650   371475846 :              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   185972496 :         if (be16_to_cpu(entry->nameidx) < ichdr->firstused)
    1657   120872101 :                 ichdr->firstused = be16_to_cpu(entry->nameidx);
    1658             : 
    1659   371954926 :         ASSERT(ichdr->firstused >= ichdr->count * sizeof(xfs_attr_leaf_entry_t)
    1660             :                                         + xfs_attr3_leaf_hdr_size(leaf));
    1661   371944992 :         tmp = (ichdr->count - 1) * sizeof(xfs_attr_leaf_entry_t)
    1662   185972496 :                                         + xfs_attr3_leaf_hdr_size(leaf);
    1663             : 
    1664   742868868 :         for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
    1665   557123482 :                 if (ichdr->freemap[i].base == tmp) {
    1666   185848112 :                         ichdr->freemap[i].base += sizeof(xfs_attr_leaf_entry_t);
    1667   185752134 :                         ichdr->freemap[i].size -=
    1668   185788347 :                                 min_t(uint16_t, ichdr->freemap[i].size,
    1669             :                                                 sizeof(xfs_attr_leaf_entry_t));
    1670             :                 }
    1671             :         }
    1672   185745386 :         ichdr->usedbytes += xfs_attr_leaf_entsize(leaf, args->index);
    1673   185745386 :         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      592054 : 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      592054 :         struct xfs_attr_leafblock *leaf_src;
    1686      592054 :         struct xfs_attr_leafblock *leaf_dst;
    1687      592054 :         struct xfs_attr3_icleaf_hdr ichdr_src;
    1688      592054 :         struct xfs_trans        *trans = args->trans;
    1689      592054 :         char                    *tmpbuffer;
    1690             : 
    1691      592054 :         trace_xfs_attr_leaf_compact(args);
    1692             : 
    1693      592040 :         tmpbuffer = kmem_alloc(args->geo->blksize, 0);
    1694     1184102 :         memcpy(tmpbuffer, bp->b_addr, args->geo->blksize);
    1695      592051 :         memset(bp->b_addr, 0, args->geo->blksize);
    1696      592051 :         leaf_src = (xfs_attr_leafblock_t *)tmpbuffer;
    1697      592051 :         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     1776152 :         memcpy(bp->b_addr, tmpbuffer, xfs_attr3_leaf_hdr_size(leaf_src));
    1705             : 
    1706             :         /* Initialise the incore headers */
    1707      592051 :         ichdr_src = *ichdr_dst; /* struct copy */
    1708      592051 :         ichdr_dst->firstused = args->geo->blksize;
    1709      592051 :         ichdr_dst->usedbytes = 0;
    1710      592051 :         ichdr_dst->count = 0;
    1711      592051 :         ichdr_dst->holes = 0;
    1712      592051 :         ichdr_dst->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_src);
    1713      592051 :         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      592051 :         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      592042 :         xfs_attr3_leaf_moveents(args, leaf_src, &ichdr_src, 0,
    1724      592042 :                                 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      592053 :         xfs_trans_log_buf(trans, bp, 0, args->geo->blksize - 1);
    1730             : 
    1731      592055 :         kmem_free(tmpbuffer);
    1732      592057 : }
    1733             : 
    1734             : /*
    1735             :  * Compare two leaf blocks "order".
    1736             :  * Return 0 unless leaf2 should go before leaf1.
    1737             :  */
    1738             : static int
    1739      392582 : 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      392582 :         struct xfs_attr_leaf_entry *entries1;
    1746      392582 :         struct xfs_attr_leaf_entry *entries2;
    1747             : 
    1748      392582 :         entries1 = xfs_attr3_leaf_entryp(leaf1_bp->b_addr);
    1749      392582 :         entries2 = xfs_attr3_leaf_entryp(leaf2_bp->b_addr);
    1750      392582 :         if (leaf1hdr->count > 0 && leaf2hdr->count > 0 &&
    1751      197430 :             ((be32_to_cpu(entries2[0].hashval) <
    1752      197430 :               be32_to_cpu(entries1[0].hashval)) ||
    1753      196588 :              (be32_to_cpu(entries2[leaf2hdr->count - 1].hashval) <
    1754      196588 :               be32_to_cpu(entries1[leaf1hdr->count - 1].hashval)))) {
    1755         842 :                 return 1;
    1756             :         }
    1757             :         return 0;
    1758             : }
    1759             : 
    1760             : int
    1761      195152 : xfs_attr_leaf_order(
    1762             :         struct xfs_buf  *leaf1_bp,
    1763             :         struct xfs_buf  *leaf2_bp)
    1764             : {
    1765      195152 :         struct xfs_attr3_icleaf_hdr ichdr1;
    1766      195152 :         struct xfs_attr3_icleaf_hdr ichdr2;
    1767      195152 :         struct xfs_mount *mp = leaf1_bp->b_mount;
    1768             : 
    1769      195152 :         xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr1, leaf1_bp->b_addr);
    1770      195152 :         xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr2, leaf2_bp->b_addr);
    1771      195152 :         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      195153 : 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      195153 :         struct xfs_da_args      *args;
    1793      195153 :         struct xfs_attr_leafblock *leaf1;
    1794      195153 :         struct xfs_attr_leafblock *leaf2;
    1795      195153 :         struct xfs_attr3_icleaf_hdr ichdr1;
    1796      195153 :         struct xfs_attr3_icleaf_hdr ichdr2;
    1797      195153 :         struct xfs_attr_leaf_entry *entries1;
    1798      195153 :         struct xfs_attr_leaf_entry *entries2;
    1799      195153 :         int                     count;
    1800      195153 :         int                     totallen;
    1801      195153 :         int                     max;
    1802      195153 :         int                     space;
    1803      195153 :         int                     swap;
    1804             : 
    1805             :         /*
    1806             :          * Set up environment.
    1807             :          */
    1808      195153 :         ASSERT(blk1->magic == XFS_ATTR_LEAF_MAGIC);
    1809      195153 :         ASSERT(blk2->magic == XFS_ATTR_LEAF_MAGIC);
    1810      195153 :         leaf1 = blk1->bp->b_addr;
    1811      195153 :         leaf2 = blk2->bp->b_addr;
    1812      195153 :         xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr1, leaf1);
    1813      195152 :         xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr2, leaf2);
    1814      195151 :         ASSERT(ichdr2.count == 0);
    1815      195151 :         args = state->args;
    1816             : 
    1817      195151 :         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      195152 :         swap = 0;
    1826      195152 :         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      195152 :         state->inleaf = xfs_attr3_leaf_figure_balance(state, blk1, &ichdr1,
    1846             :                                                       blk2, &ichdr2,
    1847             :                                                       &count, &totallen);
    1848      195153 :         if (swap)
    1849           0 :                 state->inleaf = !state->inleaf;
    1850             : 
    1851             :         /*
    1852             :          * Move any entries required from leaf to leaf:
    1853             :          */
    1854      195153 :         if (count < ichdr1.count) {
    1855             :                 /*
    1856             :                  * Figure the total bytes to be added to the destination leaf.
    1857             :                  */
    1858             :                 /* number entries being moved */
    1859      195153 :                 count = ichdr1.count - count;
    1860      195153 :                 space  = ichdr1.usedbytes - totallen;
    1861      195153 :                 space += count * sizeof(xfs_attr_leaf_entry_t);
    1862             : 
    1863             :                 /*
    1864             :                  * leaf2 is the destination, compact it if it looks tight.
    1865             :                  */
    1866      195153 :                 max  = ichdr2.firstused - xfs_attr3_leaf_hdr_size(leaf1);
    1867      195153 :                 max -= ichdr2.count * sizeof(xfs_attr_leaf_entry_t);
    1868      195153 :                 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      195153 :                 xfs_attr3_leaf_moveents(args, leaf1, &ichdr1,
    1875      195153 :                                 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      195152 :         xfs_attr3_leaf_hdr_to_disk(state->args->geo, leaf1, &ichdr1);
    1908      195153 :         xfs_attr3_leaf_hdr_to_disk(state->args->geo, leaf2, &ichdr2);
    1909      195152 :         xfs_trans_log_buf(args->trans, blk1->bp, 0, args->geo->blksize - 1);
    1910      195153 :         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      195152 :         entries1 = xfs_attr3_leaf_entryp(leaf1);
    1916      195152 :         entries2 = xfs_attr3_leaf_entryp(leaf2);
    1917      195152 :         blk1->hashval = be32_to_cpu(entries1[ichdr1.count - 1].hashval);
    1918      195152 :         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      195152 :         if (blk1->index > ichdr1.count) {
    1933      149653 :                 ASSERT(state->inleaf == 0);
    1934      149653 :                 blk2->index = blk1->index - ichdr1.count;
    1935      149653 :                 args->index = args->index2 = blk2->index;
    1936      149653 :                 args->blkno = args->blkno2 = blk2->blkno;
    1937       45499 :         } else if (blk1->index == ichdr1.count) {
    1938       17286 :                 if (state->inleaf) {
    1939        5209 :                         args->index = blk1->index;
    1940        5209 :                         args->blkno = blk1->blkno;
    1941        5209 :                         args->index2 = 0;
    1942        5209 :                         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       12077 :                         blk2->index = blk1->index - ichdr1.count;
    1950       12077 :                         args->index = blk2->index;
    1951       12077 :                         args->blkno = blk2->blkno;
    1952       12077 :                         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       12077 :                                 args->index2 = blk2->index;
    1959       12077 :                                 args->blkno2 = blk2->blkno;
    1960             :                         }
    1961             :                 }
    1962             :         } else {
    1963       28213 :                 ASSERT(state->inleaf == 1);
    1964       28213 :                 args->index = args->index2 = blk1->index;
    1965       28213 :                 args->blkno = args->blkno2 = blk1->blkno;
    1966             :         }
    1967      195152 : }
    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      195150 : 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      195150 :         struct xfs_attr_leafblock       *leaf1 = blk1->bp->b_addr;
    1987      195150 :         struct xfs_attr_leafblock       *leaf2 = blk2->bp->b_addr;
    1988      195150 :         struct xfs_attr_leaf_entry      *entry;
    1989      195150 :         int                             count;
    1990      195150 :         int                             max;
    1991      195150 :         int                             index;
    1992      195150 :         int                             totallen = 0;
    1993      195150 :         int                             half;
    1994      195150 :         int                             lastdelta;
    1995      195150 :         int                             foundit = 0;
    1996      195150 :         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      195150 :         max = ichdr1->count + ichdr2->count;
    2003      195150 :         half = (max + 1) * sizeof(*entry);
    2004      390300 :         half += ichdr1->usedbytes + ichdr2->usedbytes +
    2005      195150 :                         xfs_attr_leaf_newentsize(state->args, NULL);
    2006      195150 :         half /= 2;
    2007      195150 :         lastdelta = state->args->geo->blksize;
    2008      195150 :         entry = xfs_attr3_leaf_entryp(leaf1);
    2009     3591621 :         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     3591621 :                 if (count == blk1->index) {
    2016       91001 :                         tmp = totallen + sizeof(*entry) +
    2017       45499 :                                 xfs_attr_leaf_newentsize(state->args, NULL);
    2018       45502 :                         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     3579547 :                 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     3579547 :                 tmp = totallen + sizeof(*entry) + xfs_attr_leaf_entsize(leaf1,
    2038             :                                                                         index);
    2039     3579547 :                 if (XFS_ATTR_ABS(half - tmp) > lastdelta)
    2040             :                         break;
    2041     3396471 :                 lastdelta = XFS_ATTR_ABS(half - tmp);
    2042     3396471 :                 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      195153 :         totallen -= count * sizeof(*entry);
    2051      195153 :         if (foundit) {
    2052       66844 :                 totallen -= sizeof(*entry) +
    2053       33422 :                                 xfs_attr_leaf_newentsize(state->args, NULL);
    2054             :         }
    2055             : 
    2056      195153 :         *countarg = count;
    2057      195153 :         *usedbytesarg = totallen;
    2058      195153 :         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     1904038 : xfs_attr3_leaf_toosmall(
    2078             :         struct xfs_da_state     *state,
    2079             :         int                     *action)
    2080             : {
    2081     1904038 :         struct xfs_attr_leafblock *leaf;
    2082     1904038 :         struct xfs_da_state_blk *blk;
    2083     1904038 :         struct xfs_attr3_icleaf_hdr ichdr;
    2084     1904038 :         struct xfs_buf          *bp;
    2085     1904038 :         xfs_dablk_t             blkno;
    2086     1904038 :         int                     bytes;
    2087     1904038 :         int                     forward;
    2088     1904038 :         int                     error;
    2089     1904038 :         int                     retval;
    2090     1904038 :         int                     i;
    2091             : 
    2092     1904038 :         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     1904031 :         blk = &state->path.blk[ state->path.active-1 ];
    2100     1904031 :         leaf = blk->bp->b_addr;
    2101     1904031 :         xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr, leaf);
    2102     1904038 :         bytes = xfs_attr3_leaf_hdr_size(leaf) +
    2103     1904038 :                 ichdr.count * sizeof(xfs_attr_leaf_entry_t) +
    2104     1904038 :                 ichdr.usedbytes;
    2105     1904038 :         if (bytes > (state->args->geo->blksize >> 1)) {
    2106     1276523 :                 *action = 0;    /* blk over 50%, don't try to join */
    2107     1276523 :                 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      627515 :         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      627515 :         forward = ichdr.forw < ichdr.back;
    2144     1879007 :         for (i = 0; i < 2; forward = !forward, i++) {
    2145     1253781 :                 struct xfs_attr3_icleaf_hdr ichdr2;
    2146     1253781 :                 if (forward)
    2147             :                         blkno = ichdr.forw;
    2148             :                 else
    2149      627156 :                         blkno = ichdr.back;
    2150     1253781 :                 if (blkno == 0)
    2151      557439 :                         continue;
    2152      696342 :                 error = xfs_attr3_leaf_read(state->args->trans, state->args->dp,
    2153      696342 :                                         state->args->owner, blkno, &bp);
    2154      696343 :                 if (error)
    2155          10 :                         return error;
    2156             : 
    2157      696333 :                 xfs_attr3_leaf_hdr_from_disk(state->args->geo, &ichdr2, bp->b_addr);
    2158             : 
    2159     1392664 :                 bytes = state->args->geo->blksize -
    2160      696332 :                         (state->args->geo->blksize >> 2) -
    2161      696332 :                         ichdr.usedbytes - ichdr2.usedbytes -
    2162      696332 :                         ((ichdr.count + ichdr2.count) *
    2163      696332 :                                         sizeof(xfs_attr_leaf_entry_t)) -
    2164      696332 :                         xfs_attr3_leaf_hdr_size(leaf);
    2165             : 
    2166      696332 :                 xfs_trans_brelse(state->args->trans, bp);
    2167      696331 :                 if (bytes >= 0)
    2168             :                         break;  /* fits with at least 25% to spare */
    2169             :         }
    2170      627504 :         if (i >= 2) {
    2171      625226 :                 *action = 0;
    2172      625226 :                 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        4556 :         memcpy(&state->altpath, &state->path, sizeof(state->path));
    2180        2278 :         if (blkno < blk->blkno) {
    2181        1043 :                 error = xfs_da3_path_shift(state, &state->altpath, forward,
    2182             :                                                  0, &retval);
    2183             :         } else {
    2184        1235 :                 error = xfs_da3_path_shift(state, &state->path, forward,
    2185             :                                                  0, &retval);
    2186             :         }
    2187        2278 :         if (error)
    2188             :                 return error;
    2189        2278 :         if (retval) {
    2190           0 :                 *action = 0;
    2191             :         } else {
    2192        2278 :                 *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    89139852 : xfs_attr3_leaf_remove(
    2205             :         struct xfs_buf          *bp,
    2206             :         struct xfs_da_args      *args)
    2207             : {
    2208    89139852 :         struct xfs_attr_leafblock *leaf;
    2209    89139852 :         struct xfs_attr3_icleaf_hdr ichdr;
    2210    89139852 :         struct xfs_attr_leaf_entry *entry;
    2211    89139852 :         int                     before;
    2212    89139852 :         int                     after;
    2213    89139852 :         int                     smallest;
    2214    89139852 :         int                     entsize;
    2215    89139852 :         int                     tablesize;
    2216    89139852 :         int                     tmp;
    2217    89139852 :         int                     i;
    2218             : 
    2219    89139852 :         trace_xfs_attr_leaf_remove(args);
    2220             : 
    2221    89106649 :         leaf = bp->b_addr;
    2222    89106649 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    2223             : 
    2224    89117020 :         ASSERT(ichdr.count > 0 && ichdr.count < args->geo->blksize / 8);
    2225    89117020 :         ASSERT(args->index >= 0 && args->index < ichdr.count);
    2226   178234127 :         ASSERT(ichdr.firstused >= ichdr.count * sizeof(*entry) +
    2227             :                                         xfs_attr3_leaf_hdr_size(leaf));
    2228             : 
    2229    89117020 :         entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
    2230             : 
    2231    89117020 :         ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
    2232    89117020 :         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    89117020 :         tablesize = ichdr.count * sizeof(xfs_attr_leaf_entry_t)
    2241    89117020 :                                         + xfs_attr3_leaf_hdr_size(leaf);
    2242    89117020 :         tmp = ichdr.freemap[0].size;
    2243    89117020 :         before = after = -1;
    2244    89117020 :         smallest = XFS_ATTR_LEAF_MAPSIZE - 1;
    2245    89117020 :         entsize = xfs_attr_leaf_entsize(leaf, args->index);
    2246   356408210 :         for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) {
    2247   267264038 :                 ASSERT(ichdr.freemap[i].base < args->geo->blksize);
    2248   267237700 :                 ASSERT(ichdr.freemap[i].size < args->geo->blksize);
    2249   267253351 :                 if (ichdr.freemap[i].base == tablesize) {
    2250    88981601 :                         ichdr.freemap[i].base -= sizeof(xfs_attr_leaf_entry_t);
    2251    88980214 :                         ichdr.freemap[i].size += sizeof(xfs_attr_leaf_entry_t);
    2252             :                 }
    2253             : 
    2254   267243542 :                 if (ichdr.freemap[i].base + ichdr.freemap[i].size ==
    2255   267274584 :                                 be16_to_cpu(entry->nameidx)) {
    2256             :                         before = i;
    2257   253193402 :                 } else if (ichdr.freemap[i].base ==
    2258   253211227 :                                 (be16_to_cpu(entry->nameidx) + entsize)) {
    2259             :                         after = i;
    2260   244556185 :                 } else if (ichdr.freemap[i].size < tmp) {
    2261   126472262 :                         tmp = ichdr.freemap[i].size;
    2262   126472262 :                         smallest = i;
    2263             :                 }
    2264             :         }
    2265             : 
    2266             :         /*
    2267             :          * Coalesce adjacent freemap regions,
    2268             :          * or replace the smallest region.
    2269             :          */
    2270    89144172 :         if ((before >= 0) || (after >= 0)) {
    2271    21600261 :                 if ((before >= 0) && (after >= 0)) {
    2272     1135450 :                         ichdr.freemap[before].size += entsize;
    2273     1135445 :                         ichdr.freemap[before].size += ichdr.freemap[after].size;
    2274     1135446 :                         ichdr.freemap[after].base = 0;
    2275     1135445 :                         ichdr.freemap[after].size = 0;
    2276    20464811 :                 } else if (before >= 0) {
    2277    12945179 :                         ichdr.freemap[before].size += entsize;
    2278             :                 } else {
    2279     7519632 :                         ichdr.freemap[after].base = be16_to_cpu(entry->nameidx);
    2280     7519609 :                         ichdr.freemap[after].size += entsize;
    2281             :                 }
    2282             :         } else {
    2283             :                 /*
    2284             :                  * Replace smallest region (if it is smaller than free'd entry)
    2285             :                  */
    2286    67543911 :                 if (ichdr.freemap[smallest].size < entsize) {
    2287    55605859 :                         ichdr.freemap[smallest].base = be16_to_cpu(entry->nameidx);
    2288    55603353 :                         ichdr.freemap[smallest].size = entsize;
    2289             :                 }
    2290             :         }
    2291             : 
    2292             :         /*
    2293             :          * Did we remove the first entry?
    2294             :          */
    2295    89143157 :         if (be16_to_cpu(entry->nameidx) == ichdr.firstused)
    2296             :                 smallest = 1;
    2297             :         else
    2298    83156175 :                 smallest = 0;
    2299             : 
    2300             :         /*
    2301             :          * Compress the remaining entries and zero out the removed stuff.
    2302             :          */
    2303    89143157 :         memset(xfs_attr3_leaf_name(leaf, args->index), 0, entsize);
    2304    89143157 :         ichdr.usedbytes -= entsize;
    2305   178286314 :         xfs_trans_log_buf(args->trans, bp,
    2306   178286314 :              XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index),
    2307             :                                    entsize));
    2308             : 
    2309    89135105 :         tmp = (ichdr.count - args->index) * sizeof(xfs_attr_leaf_entry_t);
    2310   178270210 :         memmove(entry, entry + 1, tmp);
    2311    89135105 :         ichdr.count--;
    2312    89135105 :         xfs_trans_log_buf(args->trans, bp,
    2313    89135105 :             XFS_DA_LOGRANGE(leaf, entry, tmp + sizeof(xfs_attr_leaf_entry_t)));
    2314             : 
    2315    89163250 :         entry = &xfs_attr3_leaf_entryp(leaf)[ichdr.count];
    2316    89163250 :         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    89163250 :         if (smallest) {
    2325     5967927 :                 tmp = args->geo->blksize;
    2326     5967927 :                 entry = xfs_attr3_leaf_entryp(leaf);
    2327    80376160 :                 for (i = ichdr.count - 1; i >= 0; entry++, i--) {
    2328    74408249 :                         ASSERT(be16_to_cpu(entry->nameidx) >= ichdr.firstused);
    2329    74408249 :                         ASSERT(be16_to_cpu(entry->nameidx) < args->geo->blksize);
    2330             : 
    2331    74408233 :                         if (be16_to_cpu(entry->nameidx) < tmp)
    2332             :                                 tmp = be16_to_cpu(entry->nameidx);
    2333             :                 }
    2334     5967911 :                 ichdr.firstused = tmp;
    2335     5967911 :                 ASSERT(ichdr.firstused != 0);
    2336             :         } else {
    2337    83195323 :                 ichdr.holes = 1;        /* mark as needing compaction */
    2338             :         }
    2339    89163234 :         xfs_attr3_leaf_hdr_to_disk(args->geo, leaf, &ichdr);
    2340    89078186 :         xfs_trans_log_buf(args->trans, bp,
    2341    89078186 :                           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    89150822 :         tmp = ichdr.usedbytes + xfs_attr3_leaf_hdr_size(leaf) +
    2349    89150822 :               ichdr.count * sizeof(xfs_attr_leaf_entry_t);
    2350             : 
    2351    89150822 :         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        2278 : 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        2278 :         struct xfs_attr_leafblock *drop_leaf = drop_blk->bp->b_addr;
    2364        2278 :         struct xfs_attr_leafblock *save_leaf = save_blk->bp->b_addr;
    2365        2278 :         struct xfs_attr3_icleaf_hdr drophdr;
    2366        2278 :         struct xfs_attr3_icleaf_hdr savehdr;
    2367        2278 :         struct xfs_attr_leaf_entry *entry;
    2368             : 
    2369        2278 :         trace_xfs_attr_leaf_unbalance(state->args);
    2370             : 
    2371        2278 :         xfs_attr3_leaf_hdr_from_disk(state->args->geo, &drophdr, drop_leaf);
    2372        2278 :         xfs_attr3_leaf_hdr_from_disk(state->args->geo, &savehdr, save_leaf);
    2373        2278 :         entry = xfs_attr3_leaf_entryp(drop_leaf);
    2374             : 
    2375             :         /*
    2376             :          * Save last hashval from dying block for later Btree fixup.
    2377             :          */
    2378        2278 :         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        2278 :         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           0 :                 if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
    2391             :                                          drop_blk->bp, &drophdr)) {
    2392           0 :                         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        2278 :                 struct xfs_attr_leafblock *tmp_leaf;
    2408        2278 :                 struct xfs_attr3_icleaf_hdr tmphdr;
    2409             : 
    2410        2278 :                 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        6834 :                 memcpy(tmp_leaf, save_leaf, xfs_attr3_leaf_hdr_size(save_leaf));
    2418             : 
    2419        2278 :                 memset(&tmphdr, 0, sizeof(tmphdr));
    2420        2278 :                 tmphdr.magic = savehdr.magic;
    2421        2278 :                 tmphdr.forw = savehdr.forw;
    2422        2278 :                 tmphdr.back = savehdr.back;
    2423        2278 :                 tmphdr.firstused = state->args->geo->blksize;
    2424             : 
    2425             :                 /* write the header to the temp buffer to initialise it */
    2426        2278 :                 xfs_attr3_leaf_hdr_to_disk(state->args->geo, tmp_leaf, &tmphdr);
    2427             : 
    2428        2278 :                 if (xfs_attr3_leaf_order(save_blk->bp, &savehdr,
    2429             :                                          drop_blk->bp, &drophdr)) {
    2430         842 :                         xfs_attr3_leaf_moveents(state->args,
    2431             :                                                 drop_leaf, &drophdr, 0,
    2432             :                                                 tmp_leaf, &tmphdr, 0,
    2433         842 :                                                 drophdr.count);
    2434         842 :                         xfs_attr3_leaf_moveents(state->args,
    2435             :                                                 save_leaf, &savehdr, 0,
    2436         842 :                                                 tmp_leaf, &tmphdr, tmphdr.count,
    2437         842 :                                                 savehdr.count);
    2438             :                 } else {
    2439        1436 :                         xfs_attr3_leaf_moveents(state->args,
    2440             :                                                 save_leaf, &savehdr, 0,
    2441             :                                                 tmp_leaf, &tmphdr, 0,
    2442        1436 :                                                 savehdr.count);
    2443        1436 :                         xfs_attr3_leaf_moveents(state->args,
    2444             :                                                 drop_leaf, &drophdr, 0,
    2445        1436 :                                                 tmp_leaf, &tmphdr, tmphdr.count,
    2446        1436 :                                                 drophdr.count);
    2447             :                 }
    2448        4556 :                 memcpy(save_leaf, tmp_leaf, state->args->geo->blksize);
    2449        2278 :                 savehdr = tmphdr; /* struct copy */
    2450        2278 :                 kmem_free(tmp_leaf);
    2451             :         }
    2452             : 
    2453        2278 :         xfs_attr3_leaf_hdr_to_disk(state->args->geo, save_leaf, &savehdr);
    2454        2278 :         xfs_trans_log_buf(state->args->trans, save_blk->bp, 0,
    2455        2278 :                                            state->args->geo->blksize - 1);
    2456             : 
    2457             :         /*
    2458             :          * Copy out last hashval in each block for B-tree code.
    2459             :          */
    2460        2278 :         entry = xfs_attr3_leaf_entryp(save_leaf);
    2461        2278 :         save_blk->hashval = be32_to_cpu(entry[savehdr.count - 1].hashval);
    2462        2278 : }
    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  1079215946 : xfs_attr3_leaf_lookup_int(
    2483             :         struct xfs_buf          *bp,
    2484             :         struct xfs_da_args      *args)
    2485             : {
    2486  1079215946 :         struct xfs_attr_leafblock *leaf;
    2487  1079215946 :         struct xfs_attr3_icleaf_hdr ichdr;
    2488  1079215946 :         struct xfs_attr_leaf_entry *entry;
    2489  1079215946 :         struct xfs_attr_leaf_entry *entries;
    2490  1079215946 :         struct xfs_attr_leaf_name_local *name_loc;
    2491  1079215946 :         struct xfs_attr_leaf_name_remote *name_rmt;
    2492  1079215946 :         xfs_dahash_t            hashval;
    2493  1079215946 :         int                     probe;
    2494  1079215946 :         int                     span;
    2495             : 
    2496  1079215946 :         trace_xfs_attr_leaf_lookup(args);
    2497             : 
    2498  1078975355 :         leaf = bp->b_addr;
    2499  1078975355 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    2500  1079816435 :         entries = xfs_attr3_leaf_entryp(leaf);
    2501  1079816435 :         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  1079816435 :         hashval = args->hashval;
    2511  1079816435 :         probe = span = ichdr.count / 2;
    2512  1615817315 :         for (entry = &entries[probe]; span > 4; entry = &entries[probe]) {
    2513   552052724 :                 span /= 2;
    2514   552052724 :                 if (be32_to_cpu(entry->hashval) < hashval)
    2515   334085518 :                         probe += span;
    2516   217967206 :                 else if (be32_to_cpu(entry->hashval) > hashval)
    2517   201915362 :                         probe -= span;
    2518             :                 else
    2519             :                         break;
    2520             :         }
    2521  1079816435 :         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  1079816435 :         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  3831640907 :         while (probe > 0 && be32_to_cpu(entry->hashval) >= hashval) {
    2537  2751824472 :                 entry--;
    2538  2751824472 :                 probe--;
    2539             :         }
    2540  2000642687 :         while (probe < ichdr.count &&
    2541  1973418494 :                be32_to_cpu(entry->hashval) < hashval) {
    2542   920826252 :                 entry++;
    2543   920826252 :                 probe++;
    2544             :         }
    2545  1079816435 :         if (probe == ichdr.count || be32_to_cpu(entry->hashval) != hashval) {
    2546   307754050 :                 args->index = probe;
    2547   307754050 :                 return -ENOATTR;
    2548             :         }
    2549             : 
    2550             :         /*
    2551             :          * Duplicate keys may be present, so search all of them for a match.
    2552             :          */
    2553  5373858072 :         for (; probe < ichdr.count && (be32_to_cpu(entry->hashval) == hashval);
    2554  4601795687 :                         entry++, probe++) {
    2555             : /*
    2556             :  * GROT: Add code to remove incomplete entries.
    2557             :  */
    2558  4798688343 :                 if (entry->flags & XFS_ATTR_LOCAL) {
    2559  4798686445 :                         name_loc = xfs_attr3_leaf_name_local(leaf, probe);
    2560  4798545921 :                         if (!xfs_attr_match(args, name_loc->namelen,
    2561  4798686445 :                                         name_loc->nameval,
    2562  4798686445 :                                         be16_to_cpu(name_loc->valuelen),
    2563  4798686445 :                                         &name_loc->nameval[name_loc->namelen],
    2564             :                                         entry->flags))
    2565  4601795677 :                                 continue;
    2566   196750244 :                         args->index = probe;
    2567   196750244 :                         return -EEXIST;
    2568             :                 } else {
    2569        1898 :                         name_rmt = xfs_attr3_leaf_name_remote(leaf, probe);
    2570        1898 :                         if (!xfs_attr_match(args, name_rmt->namelen,
    2571        1898 :                                         name_rmt->name, 0, NULL, entry->flags))
    2572          10 :                                 continue;
    2573        1888 :                         args->index = probe;
    2574        1888 :                         args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
    2575        1888 :                         args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
    2576        3776 :                         args->rmtblkcnt = xfs_attr3_rmt_blocks(
    2577        1888 :                                                         args->dp->i_mount,
    2578             :                                                         args->rmtvaluelen);
    2579        1888 :                         return -EEXIST;
    2580             :                 }
    2581             :         }
    2582   575169729 :         args->index = probe;
    2583   575169729 :         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    19806605 : xfs_attr3_leaf_getvalue(
    2596             :         struct xfs_buf          *bp,
    2597             :         struct xfs_da_args      *args)
    2598             : {
    2599    19806605 :         struct xfs_attr_leafblock *leaf;
    2600    19806605 :         struct xfs_attr3_icleaf_hdr ichdr;
    2601    19806605 :         struct xfs_attr_leaf_entry *entry;
    2602    19806605 :         struct xfs_attr_leaf_name_local *name_loc;
    2603    19806605 :         struct xfs_attr_leaf_name_remote *name_rmt;
    2604             : 
    2605    19806605 :         leaf = bp->b_addr;
    2606    19806605 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    2607    19815109 :         ASSERT(ichdr.count < args->geo->blksize / 8);
    2608    19815109 :         ASSERT(args->index < ichdr.count);
    2609             : 
    2610    19815109 :         entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
    2611    19815109 :         if (entry->flags & XFS_ATTR_LOCAL) {
    2612    19813182 :                 name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
    2613    19813182 :                 ASSERT(name_loc->namelen == args->namelen);
    2614    39626364 :                 ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0);
    2615    19813182 :                 return xfs_attr_copy_value(args,
    2616    19813182 :                                         &name_loc->nameval[args->namelen],
    2617    19813182 :                                         be16_to_cpu(name_loc->valuelen));
    2618             :         }
    2619             : 
    2620        1927 :         name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
    2621        1927 :         ASSERT(name_rmt->namelen == args->namelen);
    2622        3854 :         ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0);
    2623        1927 :         args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
    2624        1927 :         args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
    2625        1927 :         args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount,
    2626             :                                                args->rmtvaluelen);
    2627        1927 :         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      791741 : 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      791741 :         struct xfs_attr_leaf_entry      *entry_s;
    2651      791741 :         struct xfs_attr_leaf_entry      *entry_d;
    2652      791741 :         int                             desti;
    2653      791741 :         int                             tmp;
    2654      791741 :         int                             i;
    2655             : 
    2656             :         /*
    2657             :          * Check for nothing to do.
    2658             :          */
    2659      791741 :         if (count == 0)
    2660             :                 return;
    2661             : 
    2662             :         /*
    2663             :          * Set up environment.
    2664             :          */
    2665      791741 :         ASSERT(ichdr_s->magic == XFS_ATTR_LEAF_MAGIC ||
    2666             :                ichdr_s->magic == XFS_ATTR3_LEAF_MAGIC);
    2667      791741 :         ASSERT(ichdr_s->magic == ichdr_d->magic);
    2668      791741 :         ASSERT(ichdr_s->count > 0 && ichdr_s->count < args->geo->blksize / 8);
    2669     1583483 :         ASSERT(ichdr_s->firstused >= (ichdr_s->count * sizeof(*entry_s))
    2670             :                                         + xfs_attr3_leaf_hdr_size(leaf_s));
    2671      791741 :         ASSERT(ichdr_d->count < args->geo->blksize / 8);
    2672     1583478 :         ASSERT(ichdr_d->firstused >= (ichdr_d->count * sizeof(*entry_d))
    2673             :                                         + xfs_attr3_leaf_hdr_size(leaf_d));
    2674             : 
    2675      791741 :         ASSERT(start_s < ichdr_s->count);
    2676      791741 :         ASSERT(start_d <= ichdr_d->count);
    2677      791741 :         ASSERT(count <= ichdr_s->count);
    2678             : 
    2679             : 
    2680             :         /*
    2681             :          * Move the entries in the destination leaf up to make a hole?
    2682             :          */
    2683      791741 :         if (start_d < ichdr_d->count) {
    2684           0 :                 tmp  = ichdr_d->count - start_d;
    2685           0 :                 tmp *= sizeof(xfs_attr_leaf_entry_t);
    2686           0 :                 entry_s = &xfs_attr3_leaf_entryp(leaf_d)[start_d];
    2687           0 :                 entry_d = &xfs_attr3_leaf_entryp(leaf_d)[start_d + count];
    2688           0 :                 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      791741 :         entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
    2696      791741 :         entry_d = &xfs_attr3_leaf_entryp(leaf_d)[start_d];
    2697      791741 :         desti = start_d;
    2698    32274439 :         for (i = 0; i < count; entry_s++, entry_d++, desti++, i++) {
    2699    31482674 :                 ASSERT(be16_to_cpu(entry_s->nameidx) >= ichdr_s->firstused);
    2700    31482674 :                 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    31482674 :                         ichdr_d->firstused -= tmp;
    2718             :                         /* both on-disk, don't endian flip twice */
    2719    31482674 :                         entry_d->hashval = entry_s->hashval;
    2720    31482674 :                         entry_d->nameidx = cpu_to_be16(ichdr_d->firstused);
    2721    31482674 :                         entry_d->flags = entry_s->flags;
    2722    31482674 :                         ASSERT(be16_to_cpu(entry_d->nameidx) + tmp
    2723             :                                                         <= args->geo->blksize);
    2724    31482674 :                         memmove(xfs_attr3_leaf_name(leaf_d, desti),
    2725             :                                 xfs_attr3_leaf_name(leaf_s, start_s + i), tmp);
    2726    31482674 :                         ASSERT(be16_to_cpu(entry_s->nameidx) + tmp
    2727             :                                                         <= args->geo->blksize);
    2728    31482674 :                         memset(xfs_attr3_leaf_name(leaf_s, start_s + i), 0, tmp);
    2729    31482674 :                         ichdr_s->usedbytes -= tmp;
    2730    31482674 :                         ichdr_d->usedbytes += tmp;
    2731    31482674 :                         ichdr_s->count -= 1;
    2732    31482674 :                         ichdr_d->count += 1;
    2733    31482674 :                         tmp = ichdr_d->count * sizeof(xfs_attr_leaf_entry_t)
    2734    31482674 :                                         + xfs_attr3_leaf_hdr_size(leaf_d);
    2735    31482674 :                         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      791765 :         if (start_s == ichdr_s->count) {
    2745      791765 :                 tmp = count * sizeof(xfs_attr_leaf_entry_t);
    2746      791765 :                 entry_s = &xfs_attr3_leaf_entryp(leaf_s)[start_s];
    2747      791765 :                 ASSERT(((char *)entry_s + tmp) <=
    2748             :                        ((char *)leaf_s + args->geo->blksize));
    2749     1583530 :                 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      791765 :         ichdr_d->freemap[0].base = xfs_attr3_leaf_hdr_size(leaf_d);
    2771      791765 :         ichdr_d->freemap[0].base += ichdr_d->count * sizeof(xfs_attr_leaf_entry_t);
    2772      791765 :         ichdr_d->freemap[0].size = ichdr_d->firstused - ichdr_d->freemap[0].base;
    2773      791765 :         ichdr_d->freemap[1].base = 0;
    2774      791765 :         ichdr_d->freemap[2].base = 0;
    2775      791765 :         ichdr_d->freemap[1].size = 0;
    2776      791765 :         ichdr_d->freemap[2].size = 0;
    2777      791765 :         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   596224805 : xfs_attr_leaf_lasthash(
    2785             :         struct xfs_buf  *bp,
    2786             :         int             *count)
    2787             : {
    2788   596224805 :         struct xfs_attr3_icleaf_hdr ichdr;
    2789   596224805 :         struct xfs_attr_leaf_entry *entries;
    2790   596224805 :         struct xfs_mount *mp = bp->b_mount;
    2791             : 
    2792   596224805 :         xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, bp->b_addr);
    2793   596237031 :         entries = xfs_attr3_leaf_entryp(bp->b_addr);
    2794   596237031 :         if (count)
    2795     7921982 :                 *count = ichdr.count;
    2796   596237031 :         if (!ichdr.count)
    2797             :                 return 0;
    2798   596236998 :         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   495468385 : xfs_attr_leaf_entsize(xfs_attr_leafblock_t *leaf, int index)
    2807             : {
    2808   495468385 :         struct xfs_attr_leaf_entry *entries;
    2809   495468385 :         xfs_attr_leaf_name_local_t *name_loc;
    2810   495468385 :         xfs_attr_leaf_name_remote_t *name_rmt;
    2811   495468385 :         int size;
    2812             : 
    2813   495468385 :         entries = xfs_attr3_leaf_entryp(leaf);
    2814   495468385 :         if (entries[index].flags & XFS_ATTR_LOCAL) {
    2815   495461973 :                 name_loc = xfs_attr3_leaf_name_local(leaf, index);
    2816   495461973 :                 size = xfs_attr_leaf_entsize_local(name_loc->namelen,
    2817   495461973 :                                                    be16_to_cpu(name_loc->valuelen));
    2818             :         } else {
    2819        6412 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf, index);
    2820        6412 :                 size = xfs_attr_leaf_entsize_remote(name_rmt->namelen);
    2821             :         }
    2822   495468385 :         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   782987903 : xfs_attr_leaf_newentsize(
    2833             :         struct xfs_da_args      *args,
    2834             :         int                     *local)
    2835             : {
    2836   782987903 :         int                     size;
    2837             : 
    2838   782987903 :         size = xfs_attr_leaf_entsize_local(args->namelen, args->valuelen);
    2839   782987903 :         if (size < xfs_attr_leaf_entsize_local_max(args->geo->blksize)) {
    2840   782974905 :                 if (local)
    2841   410841422 :                         *local = 1;
    2842   782974905 :                 return size;
    2843             :         }
    2844       12998 :         if (local)
    2845        6674 :                 *local = 0;
    2846       12998 :         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        3152 : xfs_attr3_leaf_clearflag(
    2859             :         struct xfs_da_args      *args)
    2860             : {
    2861        3152 :         struct xfs_attr_leafblock *leaf;
    2862        3152 :         struct xfs_attr_leaf_entry *entry;
    2863        3152 :         struct xfs_attr_leaf_name_remote *name_rmt;
    2864        3152 :         struct xfs_buf          *bp;
    2865        3152 :         int                     error;
    2866             : #ifdef DEBUG
    2867        3152 :         struct xfs_attr3_icleaf_hdr ichdr;
    2868        3152 :         xfs_attr_leaf_name_local_t *name_loc;
    2869        3152 :         int namelen;
    2870        3152 :         char *name;
    2871             : #endif /* DEBUG */
    2872             : 
    2873        3152 :         trace_xfs_attr_leaf_clearflag(args);
    2874             :         /*
    2875             :          * Set up the operation.
    2876             :          */
    2877        3152 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
    2878             :                         args->blkno, &bp);
    2879        3152 :         if (error)
    2880             :                 return error;
    2881             : 
    2882        3152 :         leaf = bp->b_addr;
    2883        3152 :         entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
    2884        3152 :         ASSERT(entry->flags & XFS_ATTR_INCOMPLETE);
    2885             : 
    2886             : #ifdef DEBUG
    2887        3152 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    2888        3152 :         ASSERT(args->index < ichdr.count);
    2889        3152 :         ASSERT(args->index >= 0);
    2890             : 
    2891        3152 :         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        3152 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
    2897        3152 :                 namelen = name_rmt->namelen;
    2898        3152 :                 name = (char *)name_rmt->name;
    2899             :         }
    2900        3152 :         ASSERT(be32_to_cpu(entry->hashval) == args->hashval);
    2901        3152 :         ASSERT(namelen == args->namelen);
    2902        6304 :         ASSERT(memcmp(name, args->name, namelen) == 0);
    2903             : #endif /* DEBUG */
    2904             : 
    2905        3152 :         entry->flags &= ~XFS_ATTR_INCOMPLETE;
    2906        3152 :         xfs_trans_log_buf(args->trans, bp,
    2907        3152 :                          XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
    2908             : 
    2909        3152 :         if (args->rmtblkno) {
    2910        3152 :                 ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0);
    2911        3152 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
    2912        3152 :                 name_rmt->valueblk = cpu_to_be32(args->rmtblkno);
    2913        3152 :                 name_rmt->valuelen = cpu_to_be32(args->rmtvaluelen);
    2914        3152 :                 xfs_trans_log_buf(args->trans, bp,
    2915             :                          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     1218157 : xfs_attr3_leaf_setflag(
    2926             :         struct xfs_da_args      *args)
    2927             : {
    2928     1218157 :         struct xfs_attr_leafblock *leaf;
    2929     1218157 :         struct xfs_attr_leaf_entry *entry;
    2930     1218157 :         struct xfs_attr_leaf_name_remote *name_rmt;
    2931     1218157 :         struct xfs_buf          *bp;
    2932     1218157 :         int error;
    2933             : #ifdef DEBUG
    2934     1218157 :         struct xfs_attr3_icleaf_hdr ichdr;
    2935             : #endif
    2936             : 
    2937     1218157 :         trace_xfs_attr_leaf_setflag(args);
    2938             : 
    2939             :         /*
    2940             :          * Set up the operation.
    2941             :          */
    2942     1218112 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
    2943             :                         args->blkno, &bp);
    2944     1218195 :         if (error)
    2945             :                 return error;
    2946             : 
    2947     1218196 :         leaf = bp->b_addr;
    2948             : #ifdef DEBUG
    2949     1218196 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
    2950     1218173 :         ASSERT(args->index < ichdr.count);
    2951     1218173 :         ASSERT(args->index >= 0);
    2952             : #endif
    2953     1218173 :         entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
    2954             : 
    2955     1218173 :         ASSERT((entry->flags & XFS_ATTR_INCOMPLETE) == 0);
    2956     1218173 :         entry->flags |= XFS_ATTR_INCOMPLETE;
    2957     1218173 :         xfs_trans_log_buf(args->trans, bp,
    2958     1218173 :                         XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
    2959     1218180 :         if ((entry->flags & XFS_ATTR_LOCAL) == 0) {
    2960          68 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
    2961          68 :                 name_rmt->valueblk = 0;
    2962          68 :                 name_rmt->valuelen = 0;
    2963          68 :                 xfs_trans_log_buf(args->trans, bp,
    2964             :                          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    33344629 : xfs_attr3_leaf_flipflags(
    2979             :         struct xfs_da_args      *args)
    2980             : {
    2981    33344629 :         struct xfs_attr_leafblock *leaf1;
    2982    33344629 :         struct xfs_attr_leafblock *leaf2;
    2983    33344629 :         struct xfs_attr_leaf_entry *entry1;
    2984    33344629 :         struct xfs_attr_leaf_entry *entry2;
    2985    33344629 :         struct xfs_attr_leaf_name_remote *name_rmt;
    2986    33344629 :         struct xfs_buf          *bp1;
    2987    33344629 :         struct xfs_buf          *bp2;
    2988    33344629 :         int error;
    2989             : #ifdef DEBUG
    2990    33344629 :         struct xfs_attr3_icleaf_hdr ichdr1;
    2991    33344629 :         struct xfs_attr3_icleaf_hdr ichdr2;
    2992    33344629 :         xfs_attr_leaf_name_local_t *name_loc;
    2993    33344629 :         int namelen1, namelen2;
    2994    33344629 :         char *name1, *name2;
    2995             : #endif /* DEBUG */
    2996             : 
    2997    33344629 :         trace_xfs_attr_leaf_flipflags(args);
    2998             : 
    2999             :         /*
    3000             :          * Read the block containing the "old" attr
    3001             :          */
    3002    33344489 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
    3003             :                         args->blkno, &bp1);
    3004    33344538 :         if (error)
    3005             :                 return error;
    3006             : 
    3007             :         /*
    3008             :          * Read the block containing the "new" attr, if it is different
    3009             :          */
    3010    33344538 :         if (args->blkno2 != args->blkno) {
    3011         405 :                 error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
    3012             :                                 args->blkno2, &bp2);
    3013         405 :                 if (error)
    3014             :                         return error;
    3015             :         } else {
    3016    33344133 :                 bp2 = bp1;
    3017             :         }
    3018             : 
    3019    33344538 :         leaf1 = bp1->b_addr;
    3020    33344538 :         entry1 = &xfs_attr3_leaf_entryp(leaf1)[args->index];
    3021             : 
    3022    33344538 :         leaf2 = bp2->b_addr;
    3023    33344538 :         entry2 = &xfs_attr3_leaf_entryp(leaf2)[args->index2];
    3024             : 
    3025             : #ifdef DEBUG
    3026    33344538 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr1, leaf1);
    3027    33344310 :         ASSERT(args->index < ichdr1.count);
    3028    33344310 :         ASSERT(args->index >= 0);
    3029             : 
    3030    33344310 :         xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr2, leaf2);
    3031    33344308 :         ASSERT(args->index2 < ichdr2.count);
    3032    33344308 :         ASSERT(args->index2 >= 0);
    3033             : 
    3034    33344308 :         if (entry1->flags & XFS_ATTR_LOCAL) {
    3035    33344298 :                 name_loc = xfs_attr3_leaf_name_local(leaf1, args->index);
    3036    33344298 :                 namelen1 = name_loc->namelen;
    3037    33344298 :                 name1 = (char *)name_loc->nameval;
    3038             :         } else {
    3039          10 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index);
    3040          10 :                 namelen1 = name_rmt->namelen;
    3041          10 :                 name1 = (char *)name_rmt->name;
    3042             :         }
    3043    33344308 :         if (entry2->flags & XFS_ATTR_LOCAL) {
    3044    33344322 :                 name_loc = xfs_attr3_leaf_name_local(leaf2, args->index2);
    3045    33344322 :                 namelen2 = name_loc->namelen;
    3046    33344322 :                 name2 = (char *)name_loc->nameval;
    3047             :         } else {
    3048          24 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf2, args->index2);
    3049          24 :                 namelen2 = name_rmt->namelen;
    3050          24 :                 name2 = (char *)name_rmt->name;
    3051             :         }
    3052    33344308 :         ASSERT(be32_to_cpu(entry1->hashval) == be32_to_cpu(entry2->hashval));
    3053    33344308 :         ASSERT(namelen1 == namelen2);
    3054    66688616 :         ASSERT(memcmp(name1, name2, namelen1) == 0);
    3055             : #endif /* DEBUG */
    3056             : 
    3057    33344308 :         ASSERT(entry1->flags & XFS_ATTR_INCOMPLETE);
    3058    33344308 :         ASSERT((entry2->flags & XFS_ATTR_INCOMPLETE) == 0);
    3059             : 
    3060    33344308 :         entry1->flags &= ~XFS_ATTR_INCOMPLETE;
    3061    33344308 :         xfs_trans_log_buf(args->trans, bp1,
    3062    33344308 :                           XFS_DA_LOGRANGE(leaf1, entry1, sizeof(*entry1)));
    3063    33344612 :         if (args->rmtblkno) {
    3064          10 :                 ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0);
    3065          10 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index);
    3066          10 :                 name_rmt->valueblk = cpu_to_be32(args->rmtblkno);
    3067          10 :                 name_rmt->valuelen = cpu_to_be32(args->rmtvaluelen);
    3068          10 :                 xfs_trans_log_buf(args->trans, bp1,
    3069             :                          XFS_DA_LOGRANGE(leaf1, name_rmt, sizeof(*name_rmt)));
    3070             :         }
    3071             : 
    3072    33344612 :         entry2->flags |= XFS_ATTR_INCOMPLETE;
    3073    33344612 :         xfs_trans_log_buf(args->trans, bp2,
    3074    33344612 :                           XFS_DA_LOGRANGE(leaf2, entry2, sizeof(*entry2)));
    3075    33344590 :         if ((entry2->flags & XFS_ATTR_LOCAL) == 0) {
    3076          20 :                 name_rmt = xfs_attr3_leaf_name_remote(leaf2, args->index2);
    3077          20 :                 name_rmt->valueblk = 0;
    3078          20 :                 name_rmt->valuelen = 0;
    3079          20 :                 xfs_trans_log_buf(args->trans, bp2,
    3080             :                          XFS_DA_LOGRANGE(leaf2, name_rmt, sizeof(*name_rmt)));
    3081             :         }
    3082             : 
    3083             :         return 0;
    3084             : }

Generated by: LCOV version 1.14