Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
0004  * All Rights Reserved.
0005  */
0006 #include "xfs.h"
0007 #include "xfs_fs.h"
0008 #include "xfs_shared.h"
0009 #include "xfs_format.h"
0010 #include "xfs_log_format.h"
0011 #include "xfs_trans_resv.h"
0012 #include "xfs_mount.h"
0013 #include "xfs_defer.h"
0014 #include "xfs_da_format.h"
0015 #include "xfs_da_btree.h"
0016 #include "xfs_attr_sf.h"
0017 #include "xfs_inode.h"
0018 #include "xfs_trans.h"
0019 #include "xfs_bmap.h"
0020 #include "xfs_bmap_btree.h"
0021 #include "xfs_attr.h"
0022 #include "xfs_attr_leaf.h"
0023 #include "xfs_attr_remote.h"
0024 #include "xfs_quota.h"
0025 #include "xfs_trans_space.h"
0026 #include "xfs_trace.h"
0027 #include "xfs_attr_item.h"
0028 #include "xfs_xattr.h"
0029 
0030 struct kmem_cache       *xfs_attr_intent_cache;
0031 
0032 /*
0033  * xfs_attr.c
0034  *
0035  * Provide the external interfaces to manage attribute lists.
0036  */
0037 
0038 /*========================================================================
0039  * Function prototypes for the kernel.
0040  *========================================================================*/
0041 
0042 /*
0043  * Internal routines when attribute list fits inside the inode.
0044  */
0045 STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
0046 
0047 /*
0048  * Internal routines when attribute list is one block.
0049  */
0050 STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
0051 STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
0052 STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp);
0053 STATIC int xfs_attr_leaf_try_add(struct xfs_da_args *args);
0054 
0055 /*
0056  * Internal routines when attribute list is more than one block.
0057  */
0058 STATIC int xfs_attr_node_get(xfs_da_args_t *args);
0059 STATIC void xfs_attr_restore_rmt_blk(struct xfs_da_args *args);
0060 static int xfs_attr_node_try_addname(struct xfs_attr_intent *attr);
0061 STATIC int xfs_attr_node_addname_find_attr(struct xfs_attr_intent *attr);
0062 STATIC int xfs_attr_node_remove_attr(struct xfs_attr_intent *attr);
0063 STATIC int xfs_attr_node_lookup(struct xfs_da_args *args,
0064         struct xfs_da_state *state);
0065 
0066 int
0067 xfs_inode_hasattr(
0068     struct xfs_inode    *ip)
0069 {
0070     if (!xfs_inode_has_attr_fork(ip))
0071         return 0;
0072     if (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
0073         ip->i_af.if_nextents == 0)
0074         return 0;
0075     return 1;
0076 }
0077 
0078 /*
0079  * Returns true if the there is exactly only block in the attr fork, in which
0080  * case the attribute fork consists of a single leaf block entry.
0081  */
0082 bool
0083 xfs_attr_is_leaf(
0084     struct xfs_inode    *ip)
0085 {
0086     struct xfs_ifork    *ifp = &ip->i_af;
0087     struct xfs_iext_cursor  icur;
0088     struct xfs_bmbt_irec    imap;
0089 
0090     if (ifp->if_nextents != 1 || ifp->if_format != XFS_DINODE_FMT_EXTENTS)
0091         return false;
0092 
0093     xfs_iext_first(ifp, &icur);
0094     xfs_iext_get_extent(ifp, &icur, &imap);
0095     return imap.br_startoff == 0 && imap.br_blockcount == 1;
0096 }
0097 
0098 /*
0099  * XXX (dchinner): name path state saving and refilling is an optimisation to
0100  * avoid needing to look up name entries after rolling transactions removing
0101  * remote xattr blocks between the name entry lookup and name entry removal.
0102  * This optimisation got sidelined when combining the set and remove state
0103  * machines, but the code has been left in place because it is worthwhile to
0104  * restore the optimisation once the combined state machine paths have settled.
0105  *
0106  * This comment is a public service announcement to remind Future Dave that he
0107  * still needs to restore this code to working order.
0108  */
0109 #if 0
0110 /*
0111  * Fill in the disk block numbers in the state structure for the buffers
0112  * that are attached to the state structure.
0113  * This is done so that we can quickly reattach ourselves to those buffers
0114  * after some set of transaction commits have released these buffers.
0115  */
0116 static int
0117 xfs_attr_fillstate(xfs_da_state_t *state)
0118 {
0119     xfs_da_state_path_t *path;
0120     xfs_da_state_blk_t *blk;
0121     int level;
0122 
0123     trace_xfs_attr_fillstate(state->args);
0124 
0125     /*
0126      * Roll down the "path" in the state structure, storing the on-disk
0127      * block number for those buffers in the "path".
0128      */
0129     path = &state->path;
0130     ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
0131     for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
0132         if (blk->bp) {
0133             blk->disk_blkno = xfs_buf_daddr(blk->bp);
0134             blk->bp = NULL;
0135         } else {
0136             blk->disk_blkno = 0;
0137         }
0138     }
0139 
0140     /*
0141      * Roll down the "altpath" in the state structure, storing the on-disk
0142      * block number for those buffers in the "altpath".
0143      */
0144     path = &state->altpath;
0145     ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
0146     for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
0147         if (blk->bp) {
0148             blk->disk_blkno = xfs_buf_daddr(blk->bp);
0149             blk->bp = NULL;
0150         } else {
0151             blk->disk_blkno = 0;
0152         }
0153     }
0154 
0155     return 0;
0156 }
0157 
0158 /*
0159  * Reattach the buffers to the state structure based on the disk block
0160  * numbers stored in the state structure.
0161  * This is done after some set of transaction commits have released those
0162  * buffers from our grip.
0163  */
0164 static int
0165 xfs_attr_refillstate(xfs_da_state_t *state)
0166 {
0167     xfs_da_state_path_t *path;
0168     xfs_da_state_blk_t *blk;
0169     int level, error;
0170 
0171     trace_xfs_attr_refillstate(state->args);
0172 
0173     /*
0174      * Roll down the "path" in the state structure, storing the on-disk
0175      * block number for those buffers in the "path".
0176      */
0177     path = &state->path;
0178     ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
0179     for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
0180         if (blk->disk_blkno) {
0181             error = xfs_da3_node_read_mapped(state->args->trans,
0182                     state->args->dp, blk->disk_blkno,
0183                     &blk->bp, XFS_ATTR_FORK);
0184             if (error)
0185                 return error;
0186         } else {
0187             blk->bp = NULL;
0188         }
0189     }
0190 
0191     /*
0192      * Roll down the "altpath" in the state structure, storing the on-disk
0193      * block number for those buffers in the "altpath".
0194      */
0195     path = &state->altpath;
0196     ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
0197     for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
0198         if (blk->disk_blkno) {
0199             error = xfs_da3_node_read_mapped(state->args->trans,
0200                     state->args->dp, blk->disk_blkno,
0201                     &blk->bp, XFS_ATTR_FORK);
0202             if (error)
0203                 return error;
0204         } else {
0205             blk->bp = NULL;
0206         }
0207     }
0208 
0209     return 0;
0210 }
0211 #else
0212 static int xfs_attr_fillstate(xfs_da_state_t *state) { return 0; }
0213 #endif
0214 
0215 /*========================================================================
0216  * Overall external interface routines.
0217  *========================================================================*/
0218 
0219 /*
0220  * Retrieve an extended attribute and its value.  Must have ilock.
0221  * Returns 0 on successful retrieval, otherwise an error.
0222  */
0223 int
0224 xfs_attr_get_ilocked(
0225     struct xfs_da_args  *args)
0226 {
0227     ASSERT(xfs_isilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
0228 
0229     if (!xfs_inode_hasattr(args->dp))
0230         return -ENOATTR;
0231 
0232     if (args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
0233         return xfs_attr_shortform_getvalue(args);
0234     if (xfs_attr_is_leaf(args->dp))
0235         return xfs_attr_leaf_get(args);
0236     return xfs_attr_node_get(args);
0237 }
0238 
0239 /*
0240  * Retrieve an extended attribute by name, and its value if requested.
0241  *
0242  * If args->valuelen is zero, then the caller does not want the value, just an
0243  * indication whether the attribute exists and the size of the value if it
0244  * exists. The size is returned in args.valuelen.
0245  *
0246  * If args->value is NULL but args->valuelen is non-zero, allocate the buffer
0247  * for the value after existence of the attribute has been determined. The
0248  * caller always has to free args->value if it is set, no matter if this
0249  * function was successful or not.
0250  *
0251  * If the attribute is found, but exceeds the size limit set by the caller in
0252  * args->valuelen, return -ERANGE with the size of the attribute that was found
0253  * in args->valuelen.
0254  */
0255 int
0256 xfs_attr_get(
0257     struct xfs_da_args  *args)
0258 {
0259     uint            lock_mode;
0260     int         error;
0261 
0262     XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
0263 
0264     if (xfs_is_shutdown(args->dp->i_mount))
0265         return -EIO;
0266 
0267     args->geo = args->dp->i_mount->m_attr_geo;
0268     args->whichfork = XFS_ATTR_FORK;
0269     args->hashval = xfs_da_hashname(args->name, args->namelen);
0270 
0271     /* Entirely possible to look up a name which doesn't exist */
0272     args->op_flags = XFS_DA_OP_OKNOENT;
0273 
0274     lock_mode = xfs_ilock_attr_map_shared(args->dp);
0275     error = xfs_attr_get_ilocked(args);
0276     xfs_iunlock(args->dp, lock_mode);
0277 
0278     return error;
0279 }
0280 
0281 /*
0282  * Calculate how many blocks we need for the new attribute,
0283  */
0284 int
0285 xfs_attr_calc_size(
0286     struct xfs_da_args  *args,
0287     int         *local)
0288 {
0289     struct xfs_mount    *mp = args->dp->i_mount;
0290     int         size;
0291     int         nblks;
0292 
0293     /*
0294      * Determine space new attribute will use, and if it would be
0295      * "local" or "remote" (note: local != inline).
0296      */
0297     size = xfs_attr_leaf_newentsize(args, local);
0298     nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
0299     if (*local) {
0300         if (size > (args->geo->blksize / 2)) {
0301             /* Double split possible */
0302             nblks *= 2;
0303         }
0304     } else {
0305         /*
0306          * Out of line attribute, cannot double split, but
0307          * make room for the attribute value itself.
0308          */
0309         uint    dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
0310         nblks += dblocks;
0311         nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
0312     }
0313 
0314     return nblks;
0315 }
0316 
0317 /* Initialize transaction reservation for attr operations */
0318 void
0319 xfs_init_attr_trans(
0320     struct xfs_da_args  *args,
0321     struct xfs_trans_res    *tres,
0322     unsigned int        *total)
0323 {
0324     struct xfs_mount    *mp = args->dp->i_mount;
0325 
0326     if (args->value) {
0327         tres->tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
0328                  M_RES(mp)->tr_attrsetrt.tr_logres *
0329                  args->total;
0330         tres->tr_logcount = XFS_ATTRSET_LOG_COUNT;
0331         tres->tr_logflags = XFS_TRANS_PERM_LOG_RES;
0332         *total = args->total;
0333     } else {
0334         *tres = M_RES(mp)->tr_attrrm;
0335         *total = XFS_ATTRRM_SPACE_RES(mp);
0336     }
0337 }
0338 
0339 /*
0340  * Add an attr to a shortform fork. If there is no space,
0341  * xfs_attr_shortform_addname() will convert to leaf format and return -ENOSPC.
0342  * to use.
0343  */
0344 STATIC int
0345 xfs_attr_try_sf_addname(
0346     struct xfs_inode    *dp,
0347     struct xfs_da_args  *args)
0348 {
0349 
0350     int         error;
0351 
0352     /*
0353      * Build initial attribute list (if required).
0354      */
0355     if (dp->i_af.if_format == XFS_DINODE_FMT_EXTENTS)
0356         xfs_attr_shortform_create(args);
0357 
0358     error = xfs_attr_shortform_addname(args);
0359     if (error == -ENOSPC)
0360         return error;
0361 
0362     /*
0363      * Commit the shortform mods, and we're done.
0364      * NOTE: this is also the error path (EEXIST, etc).
0365      */
0366     if (!error && !(args->op_flags & XFS_DA_OP_NOTIME))
0367         xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
0368 
0369     if (xfs_has_wsync(dp->i_mount))
0370         xfs_trans_set_sync(args->trans);
0371 
0372     return error;
0373 }
0374 
0375 static int
0376 xfs_attr_sf_addname(
0377     struct xfs_attr_intent      *attr)
0378 {
0379     struct xfs_da_args      *args = attr->xattri_da_args;
0380     struct xfs_inode        *dp = args->dp;
0381     int             error = 0;
0382 
0383     error = xfs_attr_try_sf_addname(dp, args);
0384     if (error != -ENOSPC) {
0385         ASSERT(!error || error == -EEXIST);
0386         attr->xattri_dela_state = XFS_DAS_DONE;
0387         goto out;
0388     }
0389 
0390     /*
0391      * It won't fit in the shortform, transform to a leaf block.  GROT:
0392      * another possible req'mt for a double-split btree op.
0393      */
0394     error = xfs_attr_shortform_to_leaf(args);
0395     if (error)
0396         return error;
0397 
0398     attr->xattri_dela_state = XFS_DAS_LEAF_ADD;
0399 out:
0400     trace_xfs_attr_sf_addname_return(attr->xattri_dela_state, args->dp);
0401     return error;
0402 }
0403 
0404 /*
0405  * Handle the state change on completion of a multi-state attr operation.
0406  *
0407  * If the XFS_DA_OP_REPLACE flag is set, this means the operation was the first
0408  * modification in a attr replace operation and we still have to do the second
0409  * state, indicated by @replace_state.
0410  *
0411  * We consume the XFS_DA_OP_REPLACE flag so that when we are called again on
0412  * completion of the second half of the attr replace operation we correctly
0413  * signal that it is done.
0414  */
0415 static enum xfs_delattr_state
0416 xfs_attr_complete_op(
0417     struct xfs_attr_intent  *attr,
0418     enum xfs_delattr_state  replace_state)
0419 {
0420     struct xfs_da_args  *args = attr->xattri_da_args;
0421     bool            do_replace = args->op_flags & XFS_DA_OP_REPLACE;
0422 
0423     args->op_flags &= ~XFS_DA_OP_REPLACE;
0424     if (do_replace) {
0425         args->attr_filter &= ~XFS_ATTR_INCOMPLETE;
0426         return replace_state;
0427     }
0428     return XFS_DAS_DONE;
0429 }
0430 
0431 static int
0432 xfs_attr_leaf_addname(
0433     struct xfs_attr_intent  *attr)
0434 {
0435     struct xfs_da_args  *args = attr->xattri_da_args;
0436     int         error;
0437 
0438     ASSERT(xfs_attr_is_leaf(args->dp));
0439 
0440     /*
0441      * Use the leaf buffer we may already hold locked as a result of
0442      * a sf-to-leaf conversion.
0443      */
0444     error = xfs_attr_leaf_try_add(args);
0445 
0446     if (error == -ENOSPC) {
0447         error = xfs_attr3_leaf_to_node(args);
0448         if (error)
0449             return error;
0450 
0451         /*
0452          * We're not in leaf format anymore, so roll the transaction and
0453          * retry the add to the newly allocated node block.
0454          */
0455         attr->xattri_dela_state = XFS_DAS_NODE_ADD;
0456         goto out;
0457     }
0458     if (error)
0459         return error;
0460 
0461     /*
0462      * We need to commit and roll if we need to allocate remote xattr blocks
0463      * or perform more xattr manipulations. Otherwise there is nothing more
0464      * to do and we can return success.
0465      */
0466     if (args->rmtblkno)
0467         attr->xattri_dela_state = XFS_DAS_LEAF_SET_RMT;
0468     else
0469         attr->xattri_dela_state = xfs_attr_complete_op(attr,
0470                             XFS_DAS_LEAF_REPLACE);
0471 out:
0472     trace_xfs_attr_leaf_addname_return(attr->xattri_dela_state, args->dp);
0473     return error;
0474 }
0475 
0476 /*
0477  * Add an entry to a node format attr tree.
0478  *
0479  * Note that we might still have a leaf here - xfs_attr_is_leaf() cannot tell
0480  * the difference between leaf + remote attr blocks and a node format tree,
0481  * so we may still end up having to convert from leaf to node format here.
0482  */
0483 static int
0484 xfs_attr_node_addname(
0485     struct xfs_attr_intent  *attr)
0486 {
0487     struct xfs_da_args  *args = attr->xattri_da_args;
0488     int         error;
0489 
0490     error = xfs_attr_node_addname_find_attr(attr);
0491     if (error)
0492         return error;
0493 
0494     error = xfs_attr_node_try_addname(attr);
0495     if (error == -ENOSPC) {
0496         error = xfs_attr3_leaf_to_node(args);
0497         if (error)
0498             return error;
0499         /*
0500          * No state change, we really are in node form now
0501          * but we need the transaction rolled to continue.
0502          */
0503         goto out;
0504     }
0505     if (error)
0506         return error;
0507 
0508     if (args->rmtblkno)
0509         attr->xattri_dela_state = XFS_DAS_NODE_SET_RMT;
0510     else
0511         attr->xattri_dela_state = xfs_attr_complete_op(attr,
0512                             XFS_DAS_NODE_REPLACE);
0513 out:
0514     trace_xfs_attr_node_addname_return(attr->xattri_dela_state, args->dp);
0515     return error;
0516 }
0517 
0518 static int
0519 xfs_attr_rmtval_alloc(
0520     struct xfs_attr_intent      *attr)
0521 {
0522     struct xfs_da_args              *args = attr->xattri_da_args;
0523     int             error = 0;
0524 
0525     /*
0526      * If there was an out-of-line value, allocate the blocks we
0527      * identified for its storage and copy the value.  This is done
0528      * after we create the attribute so that we don't overflow the
0529      * maximum size of a transaction and/or hit a deadlock.
0530      */
0531     if (attr->xattri_blkcnt > 0) {
0532         error = xfs_attr_rmtval_set_blk(attr);
0533         if (error)
0534             return error;
0535         /* Roll the transaction only if there is more to allocate. */
0536         if (attr->xattri_blkcnt > 0)
0537             goto out;
0538     }
0539 
0540     error = xfs_attr_rmtval_set_value(args);
0541     if (error)
0542         return error;
0543 
0544     attr->xattri_dela_state = xfs_attr_complete_op(attr,
0545                         ++attr->xattri_dela_state);
0546     /*
0547      * If we are not doing a rename, we've finished the operation but still
0548      * have to clear the incomplete flag protecting the new attr from
0549      * exposing partially initialised state if we crash during creation.
0550      */
0551     if (attr->xattri_dela_state == XFS_DAS_DONE)
0552         error = xfs_attr3_leaf_clearflag(args);
0553 out:
0554     trace_xfs_attr_rmtval_alloc(attr->xattri_dela_state, args->dp);
0555     return error;
0556 }
0557 
0558 /*
0559  * Mark an attribute entry INCOMPLETE and save pointers to the relevant buffers
0560  * for later deletion of the entry.
0561  */
0562 static int
0563 xfs_attr_leaf_mark_incomplete(
0564     struct xfs_da_args  *args,
0565     struct xfs_da_state *state)
0566 {
0567     int         error;
0568 
0569     /*
0570      * Fill in disk block numbers in the state structure
0571      * so that we can get the buffers back after we commit
0572      * several transactions in the following calls.
0573      */
0574     error = xfs_attr_fillstate(state);
0575     if (error)
0576         return error;
0577 
0578     /*
0579      * Mark the attribute as INCOMPLETE
0580      */
0581     return xfs_attr3_leaf_setflag(args);
0582 }
0583 
0584 /* Ensure the da state of an xattr deferred work item is ready to go. */
0585 static inline void
0586 xfs_attr_item_init_da_state(
0587     struct xfs_attr_intent  *attr)
0588 {
0589     struct xfs_da_args  *args = attr->xattri_da_args;
0590 
0591     if (!attr->xattri_da_state)
0592         attr->xattri_da_state = xfs_da_state_alloc(args);
0593     else
0594         xfs_da_state_reset(attr->xattri_da_state, args);
0595 }
0596 
0597 /*
0598  * Initial setup for xfs_attr_node_removename.  Make sure the attr is there and
0599  * the blocks are valid.  Attr keys with remote blocks will be marked
0600  * incomplete.
0601  */
0602 static
0603 int xfs_attr_node_removename_setup(
0604     struct xfs_attr_intent      *attr)
0605 {
0606     struct xfs_da_args      *args = attr->xattri_da_args;
0607     struct xfs_da_state     *state;
0608     int             error;
0609 
0610     xfs_attr_item_init_da_state(attr);
0611     error = xfs_attr_node_lookup(args, attr->xattri_da_state);
0612     if (error != -EEXIST)
0613         goto out;
0614     error = 0;
0615 
0616     state = attr->xattri_da_state;
0617     ASSERT(state->path.blk[state->path.active - 1].bp != NULL);
0618     ASSERT(state->path.blk[state->path.active - 1].magic ==
0619         XFS_ATTR_LEAF_MAGIC);
0620 
0621     error = xfs_attr_leaf_mark_incomplete(args, state);
0622     if (error)
0623         goto out;
0624     if (args->rmtblkno > 0)
0625         error = xfs_attr_rmtval_invalidate(args);
0626 out:
0627     if (error) {
0628         xfs_da_state_free(attr->xattri_da_state);
0629         attr->xattri_da_state = NULL;
0630     }
0631 
0632     return error;
0633 }
0634 
0635 /*
0636  * Remove the original attr we have just replaced. This is dependent on the
0637  * original lookup and insert placing the old attr in args->blkno/args->index
0638  * and the new attr in args->blkno2/args->index2.
0639  */
0640 static int
0641 xfs_attr_leaf_remove_attr(
0642     struct xfs_attr_intent      *attr)
0643 {
0644     struct xfs_da_args              *args = attr->xattri_da_args;
0645     struct xfs_inode        *dp = args->dp;
0646     struct xfs_buf          *bp = NULL;
0647     int             forkoff;
0648     int             error;
0649 
0650     error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno,
0651                    &bp);
0652     if (error)
0653         return error;
0654 
0655     xfs_attr3_leaf_remove(bp, args);
0656 
0657     forkoff = xfs_attr_shortform_allfit(bp, dp);
0658     if (forkoff)
0659         error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
0660         /* bp is gone due to xfs_da_shrink_inode */
0661 
0662     return error;
0663 }
0664 
0665 /*
0666  * Shrink an attribute from leaf to shortform. Used by the node format remove
0667  * path when the node format collapses to a single block and so we have to check
0668  * if it can be collapsed further.
0669  */
0670 static int
0671 xfs_attr_leaf_shrink(
0672     struct xfs_da_args  *args)
0673 {
0674     struct xfs_inode    *dp = args->dp;
0675     struct xfs_buf      *bp;
0676     int         forkoff;
0677     int         error;
0678 
0679     if (!xfs_attr_is_leaf(dp))
0680         return 0;
0681 
0682     error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp);
0683     if (error)
0684         return error;
0685 
0686     forkoff = xfs_attr_shortform_allfit(bp, dp);
0687     if (forkoff) {
0688         error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
0689         /* bp is gone due to xfs_da_shrink_inode */
0690     } else {
0691         xfs_trans_brelse(args->trans, bp);
0692     }
0693 
0694     return error;
0695 }
0696 
0697 /*
0698  * Run the attribute operation specified in @attr.
0699  *
0700  * This routine is meant to function as a delayed operation and will set the
0701  * state to XFS_DAS_DONE when the operation is complete.  Calling functions will
0702  * need to handle this, and recall the function until either an error or
0703  * XFS_DAS_DONE is detected.
0704  */
0705 int
0706 xfs_attr_set_iter(
0707     struct xfs_attr_intent      *attr)
0708 {
0709     struct xfs_da_args              *args = attr->xattri_da_args;
0710     int             error = 0;
0711 
0712     /* State machine switch */
0713 next_state:
0714     switch (attr->xattri_dela_state) {
0715     case XFS_DAS_UNINIT:
0716         ASSERT(0);
0717         return -EFSCORRUPTED;
0718     case XFS_DAS_SF_ADD:
0719         return xfs_attr_sf_addname(attr);
0720     case XFS_DAS_LEAF_ADD:
0721         return xfs_attr_leaf_addname(attr);
0722     case XFS_DAS_NODE_ADD:
0723         return xfs_attr_node_addname(attr);
0724 
0725     case XFS_DAS_SF_REMOVE:
0726         error = xfs_attr_sf_removename(args);
0727         attr->xattri_dela_state = xfs_attr_complete_op(attr,
0728                         xfs_attr_init_add_state(args));
0729         break;
0730     case XFS_DAS_LEAF_REMOVE:
0731         error = xfs_attr_leaf_removename(args);
0732         attr->xattri_dela_state = xfs_attr_complete_op(attr,
0733                         xfs_attr_init_add_state(args));
0734         break;
0735     case XFS_DAS_NODE_REMOVE:
0736         error = xfs_attr_node_removename_setup(attr);
0737         if (error == -ENOATTR &&
0738             (args->op_flags & XFS_DA_OP_RECOVERY)) {
0739             attr->xattri_dela_state = xfs_attr_complete_op(attr,
0740                         xfs_attr_init_add_state(args));
0741             error = 0;
0742             break;
0743         }
0744         if (error)
0745             return error;
0746         attr->xattri_dela_state = XFS_DAS_NODE_REMOVE_RMT;
0747         if (args->rmtblkno == 0)
0748             attr->xattri_dela_state++;
0749         break;
0750 
0751     case XFS_DAS_LEAF_SET_RMT:
0752     case XFS_DAS_NODE_SET_RMT:
0753         error = xfs_attr_rmtval_find_space(attr);
0754         if (error)
0755             return error;
0756         attr->xattri_dela_state++;
0757         fallthrough;
0758 
0759     case XFS_DAS_LEAF_ALLOC_RMT:
0760     case XFS_DAS_NODE_ALLOC_RMT:
0761         error = xfs_attr_rmtval_alloc(attr);
0762         if (error)
0763             return error;
0764         if (attr->xattri_dela_state == XFS_DAS_DONE)
0765             break;
0766         goto next_state;
0767 
0768     case XFS_DAS_LEAF_REPLACE:
0769     case XFS_DAS_NODE_REPLACE:
0770         /*
0771          * We must "flip" the incomplete flags on the "new" and "old"
0772          * attribute/value pairs so that one disappears and one appears
0773          * atomically.
0774          */
0775         error = xfs_attr3_leaf_flipflags(args);
0776         if (error)
0777             return error;
0778         /*
0779          * We must commit the flag value change now to make it atomic
0780          * and then we can start the next trans in series at REMOVE_OLD.
0781          */
0782         attr->xattri_dela_state++;
0783         break;
0784 
0785     case XFS_DAS_LEAF_REMOVE_OLD:
0786     case XFS_DAS_NODE_REMOVE_OLD:
0787         /*
0788          * If we have a remote attr, start the process of removing it
0789          * by invalidating any cached buffers.
0790          *
0791          * If we don't have a remote attr, we skip the remote block
0792          * removal state altogether with a second state increment.
0793          */
0794         xfs_attr_restore_rmt_blk(args);
0795         if (args->rmtblkno) {
0796             error = xfs_attr_rmtval_invalidate(args);
0797             if (error)
0798                 return error;
0799         } else {
0800             attr->xattri_dela_state++;
0801         }
0802 
0803         attr->xattri_dela_state++;
0804         goto next_state;
0805 
0806     case XFS_DAS_LEAF_REMOVE_RMT:
0807     case XFS_DAS_NODE_REMOVE_RMT:
0808         error = xfs_attr_rmtval_remove(attr);
0809         if (error == -EAGAIN) {
0810             error = 0;
0811             break;
0812         }
0813         if (error)
0814             return error;
0815 
0816         /*
0817          * We've finished removing the remote attr blocks, so commit the
0818          * transaction and move on to removing the attr name from the
0819          * leaf/node block. Removing the attr might require a full
0820          * transaction reservation for btree block freeing, so we
0821          * can't do that in the same transaction where we removed the
0822          * remote attr blocks.
0823          */
0824         attr->xattri_dela_state++;
0825         break;
0826 
0827     case XFS_DAS_LEAF_REMOVE_ATTR:
0828         error = xfs_attr_leaf_remove_attr(attr);
0829         attr->xattri_dela_state = xfs_attr_complete_op(attr,
0830                         xfs_attr_init_add_state(args));
0831         break;
0832 
0833     case XFS_DAS_NODE_REMOVE_ATTR:
0834         error = xfs_attr_node_remove_attr(attr);
0835         if (!error)
0836             error = xfs_attr_leaf_shrink(args);
0837         attr->xattri_dela_state = xfs_attr_complete_op(attr,
0838                         xfs_attr_init_add_state(args));
0839         break;
0840     default:
0841         ASSERT(0);
0842         break;
0843     }
0844 
0845     trace_xfs_attr_set_iter_return(attr->xattri_dela_state, args->dp);
0846     return error;
0847 }
0848 
0849 
0850 /*
0851  * Return EEXIST if attr is found, or ENOATTR if not
0852  */
0853 static int
0854 xfs_attr_lookup(
0855     struct xfs_da_args  *args)
0856 {
0857     struct xfs_inode    *dp = args->dp;
0858     struct xfs_buf      *bp = NULL;
0859     struct xfs_da_state *state;
0860     int         error;
0861 
0862     if (!xfs_inode_hasattr(dp))
0863         return -ENOATTR;
0864 
0865     if (dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
0866         return xfs_attr_sf_findname(args, NULL, NULL);
0867 
0868     if (xfs_attr_is_leaf(dp)) {
0869         error = xfs_attr_leaf_hasname(args, &bp);
0870 
0871         if (bp)
0872             xfs_trans_brelse(args->trans, bp);
0873 
0874         return error;
0875     }
0876 
0877     state = xfs_da_state_alloc(args);
0878     error = xfs_attr_node_lookup(args, state);
0879     xfs_da_state_free(state);
0880     return error;
0881 }
0882 
0883 static int
0884 xfs_attr_intent_init(
0885     struct xfs_da_args  *args,
0886     unsigned int        op_flags,   /* op flag (set or remove) */
0887     struct xfs_attr_intent  **attr)     /* new xfs_attr_intent */
0888 {
0889 
0890     struct xfs_attr_intent  *new;
0891 
0892     new = kmem_cache_zalloc(xfs_attr_intent_cache, GFP_NOFS | __GFP_NOFAIL);
0893     new->xattri_op_flags = op_flags;
0894     new->xattri_da_args = args;
0895 
0896     *attr = new;
0897     return 0;
0898 }
0899 
0900 /* Sets an attribute for an inode as a deferred operation */
0901 static int
0902 xfs_attr_defer_add(
0903     struct xfs_da_args  *args)
0904 {
0905     struct xfs_attr_intent  *new;
0906     int         error = 0;
0907 
0908     error = xfs_attr_intent_init(args, XFS_ATTRI_OP_FLAGS_SET, &new);
0909     if (error)
0910         return error;
0911 
0912     new->xattri_dela_state = xfs_attr_init_add_state(args);
0913     xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
0914     trace_xfs_attr_defer_add(new->xattri_dela_state, args->dp);
0915 
0916     return 0;
0917 }
0918 
0919 /* Sets an attribute for an inode as a deferred operation */
0920 static int
0921 xfs_attr_defer_replace(
0922     struct xfs_da_args  *args)
0923 {
0924     struct xfs_attr_intent  *new;
0925     int         error = 0;
0926 
0927     error = xfs_attr_intent_init(args, XFS_ATTRI_OP_FLAGS_REPLACE, &new);
0928     if (error)
0929         return error;
0930 
0931     new->xattri_dela_state = xfs_attr_init_replace_state(args);
0932     xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
0933     trace_xfs_attr_defer_replace(new->xattri_dela_state, args->dp);
0934 
0935     return 0;
0936 }
0937 
0938 /* Removes an attribute for an inode as a deferred operation */
0939 static int
0940 xfs_attr_defer_remove(
0941     struct xfs_da_args  *args)
0942 {
0943 
0944     struct xfs_attr_intent  *new;
0945     int         error;
0946 
0947     error  = xfs_attr_intent_init(args, XFS_ATTRI_OP_FLAGS_REMOVE, &new);
0948     if (error)
0949         return error;
0950 
0951     new->xattri_dela_state = xfs_attr_init_remove_state(args);
0952     xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
0953     trace_xfs_attr_defer_remove(new->xattri_dela_state, args->dp);
0954 
0955     return 0;
0956 }
0957 
0958 /*
0959  * Note: If args->value is NULL the attribute will be removed, just like the
0960  * Linux ->setattr API.
0961  */
0962 int
0963 xfs_attr_set(
0964     struct xfs_da_args  *args)
0965 {
0966     struct xfs_inode    *dp = args->dp;
0967     struct xfs_mount    *mp = dp->i_mount;
0968     struct xfs_trans_res    tres;
0969     bool            rsvd = (args->attr_filter & XFS_ATTR_ROOT);
0970     int         error, local;
0971     int         rmt_blks = 0;
0972     unsigned int        total;
0973 
0974     if (xfs_is_shutdown(dp->i_mount))
0975         return -EIO;
0976 
0977     error = xfs_qm_dqattach(dp);
0978     if (error)
0979         return error;
0980 
0981     args->geo = mp->m_attr_geo;
0982     args->whichfork = XFS_ATTR_FORK;
0983     args->hashval = xfs_da_hashname(args->name, args->namelen);
0984 
0985     /*
0986      * We have no control over the attribute names that userspace passes us
0987      * to remove, so we have to allow the name lookup prior to attribute
0988      * removal to fail as well.  Preserve the logged flag, since we need
0989      * to pass that through to the logging code.
0990      */
0991     args->op_flags = XFS_DA_OP_OKNOENT |
0992                     (args->op_flags & XFS_DA_OP_LOGGED);
0993 
0994     if (args->value) {
0995         XFS_STATS_INC(mp, xs_attr_set);
0996         args->total = xfs_attr_calc_size(args, &local);
0997 
0998         /*
0999          * If the inode doesn't have an attribute fork, add one.
1000          * (inode must not be locked when we call this routine)
1001          */
1002         if (xfs_inode_has_attr_fork(dp) == 0) {
1003             int sf_size = sizeof(struct xfs_attr_sf_hdr) +
1004                 xfs_attr_sf_entsize_byname(args->namelen,
1005                         args->valuelen);
1006 
1007             error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
1008             if (error)
1009                 return error;
1010         }
1011 
1012         if (!local)
1013             rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
1014     } else {
1015         XFS_STATS_INC(mp, xs_attr_remove);
1016         rmt_blks = xfs_attr3_rmt_blocks(mp, XFS_XATTR_SIZE_MAX);
1017     }
1018 
1019     /*
1020      * Root fork attributes can use reserved data blocks for this
1021      * operation if necessary
1022      */
1023     xfs_init_attr_trans(args, &tres, &total);
1024     error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
1025     if (error)
1026         return error;
1027 
1028     if (args->value || xfs_inode_hasattr(dp)) {
1029         error = xfs_iext_count_may_overflow(dp, XFS_ATTR_FORK,
1030                 XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
1031         if (error == -EFBIG)
1032             error = xfs_iext_count_upgrade(args->trans, dp,
1033                     XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
1034         if (error)
1035             goto out_trans_cancel;
1036     }
1037 
1038     error = xfs_attr_lookup(args);
1039     switch (error) {
1040     case -EEXIST:
1041         /* if no value, we are performing a remove operation */
1042         if (!args->value) {
1043             error = xfs_attr_defer_remove(args);
1044             break;
1045         }
1046         /* Pure create fails if the attr already exists */
1047         if (args->attr_flags & XATTR_CREATE)
1048             goto out_trans_cancel;
1049 
1050         error = xfs_attr_defer_replace(args);
1051         break;
1052     case -ENOATTR:
1053         /* Can't remove what isn't there. */
1054         if (!args->value)
1055             goto out_trans_cancel;
1056 
1057         /* Pure replace fails if no existing attr to replace. */
1058         if (args->attr_flags & XATTR_REPLACE)
1059             goto out_trans_cancel;
1060 
1061         error = xfs_attr_defer_add(args);
1062         break;
1063     default:
1064         goto out_trans_cancel;
1065     }
1066     if (error)
1067         goto out_trans_cancel;
1068 
1069     /*
1070      * If this is a synchronous mount, make sure that the
1071      * transaction goes to disk before returning to the user.
1072      */
1073     if (xfs_has_wsync(mp))
1074         xfs_trans_set_sync(args->trans);
1075 
1076     if (!(args->op_flags & XFS_DA_OP_NOTIME))
1077         xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
1078 
1079     /*
1080      * Commit the last in the sequence of transactions.
1081      */
1082     xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
1083     error = xfs_trans_commit(args->trans);
1084 out_unlock:
1085     xfs_iunlock(dp, XFS_ILOCK_EXCL);
1086     return error;
1087 
1088 out_trans_cancel:
1089     if (args->trans)
1090         xfs_trans_cancel(args->trans);
1091     goto out_unlock;
1092 }
1093 
1094 /*========================================================================
1095  * External routines when attribute list is inside the inode
1096  *========================================================================*/
1097 
1098 static inline int xfs_attr_sf_totsize(struct xfs_inode *dp)
1099 {
1100     struct xfs_attr_shortform *sf;
1101 
1102     sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data;
1103     return be16_to_cpu(sf->hdr.totsize);
1104 }
1105 
1106 /*
1107  * Add a name to the shortform attribute list structure
1108  * This is the external routine.
1109  */
1110 static int
1111 xfs_attr_shortform_addname(
1112     struct xfs_da_args  *args)
1113 {
1114     int         newsize, forkoff;
1115     int         error;
1116 
1117     trace_xfs_attr_sf_addname(args);
1118 
1119     error = xfs_attr_shortform_lookup(args);
1120     switch (error) {
1121     case -ENOATTR:
1122         if (args->op_flags & XFS_DA_OP_REPLACE)
1123             return error;
1124         break;
1125     case -EEXIST:
1126         if (!(args->op_flags & XFS_DA_OP_REPLACE))
1127             return error;
1128 
1129         error = xfs_attr_sf_removename(args);
1130         if (error)
1131             return error;
1132 
1133         /*
1134          * Since we have removed the old attr, clear XFS_DA_OP_REPLACE
1135          * so that the new attr doesn't fit in shortform format, the
1136          * leaf format add routine won't trip over the attr not being
1137          * around.
1138          */
1139         args->op_flags &= ~XFS_DA_OP_REPLACE;
1140         break;
1141     case 0:
1142         break;
1143     default:
1144         return error;
1145     }
1146 
1147     if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
1148         args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
1149         return -ENOSPC;
1150 
1151     newsize = xfs_attr_sf_totsize(args->dp);
1152     newsize += xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
1153 
1154     forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
1155     if (!forkoff)
1156         return -ENOSPC;
1157 
1158     xfs_attr_shortform_add(args, forkoff);
1159     return 0;
1160 }
1161 
1162 
1163 /*========================================================================
1164  * External routines when attribute list is one block
1165  *========================================================================*/
1166 
1167 /* Save the current remote block info and clear the current pointers. */
1168 static void
1169 xfs_attr_save_rmt_blk(
1170     struct xfs_da_args  *args)
1171 {
1172     args->blkno2 = args->blkno;
1173     args->index2 = args->index;
1174     args->rmtblkno2 = args->rmtblkno;
1175     args->rmtblkcnt2 = args->rmtblkcnt;
1176     args->rmtvaluelen2 = args->rmtvaluelen;
1177     args->rmtblkno = 0;
1178     args->rmtblkcnt = 0;
1179     args->rmtvaluelen = 0;
1180 }
1181 
1182 /* Set stored info about a remote block */
1183 static void
1184 xfs_attr_restore_rmt_blk(
1185     struct xfs_da_args  *args)
1186 {
1187     args->blkno = args->blkno2;
1188     args->index = args->index2;
1189     args->rmtblkno = args->rmtblkno2;
1190     args->rmtblkcnt = args->rmtblkcnt2;
1191     args->rmtvaluelen = args->rmtvaluelen2;
1192 }
1193 
1194 /*
1195  * Tries to add an attribute to an inode in leaf form
1196  *
1197  * This function is meant to execute as part of a delayed operation and leaves
1198  * the transaction handling to the caller.  On success the attribute is added
1199  * and the inode and transaction are left dirty.  If there is not enough space,
1200  * the attr data is converted to node format and -ENOSPC is returned. Caller is
1201  * responsible for handling the dirty inode and transaction or adding the attr
1202  * in node format.
1203  */
1204 STATIC int
1205 xfs_attr_leaf_try_add(
1206     struct xfs_da_args  *args)
1207 {
1208     struct xfs_buf      *bp;
1209     int         error;
1210 
1211     error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp);
1212     if (error)
1213         return error;
1214 
1215     /*
1216      * Look up the xattr name to set the insertion point for the new xattr.
1217      */
1218     error = xfs_attr3_leaf_lookup_int(bp, args);
1219     switch (error) {
1220     case -ENOATTR:
1221         if (args->op_flags & XFS_DA_OP_REPLACE)
1222             goto out_brelse;
1223         break;
1224     case -EEXIST:
1225         if (!(args->op_flags & XFS_DA_OP_REPLACE))
1226             goto out_brelse;
1227 
1228         trace_xfs_attr_leaf_replace(args);
1229         /*
1230          * Save the existing remote attr state so that the current
1231          * values reflect the state of the new attribute we are about to
1232          * add, not the attribute we just found and will remove later.
1233          */
1234         xfs_attr_save_rmt_blk(args);
1235         break;
1236     case 0:
1237         break;
1238     default:
1239         goto out_brelse;
1240     }
1241 
1242     return xfs_attr3_leaf_add(bp, args);
1243 
1244 out_brelse:
1245     xfs_trans_brelse(args->trans, bp);
1246     return error;
1247 }
1248 
1249 /*
1250  * Return EEXIST if attr is found, or ENOATTR if not
1251  */
1252 STATIC int
1253 xfs_attr_leaf_hasname(
1254     struct xfs_da_args  *args,
1255     struct xfs_buf      **bp)
1256 {
1257     int                     error = 0;
1258 
1259     error = xfs_attr3_leaf_read(args->trans, args->dp, 0, bp);
1260     if (error)
1261         return error;
1262 
1263     error = xfs_attr3_leaf_lookup_int(*bp, args);
1264     if (error != -ENOATTR && error != -EEXIST)
1265         xfs_trans_brelse(args->trans, *bp);
1266 
1267     return error;
1268 }
1269 
1270 /*
1271  * Remove a name from the leaf attribute list structure
1272  *
1273  * This leaf block cannot have a "remote" value, we only call this routine
1274  * if bmap_one_block() says there is only one block (ie: no remote blks).
1275  */
1276 STATIC int
1277 xfs_attr_leaf_removename(
1278     struct xfs_da_args  *args)
1279 {
1280     struct xfs_inode    *dp;
1281     struct xfs_buf      *bp;
1282     int         error, forkoff;
1283 
1284     trace_xfs_attr_leaf_removename(args);
1285 
1286     /*
1287      * Remove the attribute.
1288      */
1289     dp = args->dp;
1290 
1291     error = xfs_attr_leaf_hasname(args, &bp);
1292     if (error == -ENOATTR) {
1293         xfs_trans_brelse(args->trans, bp);
1294         if (args->op_flags & XFS_DA_OP_RECOVERY)
1295             return 0;
1296         return error;
1297     } else if (error != -EEXIST)
1298         return error;
1299 
1300     xfs_attr3_leaf_remove(bp, args);
1301 
1302     /*
1303      * If the result is small enough, shrink it all into the inode.
1304      */
1305     forkoff = xfs_attr_shortform_allfit(bp, dp);
1306     if (forkoff)
1307         return xfs_attr3_leaf_to_shortform(bp, args, forkoff);
1308         /* bp is gone due to xfs_da_shrink_inode */
1309 
1310     return 0;
1311 }
1312 
1313 /*
1314  * Look up a name in a leaf attribute list structure.
1315  *
1316  * This leaf block cannot have a "remote" value, we only call this routine
1317  * if bmap_one_block() says there is only one block (ie: no remote blks).
1318  *
1319  * Returns 0 on successful retrieval, otherwise an error.
1320  */
1321 STATIC int
1322 xfs_attr_leaf_get(xfs_da_args_t *args)
1323 {
1324     struct xfs_buf *bp;
1325     int error;
1326 
1327     trace_xfs_attr_leaf_get(args);
1328 
1329     error = xfs_attr_leaf_hasname(args, &bp);
1330 
1331     if (error == -ENOATTR)  {
1332         xfs_trans_brelse(args->trans, bp);
1333         return error;
1334     } else if (error != -EEXIST)
1335         return error;
1336 
1337 
1338     error = xfs_attr3_leaf_getvalue(bp, args);
1339     xfs_trans_brelse(args->trans, bp);
1340     return error;
1341 }
1342 
1343 /* Return EEXIST if attr is found, or ENOATTR if not. */
1344 STATIC int
1345 xfs_attr_node_lookup(
1346     struct xfs_da_args  *args,
1347     struct xfs_da_state *state)
1348 {
1349     int         retval, error;
1350 
1351     /*
1352      * Search to see if name exists, and get back a pointer to it.
1353      */
1354     error = xfs_da3_node_lookup_int(state, &retval);
1355     if (error)
1356         return error;
1357 
1358     return retval;
1359 }
1360 
1361 /*========================================================================
1362  * External routines when attribute list size > geo->blksize
1363  *========================================================================*/
1364 
1365 STATIC int
1366 xfs_attr_node_addname_find_attr(
1367      struct xfs_attr_intent *attr)
1368 {
1369     struct xfs_da_args  *args = attr->xattri_da_args;
1370     int         error;
1371 
1372     /*
1373      * Search to see if name already exists, and get back a pointer
1374      * to where it should go.
1375      */
1376     xfs_attr_item_init_da_state(attr);
1377     error = xfs_attr_node_lookup(args, attr->xattri_da_state);
1378     switch (error) {
1379     case -ENOATTR:
1380         if (args->op_flags & XFS_DA_OP_REPLACE)
1381             goto error;
1382         break;
1383     case -EEXIST:
1384         if (!(args->op_flags & XFS_DA_OP_REPLACE))
1385             goto error;
1386 
1387 
1388         trace_xfs_attr_node_replace(args);
1389         /*
1390          * Save the existing remote attr state so that the current
1391          * values reflect the state of the new attribute we are about to
1392          * add, not the attribute we just found and will remove later.
1393          */
1394         xfs_attr_save_rmt_blk(args);
1395         break;
1396     case 0:
1397         break;
1398     default:
1399         goto error;
1400     }
1401 
1402     return 0;
1403 error:
1404     if (attr->xattri_da_state) {
1405         xfs_da_state_free(attr->xattri_da_state);
1406         attr->xattri_da_state = NULL;
1407     }
1408     return error;
1409 }
1410 
1411 /*
1412  * Add a name to a Btree-format attribute list.
1413  *
1414  * This will involve walking down the Btree, and may involve splitting
1415  * leaf nodes and even splitting intermediate nodes up to and including
1416  * the root node (a special case of an intermediate node).
1417  */
1418 static int
1419 xfs_attr_node_try_addname(
1420     struct xfs_attr_intent      *attr)
1421 {
1422     struct xfs_da_state     *state = attr->xattri_da_state;
1423     struct xfs_da_state_blk     *blk;
1424     int             error;
1425 
1426     trace_xfs_attr_node_addname(state->args);
1427 
1428     blk = &state->path.blk[state->path.active-1];
1429     ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1430 
1431     error = xfs_attr3_leaf_add(blk->bp, state->args);
1432     if (error == -ENOSPC) {
1433         if (state->path.active == 1) {
1434             /*
1435              * Its really a single leaf node, but it had
1436              * out-of-line values so it looked like it *might*
1437              * have been a b-tree. Let the caller deal with this.
1438              */
1439             goto out;
1440         }
1441 
1442         /*
1443          * Split as many Btree elements as required.
1444          * This code tracks the new and old attr's location
1445          * in the index/blkno/rmtblkno/rmtblkcnt fields and
1446          * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields.
1447          */
1448         error = xfs_da3_split(state);
1449         if (error)
1450             goto out;
1451     } else {
1452         /*
1453          * Addition succeeded, update Btree hashvals.
1454          */
1455         xfs_da3_fixhashpath(state, &state->path);
1456     }
1457 
1458 out:
1459     xfs_da_state_free(state);
1460     attr->xattri_da_state = NULL;
1461     return error;
1462 }
1463 
1464 static int
1465 xfs_attr_node_removename(
1466     struct xfs_da_args  *args,
1467     struct xfs_da_state *state)
1468 {
1469     struct xfs_da_state_blk *blk;
1470     int         retval;
1471 
1472     /*
1473      * Remove the name and update the hashvals in the tree.
1474      */
1475     blk = &state->path.blk[state->path.active-1];
1476     ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1477     retval = xfs_attr3_leaf_remove(blk->bp, args);
1478     xfs_da3_fixhashpath(state, &state->path);
1479 
1480     return retval;
1481 }
1482 
1483 static int
1484 xfs_attr_node_remove_attr(
1485     struct xfs_attr_intent      *attr)
1486 {
1487     struct xfs_da_args      *args = attr->xattri_da_args;
1488     struct xfs_da_state     *state = xfs_da_state_alloc(args);
1489     int             retval = 0;
1490     int             error = 0;
1491 
1492     /*
1493      * The attr we are removing has already been marked incomplete, so
1494      * we need to set the filter appropriately to re-find the "old"
1495      * attribute entry after any split ops.
1496      */
1497     args->attr_filter |= XFS_ATTR_INCOMPLETE;
1498     error = xfs_da3_node_lookup_int(state, &retval);
1499     if (error)
1500         goto out;
1501 
1502     error = xfs_attr_node_removename(args, state);
1503 
1504     /*
1505      * Check to see if the tree needs to be collapsed.
1506      */
1507     if (retval && (state->path.active > 1)) {
1508         error = xfs_da3_join(state);
1509         if (error)
1510             goto out;
1511     }
1512     retval = error = 0;
1513 
1514 out:
1515     xfs_da_state_free(state);
1516     if (error)
1517         return error;
1518     return retval;
1519 }
1520 
1521 /*
1522  * Retrieve the attribute data from a node attribute list.
1523  *
1524  * This routine gets called for any attribute fork that has more than one
1525  * block, ie: both true Btree attr lists and for single-leaf-blocks with
1526  * "remote" values taking up more blocks.
1527  *
1528  * Returns 0 on successful retrieval, otherwise an error.
1529  */
1530 STATIC int
1531 xfs_attr_node_get(
1532     struct xfs_da_args  *args)
1533 {
1534     struct xfs_da_state *state;
1535     struct xfs_da_state_blk *blk;
1536     int         i;
1537     int         error;
1538 
1539     trace_xfs_attr_node_get(args);
1540 
1541     /*
1542      * Search to see if name exists, and get back a pointer to it.
1543      */
1544     state = xfs_da_state_alloc(args);
1545     error = xfs_attr_node_lookup(args, state);
1546     if (error != -EEXIST)
1547         goto out_release;
1548 
1549     /*
1550      * Get the value, local or "remote"
1551      */
1552     blk = &state->path.blk[state->path.active - 1];
1553     error = xfs_attr3_leaf_getvalue(blk->bp, args);
1554 
1555     /*
1556      * If not in a transaction, we have to release all the buffers.
1557      */
1558 out_release:
1559     for (i = 0; i < state->path.active; i++) {
1560         xfs_trans_brelse(args->trans, state->path.blk[i].bp);
1561         state->path.blk[i].bp = NULL;
1562     }
1563 
1564     xfs_da_state_free(state);
1565     return error;
1566 }
1567 
1568 /* Returns true if the attribute entry name is valid. */
1569 bool
1570 xfs_attr_namecheck(
1571     const void  *name,
1572     size_t      length)
1573 {
1574     /*
1575      * MAXNAMELEN includes the trailing null, but (name/length) leave it
1576      * out, so use >= for the length check.
1577      */
1578     if (length >= MAXNAMELEN)
1579         return false;
1580 
1581     /* There shouldn't be any nulls here */
1582     return !memchr(name, 0, length);
1583 }
1584 
1585 int __init
1586 xfs_attr_intent_init_cache(void)
1587 {
1588     xfs_attr_intent_cache = kmem_cache_create("xfs_attr_intent",
1589             sizeof(struct xfs_attr_intent),
1590             0, 0, NULL);
1591 
1592     return xfs_attr_intent_cache != NULL ? 0 : -ENOMEM;
1593 }
1594 
1595 void
1596 xfs_attr_intent_destroy_cache(void)
1597 {
1598     kmem_cache_destroy(xfs_attr_intent_cache);
1599     xfs_attr_intent_cache = NULL;
1600 }