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