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