LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_attr.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsa @ Mon Jul 31 20:08:27 PDT 2023 Lines: 581 618 94.0 %
Date: 2023-07-31 20:08:27 Functions: 38 39 97.4 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
       4             :  * All Rights Reserved.
       5             :  */
       6             : #include "xfs.h"
       7             : #include "xfs_fs.h"
       8             : #include "xfs_shared.h"
       9             : #include "xfs_format.h"
      10             : #include "xfs_log_format.h"
      11             : #include "xfs_trans_resv.h"
      12             : #include "xfs_mount.h"
      13             : #include "xfs_defer.h"
      14             : #include "xfs_da_format.h"
      15             : #include "xfs_da_btree.h"
      16             : #include "xfs_attr_sf.h"
      17             : #include "xfs_inode.h"
      18             : #include "xfs_trans.h"
      19             : #include "xfs_bmap.h"
      20             : #include "xfs_bmap_btree.h"
      21             : #include "xfs_attr.h"
      22             : #include "xfs_attr_leaf.h"
      23             : #include "xfs_attr_remote.h"
      24             : #include "xfs_quota.h"
      25             : #include "xfs_trans_space.h"
      26             : #include "xfs_trace.h"
      27             : #include "xfs_attr_item.h"
      28             : #include "xfs_xattr.h"
      29             : #include "xfs_parent.h"
      30             : 
      31             : struct kmem_cache               *xfs_attr_intent_cache;
      32             : 
      33             : /*
      34             :  * xfs_attr.c
      35             :  *
      36             :  * Provide the external interfaces to manage attribute lists.
      37             :  */
      38             : 
      39             : /*========================================================================
      40             :  * Function prototypes for the kernel.
      41             :  *========================================================================*/
      42             : 
      43             : /*
      44             :  * Internal routines when attribute list fits inside the inode.
      45             :  */
      46             : STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
      47             : 
      48             : /*
      49             :  * Internal routines when attribute list is one block.
      50             :  */
      51             : STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
      52             : STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
      53             : STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp);
      54             : STATIC int xfs_attr_leaf_try_add(struct xfs_da_args *args);
      55             : 
      56             : /*
      57             :  * Internal routines when attribute list is more than one block.
      58             :  */
      59             : STATIC int xfs_attr_node_get(xfs_da_args_t *args);
      60             : STATIC void xfs_attr_restore_rmt_blk(struct xfs_da_args *args);
      61             : static int xfs_attr_node_try_addname(struct xfs_attr_intent *attr);
      62             : STATIC int xfs_attr_node_addname_find_attr(struct xfs_attr_intent *attr);
      63             : STATIC int xfs_attr_node_remove_attr(struct xfs_attr_intent *attr);
      64             : STATIC int xfs_attr_node_lookup(struct xfs_da_args *args,
      65             :                 struct xfs_da_state *state);
      66             : 
      67             : int
      68  2493987087 : xfs_inode_hasattr(
      69             :         struct xfs_inode        *ip)
      70             : {
      71  2600001478 :         if (!xfs_inode_has_attr_fork(ip))
      72             :                 return 0;
      73  3111160663 :         if (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
      74   472243862 :             ip->i_af.if_nextents == 0)
      75     1578834 :                 return 0;
      76             :         return 1;
      77             : }
      78             : 
      79             : /*
      80             :  * Returns true if the there is exactly only block in the attr fork, in which
      81             :  * case the attribute fork consists of a single leaf block entry.
      82             :  */
      83             : bool
      84   835119071 : xfs_attr_is_leaf(
      85             :         struct xfs_inode        *ip)
      86             : {
      87   835119071 :         struct xfs_ifork        *ifp = &ip->i_af;
      88   835119071 :         struct xfs_iext_cursor  icur;
      89   835119071 :         struct xfs_bmbt_irec    imap;
      90             : 
      91   835119071 :         if (ifp->if_nextents != 1 || ifp->if_format != XFS_DINODE_FMT_EXTENTS)
      92             :                 return false;
      93             : 
      94   818911489 :         xfs_iext_first(ifp, &icur);
      95   818839721 :         xfs_iext_get_extent(ifp, &icur, &imap);
      96   819201968 :         return imap.br_startoff == 0 && imap.br_blockcount == 1;
      97             : }
      98             : 
      99             : /*
     100             :  * XXX (dchinner): name path state saving and refilling is an optimisation to
     101             :  * avoid needing to look up name entries after rolling transactions removing
     102             :  * remote xattr blocks between the name entry lookup and name entry removal.
     103             :  * This optimisation got sidelined when combining the set and remove state
     104             :  * machines, but the code has been left in place because it is worthwhile to
     105             :  * restore the optimisation once the combined state machine paths have settled.
     106             :  *
     107             :  * This comment is a public service announcement to remind Future Dave that he
     108             :  * still needs to restore this code to working order.
     109             :  */
     110             : #if 0
     111             : /*
     112             :  * Fill in the disk block numbers in the state structure for the buffers
     113             :  * that are attached to the state structure.
     114             :  * This is done so that we can quickly reattach ourselves to those buffers
     115             :  * after some set of transaction commits have released these buffers.
     116             :  */
     117             : static int
     118             : xfs_attr_fillstate(xfs_da_state_t *state)
     119             : {
     120             :         xfs_da_state_path_t *path;
     121             :         xfs_da_state_blk_t *blk;
     122             :         int level;
     123             : 
     124             :         trace_xfs_attr_fillstate(state->args);
     125             : 
     126             :         /*
     127             :          * Roll down the "path" in the state structure, storing the on-disk
     128             :          * block number for those buffers in the "path".
     129             :          */
     130             :         path = &state->path;
     131             :         ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
     132             :         for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
     133             :                 if (blk->bp) {
     134             :                         blk->disk_blkno = xfs_buf_daddr(blk->bp);
     135             :                         blk->bp = NULL;
     136             :                 } else {
     137             :                         blk->disk_blkno = 0;
     138             :                 }
     139             :         }
     140             : 
     141             :         /*
     142             :          * Roll down the "altpath" in the state structure, storing the on-disk
     143             :          * block number for those buffers in the "altpath".
     144             :          */
     145             :         path = &state->altpath;
     146             :         ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
     147             :         for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
     148             :                 if (blk->bp) {
     149             :                         blk->disk_blkno = xfs_buf_daddr(blk->bp);
     150             :                         blk->bp = NULL;
     151             :                 } else {
     152             :                         blk->disk_blkno = 0;
     153             :                 }
     154             :         }
     155             : 
     156             :         return 0;
     157             : }
     158             : 
     159             : /*
     160             :  * Reattach the buffers to the state structure based on the disk block
     161             :  * numbers stored in the state structure.
     162             :  * This is done after some set of transaction commits have released those
     163             :  * buffers from our grip.
     164             :  */
     165             : static int
     166             : xfs_attr_refillstate(xfs_da_state_t *state)
     167             : {
     168             :         xfs_da_state_path_t *path;
     169             :         xfs_da_state_blk_t *blk;
     170             :         int level, error;
     171             : 
     172             :         trace_xfs_attr_refillstate(state->args);
     173             : 
     174             :         /*
     175             :          * Roll down the "path" in the state structure, storing the on-disk
     176             :          * block number for those buffers in the "path".
     177             :          */
     178             :         path = &state->path;
     179             :         ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
     180             :         for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
     181             :                 if (blk->disk_blkno) {
     182             :                         error = xfs_da3_node_read_mapped(state->args->trans,
     183             :                                         state->args->dp, blk->disk_blkno,
     184             :                                         &blk->bp, XFS_ATTR_FORK);
     185             :                         if (error)
     186             :                                 return error;
     187             :                 } else {
     188             :                         blk->bp = NULL;
     189             :                 }
     190             :         }
     191             : 
     192             :         /*
     193             :          * Roll down the "altpath" in the state structure, storing the on-disk
     194             :          * block number for those buffers in the "altpath".
     195             :          */
     196             :         path = &state->altpath;
     197             :         ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
     198             :         for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
     199             :                 if (blk->disk_blkno) {
     200             :                         error = xfs_da3_node_read_mapped(state->args->trans,
     201             :                                         state->args->dp, blk->disk_blkno,
     202             :                                         &blk->bp, XFS_ATTR_FORK);
     203             :                         if (error)
     204             :                                 return error;
     205             :                 } else {
     206             :                         blk->bp = NULL;
     207             :                 }
     208             :         }
     209             : 
     210             :         return 0;
     211             : }
     212             : #else
     213             : static int xfs_attr_fillstate(xfs_da_state_t *state) { return 0; }
     214             : #endif
     215             : 
     216             : /*========================================================================
     217             :  * Overall external interface routines.
     218             :  *========================================================================*/
     219             : 
     220             : /*
     221             :  * Retrieve an extended attribute and its value.  Must have ilock.
     222             :  * Returns 0 on successful retrieval, otherwise an error.
     223             :  */
     224             : int
     225   171159780 : xfs_attr_get_ilocked(
     226             :         struct xfs_da_args      *args)
     227             : {
     228   171159780 :         ASSERT(xfs_isilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
     229             : 
     230   171158353 :         if (!xfs_inode_hasattr(args->dp))
     231             :                 return -ENOATTR;
     232             : 
     233   171145448 :         if (args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
     234   137807984 :                 return xfs_attr_shortform_getvalue(args);
     235    33337464 :         if (xfs_attr_is_leaf(args->dp))
     236    32550306 :                 return xfs_attr_leaf_get(args);
     237      786807 :         return xfs_attr_node_get(args);
     238             : }
     239             : 
     240             : /*
     241             :  * Retrieve an extended attribute by name, and its value if requested.
     242             :  *
     243             :  * If args->valuelen is zero, then the caller does not want the value, just an
     244             :  * indication whether the attribute exists and the size of the value if it
     245             :  * exists. The size is returned in args.valuelen.
     246             :  *
     247             :  * If args->value is NULL but args->valuelen is non-zero, allocate the buffer
     248             :  * for the value after existence of the attribute has been determined. The
     249             :  * caller always has to free args->value if it is set, no matter if this
     250             :  * function was successful or not.
     251             :  *
     252             :  * If the attribute is found, but exceeds the size limit set by the caller in
     253             :  * args->valuelen, return -ERANGE with the size of the attribute that was found
     254             :  * in args->valuelen.
     255             :  */
     256             : int
     257    74647962 : xfs_attr_get(
     258             :         struct xfs_da_args      *args)
     259             : {
     260    74647962 :         uint                    lock_mode;
     261    74647962 :         int                     error;
     262             : 
     263    74647962 :         XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
     264             : 
     265   149295924 :         if (xfs_is_shutdown(args->dp->i_mount))
     266             :                 return -EIO;
     267             : 
     268    74646986 :         args->geo = args->dp->i_mount->m_attr_geo;
     269    74646986 :         args->whichfork = XFS_ATTR_FORK;
     270    74646986 :         args->hashval = xfs_da_hashname(args->name, args->namelen);
     271             : 
     272             :         /* Entirely possible to look up a name which doesn't exist */
     273    74646022 :         args->op_flags = XFS_DA_OP_OKNOENT;
     274             : 
     275    74646022 :         lock_mode = xfs_ilock_attr_map_shared(args->dp);
     276    74646554 :         error = xfs_attr_get_ilocked(args);
     277    74645174 :         xfs_iunlock(args->dp, lock_mode);
     278             : 
     279    74645174 :         return error;
     280             : }
     281             : 
     282             : /*
     283             :  * Calculate how many blocks we need for the new attribute,
     284             :  */
     285             : int
     286   234730861 : xfs_attr_calc_size(
     287             :         struct xfs_da_args      *args,
     288             :         int                     *local)
     289             : {
     290   234730861 :         struct xfs_mount        *mp = args->dp->i_mount;
     291   234730861 :         int                     size;
     292   234730861 :         int                     nblks;
     293             : 
     294             :         /*
     295             :          * Determine space new attribute will use, and if it would be
     296             :          * "local" or "remote" (note: local != inline).
     297             :          */
     298   234730861 :         size = xfs_attr_leaf_newentsize(args, local);
     299   234733150 :         nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
     300   234733150 :         if (*local) {
     301   234732435 :                 if (size > (args->geo->blksize / 2)) {
     302             :                         /* Double split possible */
     303           2 :                         nblks *= 2;
     304             :                 }
     305             :         } else {
     306             :                 /*
     307             :                  * Out of line attribute, cannot double split, but
     308             :                  * make room for the attribute value itself.
     309             :                  */
     310         715 :                 uint    dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
     311         715 :                 nblks += dblocks;
     312         715 :                 nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
     313             :         }
     314             : 
     315   234733150 :         return nblks;
     316             : }
     317             : 
     318             : /* Initialize transaction reservation for attr operations */
     319             : void
     320   340765465 : xfs_init_attr_trans(
     321             :         struct xfs_da_args      *args,
     322             :         struct xfs_trans_res    *tres,
     323             :         unsigned int            *total)
     324             : {
     325   340765465 :         struct xfs_mount        *mp = args->dp->i_mount;
     326             : 
     327   340765465 :         if (args->value) {
     328   234732215 :                 tres->tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
     329   234732215 :                                  M_RES(mp)->tr_attrsetrt.tr_logres *
     330   234732215 :                                  args->total;
     331   234732215 :                 tres->tr_logcount = XFS_ATTRSET_LOG_COUNT;
     332   234732215 :                 tres->tr_logflags = XFS_TRANS_PERM_LOG_RES;
     333   234732215 :                 *total = args->total;
     334             :         } else {
     335   106033250 :                 *tres = M_RES(mp)->tr_attrrm;
     336   106033250 :                 *total = XFS_ATTRRM_SPACE_RES(mp);
     337             :         }
     338   340765465 : }
     339             : 
     340             : /*
     341             :  * Add an attr to a shortform fork. If there is no space,
     342             :  * xfs_attr_shortform_addname() will convert to leaf format and return -ENOSPC.
     343             :  * to use.
     344             :  */
     345             : STATIC int
     346   164734836 : xfs_attr_try_sf_addname(
     347             :         struct xfs_inode        *dp,
     348             :         struct xfs_da_args      *args)
     349             : {
     350             : 
     351   164734836 :         int                     error;
     352             : 
     353             :         /*
     354             :          * Build initial attribute list (if required).
     355             :          */
     356   164734836 :         if (dp->i_af.if_format == XFS_DINODE_FMT_EXTENTS)
     357    62964995 :                 xfs_attr_shortform_create(args);
     358             : 
     359   164734862 :         error = xfs_attr_shortform_addname(args);
     360   164739093 :         if (error == -ENOSPC)
     361             :                 return error;
     362             : 
     363             :         /*
     364             :          * Commit the shortform mods, and we're done.
     365             :          * NOTE: this is also the error path (EEXIST, etc).
     366             :          */
     367   156152300 :         if (!error && !(args->op_flags & XFS_DA_OP_NOTIME))
     368   156152087 :                 xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
     369             : 
     370   156153873 :         if (xfs_has_wsync(dp->i_mount))
     371         270 :                 xfs_trans_set_sync(args->trans);
     372             : 
     373             :         return error;
     374             : }
     375             : 
     376             : static int
     377   164738106 : xfs_attr_sf_addname(
     378             :         struct xfs_attr_intent          *attr)
     379             : {
     380   164738106 :         struct xfs_da_args              *args = attr->xattri_da_args;
     381   164738106 :         struct xfs_inode                *dp = args->dp;
     382   164738106 :         int                             error = 0;
     383             : 
     384   164738106 :         error = xfs_attr_try_sf_addname(dp, args);
     385   164734376 :         if (error != -ENOSPC) {
     386   156147560 :                 ASSERT(!error || error == -EEXIST);
     387   156147560 :                 attr->xattri_dela_state = XFS_DAS_DONE;
     388   156147560 :                 goto out;
     389             :         }
     390             : 
     391             :         /*
     392             :          * It won't fit in the shortform, transform to a leaf block.  GROT:
     393             :          * another possible req'mt for a double-split btree op.
     394             :          */
     395     8586816 :         error = xfs_attr_shortform_to_leaf(args);
     396     8586720 :         if (error)
     397             :                 return error;
     398             : 
     399     8586717 :         attr->xattri_dela_state = XFS_DAS_LEAF_ADD;
     400   164734277 : out:
     401   164734277 :         trace_xfs_attr_sf_addname_return(attr->xattri_dela_state, args->dp);
     402   164734277 :         return error;
     403             : }
     404             : 
     405             : /*
     406             :  * Handle the state change on completion of a multi-state attr operation.
     407             :  *
     408             :  * If the XFS_DA_OP_REPLACE flag is set, this means the operation was the first
     409             :  * modification in a attr replace operation and we still have to do the second
     410             :  * state, indicated by @replace_state.
     411             :  *
     412             :  * We consume the XFS_DA_OP_REPLACE flag so that when we are called again on
     413             :  * completion of the second half of the attr replace operation we correctly
     414             :  * signal that it is done.
     415             :  */
     416             : static enum xfs_delattr_state
     417   341036528 : xfs_attr_complete_op(
     418             :         struct xfs_attr_intent  *attr,
     419             :         enum xfs_delattr_state  replace_state)
     420             : {
     421   341036528 :         struct xfs_da_args      *args = attr->xattri_da_args;
     422   341036528 :         bool                    do_replace = args->op_flags & XFS_DA_OP_REPLACE;
     423             : 
     424   341036528 :         args->op_flags &= ~XFS_DA_OP_REPLACE;
     425   341036528 :         if (!do_replace)
     426             :                 return XFS_DAS_DONE;
     427             : 
     428    76772159 :         args->attr_filter &= ~XFS_ATTR_INCOMPLETE;
     429    76772159 :         if (xfs_attr_intent_op(attr) != XFS_ATTRI_OP_FLAGS_NVREPLACE)
     430             :                 return replace_state;
     431             : 
     432             :         /*
     433             :          * NVREPLACE operations require the caller to set the old and new names
     434             :          * and values explicitly.
     435             :          */
     436    39781127 :         ASSERT(args->new_namelen > 0);
     437             : 
     438    39781127 :         args->name = args->new_name;
     439    39781127 :         args->namelen = args->new_namelen;
     440    39781127 :         args->hashval = xfs_da_hashname(args->name, args->namelen);
     441    39781129 :         args->value = args->new_value;
     442    39781129 :         args->valuelen = args->new_valuelen;
     443    39781129 :         return replace_state;
     444             : }
     445             : 
     446             : static int
     447   151840453 : xfs_attr_leaf_addname(
     448             :         struct xfs_attr_intent  *attr)
     449             : {
     450   151840453 :         struct xfs_da_args      *args = attr->xattri_da_args;
     451   151840453 :         int                     error;
     452             : 
     453   151840453 :         ASSERT(xfs_attr_is_leaf(args->dp));
     454             : 
     455             :         /*
     456             :          * Use the leaf buffer we may already hold locked as a result of
     457             :          * a sf-to-leaf conversion.
     458             :          */
     459   151844860 :         error = xfs_attr_leaf_try_add(args);
     460             : 
     461   151842369 :         if (error == -ENOSPC) {
     462       80091 :                 error = xfs_attr3_leaf_to_node(args);
     463       80091 :                 if (error)
     464             :                         return error;
     465             : 
     466             :                 /*
     467             :                  * We're not in leaf format anymore, so roll the transaction and
     468             :                  * retry the add to the newly allocated node block.
     469             :                  */
     470       80089 :                 attr->xattri_dela_state = XFS_DAS_NODE_ADD;
     471       80089 :                 goto out;
     472             :         }
     473   151762278 :         if (error)
     474             :                 return error;
     475             : 
     476             :         /*
     477             :          * We need to commit and roll if we need to allocate remote xattr blocks
     478             :          * or perform more xattr manipulations. Otherwise there is nothing more
     479             :          * to do and we can return success.
     480             :          */
     481   151762278 :         if (args->rmtblkno)
     482         581 :                 attr->xattri_dela_state = XFS_DAS_LEAF_SET_RMT;
     483             :         else
     484   151761697 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     485             :                                                         XFS_DAS_LEAF_REPLACE);
     486   151851075 : out:
     487   151851075 :         trace_xfs_attr_leaf_addname_return(attr->xattri_dela_state, args->dp);
     488   151851075 :         return error;
     489             : }
     490             : 
     491             : /*
     492             :  * Add an entry to a node format attr tree.
     493             :  *
     494             :  * Note that we might still have a leaf here - xfs_attr_is_leaf() cannot tell
     495             :  * the difference between leaf + remote attr blocks and a node format tree,
     496             :  * so we may still end up having to convert from leaf to node format here.
     497             :  */
     498             : static int
     499     3219837 : xfs_attr_node_addname(
     500             :         struct xfs_attr_intent  *attr)
     501             : {
     502     3219837 :         struct xfs_da_args      *args = attr->xattri_da_args;
     503     3219837 :         int                     error;
     504             : 
     505     3219837 :         error = xfs_attr_node_addname_find_attr(attr);
     506     3219852 :         if (error)
     507             :                 return error;
     508             : 
     509     3219835 :         error = xfs_attr_node_try_addname(attr);
     510     3219848 :         if (error == -ENOSPC) {
     511           0 :                 error = xfs_attr3_leaf_to_node(args);
     512           0 :                 if (error)
     513             :                         return error;
     514             :                 /*
     515             :                  * No state change, we really are in node form now
     516             :                  * but we need the transaction rolled to continue.
     517             :                  */
     518           0 :                 goto out;
     519             :         }
     520     3219848 :         if (error)
     521             :                 return error;
     522             : 
     523     3219846 :         if (args->rmtblkno)
     524           4 :                 attr->xattri_dela_state = XFS_DAS_NODE_SET_RMT;
     525             :         else
     526     3219842 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     527             :                                                         XFS_DAS_NODE_REPLACE);
     528     3219845 : out:
     529     3219845 :         trace_xfs_attr_node_addname_return(attr->xattri_dela_state, args->dp);
     530     3219845 :         return error;
     531             : }
     532             : 
     533             : static int
     534         585 : xfs_attr_rmtval_alloc(
     535             :         struct xfs_attr_intent          *attr)
     536             : {
     537         585 :         struct xfs_da_args              *args = attr->xattri_da_args;
     538         585 :         int                             error = 0;
     539             : 
     540             :         /*
     541             :          * If there was an out-of-line value, allocate the blocks we
     542             :          * identified for its storage and copy the value.  This is done
     543             :          * after we create the attribute so that we don't overflow the
     544             :          * maximum size of a transaction and/or hit a deadlock.
     545             :          */
     546         585 :         if (attr->xattri_blkcnt > 0) {
     547         585 :                 error = xfs_attr_rmtval_set_blk(attr);
     548         585 :                 if (error)
     549             :                         return error;
     550             :                 /* Roll the transaction only if there is more to allocate. */
     551         585 :                 if (attr->xattri_blkcnt > 0)
     552           0 :                         goto out;
     553             :         }
     554             : 
     555         585 :         error = xfs_attr_rmtval_set_value(args);
     556         585 :         if (error)
     557             :                 return error;
     558             : 
     559        1170 :         attr->xattri_dela_state = xfs_attr_complete_op(attr,
     560         585 :                                                 ++attr->xattri_dela_state);
     561             :         /*
     562             :          * If we are not doing a rename, we've finished the operation but still
     563             :          * have to clear the incomplete flag protecting the new attr from
     564             :          * exposing partially initialised state if we crash during creation.
     565             :          */
     566         585 :         if (attr->xattri_dela_state == XFS_DAS_DONE)
     567         583 :                 error = xfs_attr3_leaf_clearflag(args);
     568           2 : out:
     569         585 :         trace_xfs_attr_rmtval_alloc(attr->xattri_dela_state, args->dp);
     570         585 :         return error;
     571             : }
     572             : 
     573             : /*
     574             :  * Mark an attribute entry INCOMPLETE and save pointers to the relevant buffers
     575             :  * for later deletion of the entry.
     576             :  */
     577             : static int
     578             : xfs_attr_leaf_mark_incomplete(
     579             :         struct xfs_da_args      *args,
     580             :         struct xfs_da_state     *state)
     581             : {
     582     1283333 :         int                     error;
     583             : 
     584             :         /*
     585             :          * Fill in disk block numbers in the state structure
     586             :          * so that we can get the buffers back after we commit
     587             :          * several transactions in the following calls.
     588             :          */
     589     1283333 :         error = xfs_attr_fillstate(state);
     590     1283333 :         if (error)
     591             :                 return error;
     592             : 
     593             :         /*
     594             :          * Mark the attribute as INCOMPLETE
     595             :          */
     596     1283333 :         return xfs_attr3_leaf_setflag(args);
     597             : }
     598             : 
     599             : /* Ensure the da state of an xattr deferred work item is ready to go. */
     600             : static inline void
     601     4503173 : xfs_attr_item_init_da_state(
     602             :         struct xfs_attr_intent  *attr)
     603             : {
     604     4503173 :         struct xfs_da_args      *args = attr->xattri_da_args;
     605             : 
     606     4503173 :         if (!attr->xattri_da_state)
     607     4493711 :                 attr->xattri_da_state = xfs_da_state_alloc(args);
     608             :         else
     609        9462 :                 xfs_da_state_reset(attr->xattri_da_state, args);
     610     4503172 : }
     611             : 
     612             : /*
     613             :  * Initial setup for xfs_attr_node_removename.  Make sure the attr is there and
     614             :  * the blocks are valid.  Attr keys with remote blocks will be marked
     615             :  * incomplete.
     616             :  */
     617             : static
     618     1283333 : int xfs_attr_node_removename_setup(
     619             :         struct xfs_attr_intent          *attr)
     620             : {
     621     1283333 :         struct xfs_da_args              *args = attr->xattri_da_args;
     622     1283333 :         struct xfs_da_state             *state;
     623     1283333 :         int                             error;
     624             : 
     625     1283333 :         xfs_attr_item_init_da_state(attr);
     626     1283335 :         error = xfs_attr_node_lookup(args, attr->xattri_da_state);
     627     1283339 :         if (error != -EEXIST)
     628           6 :                 goto out;
     629     1283333 :         error = 0;
     630             : 
     631     1283333 :         state = attr->xattri_da_state;
     632     1283333 :         ASSERT(state->path.blk[state->path.active - 1].bp != NULL);
     633     1283333 :         ASSERT(state->path.blk[state->path.active - 1].magic ==
     634             :                 XFS_ATTR_LEAF_MAGIC);
     635             : 
     636     1283333 :         error = xfs_attr_leaf_mark_incomplete(args, state);
     637     1283332 :         if (error)
     638           0 :                 goto out;
     639     1283332 :         if (args->rmtblkno > 0)
     640          12 :                 error = xfs_attr_rmtval_invalidate(args);
     641     1283320 : out:
     642     1283338 :         if (error) {
     643           6 :                 xfs_da_state_free(attr->xattri_da_state);
     644           6 :                 attr->xattri_da_state = NULL;
     645             :         }
     646             : 
     647     1283338 :         return error;
     648             : }
     649             : 
     650             : /*
     651             :  * Remove the original attr we have just replaced. This is dependent on the
     652             :  * original lookup and insert placing the old attr in args->blkno/args->index
     653             :  * and the new attr in args->blkno2/args->index2.
     654             :  */
     655             : static int
     656    36207591 : xfs_attr_leaf_remove_attr(
     657             :         struct xfs_attr_intent          *attr)
     658             : {
     659    36207591 :         struct xfs_da_args              *args = attr->xattri_da_args;
     660    36207591 :         struct xfs_inode                *dp = args->dp;
     661    36207591 :         struct xfs_buf                  *bp = NULL;
     662    36207591 :         int                             forkoff;
     663    36207591 :         int                             error;
     664             : 
     665    36207591 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
     666             :                         args->blkno, &bp);
     667    36207630 :         if (error)
     668             :                 return error;
     669             : 
     670    36208574 :         xfs_attr3_leaf_remove(bp, args);
     671             : 
     672    36208115 :         forkoff = xfs_attr_shortform_allfit(bp, dp);
     673    36208898 :         if (forkoff)
     674      803032 :                 error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
     675             :                 /* bp is gone due to xfs_da_shrink_inode */
     676             : 
     677             :         return error;
     678             : }
     679             : 
     680             : /*
     681             :  * Shrink an attribute from leaf to shortform. Used by the node format remove
     682             :  * path when the node format collapses to a single block and so we have to check
     683             :  * if it can be collapsed further.
     684             :  */
     685             : static int
     686     2065816 : xfs_attr_leaf_shrink(
     687             :         struct xfs_da_args      *args)
     688             : {
     689     2065816 :         struct xfs_inode        *dp = args->dp;
     690     2065816 :         struct xfs_buf          *bp;
     691     2065816 :         int                     forkoff;
     692     2065816 :         int                     error;
     693             : 
     694     2065816 :         if (!xfs_attr_is_leaf(dp))
     695             :                 return 0;
     696             : 
     697          86 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
     698          86 :         if (error)
     699             :                 return error;
     700             : 
     701          86 :         forkoff = xfs_attr_shortform_allfit(bp, dp);
     702          86 :         if (forkoff) {
     703          10 :                 error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
     704             :                 /* bp is gone due to xfs_da_shrink_inode */
     705             :         } else {
     706          76 :                 xfs_trans_brelse(args->trans, bp);
     707             :         }
     708             : 
     709             :         return error;
     710             : }
     711             : 
     712             : /*
     713             :  * Run the attribute operation specified in @attr.
     714             :  *
     715             :  * This routine is meant to function as a delayed operation and will set the
     716             :  * state to XFS_DAS_DONE when the operation is complete.  Calling functions will
     717             :  * need to handle this, and recall the function until either an error or
     718             :  * XFS_DAS_DONE is detected.
     719             :  */
     720             : int
     721   544138213 : xfs_attr_set_iter(
     722             :         struct xfs_attr_intent          *attr)
     723             : {
     724   544138213 :         struct xfs_da_args              *args = attr->xattri_da_args;
     725   544138213 :         int                             error = 0;
     726             : 
     727             :         /* State machine switch */
     728             : next_state:
     729   581128176 :         switch (attr->xattri_dela_state) {
     730           0 :         case XFS_DAS_UNINIT:
     731           0 :                 ASSERT(0);
     732           0 :                 return -EFSCORRUPTED;
     733   164731796 :         case XFS_DAS_SF_ADD:
     734   164731796 :                 return xfs_attr_sf_addname(attr);
     735   151819680 :         case XFS_DAS_LEAF_ADD:
     736   151819680 :                 return xfs_attr_leaf_addname(attr);
     737     3219833 :         case XFS_DAS_NODE_ADD:
     738     3219833 :                 return xfs_attr_node_addname(attr);
     739             : 
     740    88998651 :         case XFS_DAS_SF_REMOVE:
     741    88998651 :                 error = xfs_attr_sf_removename(args);
     742    88998958 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     743             :                                                 xfs_attr_init_add_state(args));
     744    89000053 :                 break;
     745    58820381 :         case XFS_DAS_LEAF_REMOVE:
     746    58820381 :                 error = xfs_attr_leaf_removename(args);
     747    58822029 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     748             :                                                 xfs_attr_init_add_state(args));
     749    58824439 :                 break;
     750     1283334 :         case XFS_DAS_NODE_REMOVE:
     751     1283334 :                 error = xfs_attr_node_removename_setup(attr);
     752     1283338 :                 if (error == -ENOATTR &&
     753           6 :                     (args->op_flags & XFS_DA_OP_RECOVERY)) {
     754           6 :                         attr->xattri_dela_state = xfs_attr_complete_op(attr,
     755             :                                                 xfs_attr_init_add_state(args));
     756           6 :                         error = 0;
     757           6 :                         break;
     758             :                 }
     759     1283332 :                 if (error)
     760             :                         return error;
     761     1283332 :                 attr->xattri_dela_state = XFS_DAS_NODE_REMOVE_RMT;
     762     1283332 :                 if (args->rmtblkno == 0)
     763     1283320 :                         attr->xattri_dela_state++;
     764             :                 break;
     765             : 
     766         585 :         case XFS_DAS_LEAF_SET_RMT:
     767             :         case XFS_DAS_NODE_SET_RMT:
     768         585 :                 error = xfs_attr_rmtval_find_space(attr);
     769         585 :                 if (error)
     770           0 :                         return error;
     771         585 :                 attr->xattri_dela_state++;
     772         585 :                 fallthrough;
     773             : 
     774         585 :         case XFS_DAS_LEAF_ALLOC_RMT:
     775             :         case XFS_DAS_NODE_ALLOC_RMT:
     776         585 :                 error = xfs_attr_rmtval_alloc(attr);
     777         585 :                 if (error)
     778           0 :                         return error;
     779         585 :                 if (attr->xattri_dela_state == XFS_DAS_DONE)
     780             :                         break;
     781           2 :                 goto next_state;
     782             : 
     783    36989742 :         case XFS_DAS_LEAF_REPLACE:
     784             :         case XFS_DAS_NODE_REPLACE:
     785             :                 /*
     786             :                  * We must "flip" the incomplete flags on the "new" and "old"
     787             :                  * attribute/value pairs so that one disappears and one appears
     788             :                  * atomically.
     789             :                  */
     790    36989742 :                 error = xfs_attr3_leaf_flipflags(args);
     791    36989983 :                 if (error)
     792             :                         return error;
     793             :                 /*
     794             :                  * We must commit the flag value change now to make it atomic
     795             :                  * and then we can start the next trans in series at REMOVE_OLD.
     796             :                  */
     797    36989983 :                 attr->xattri_dela_state++;
     798    36989983 :                 break;
     799             : 
     800    36991040 :         case XFS_DAS_LEAF_REMOVE_OLD:
     801             :         case XFS_DAS_NODE_REMOVE_OLD:
     802             :                 /*
     803             :                  * If we have a remote attr, start the process of removing it
     804             :                  * by invalidating any cached buffers.
     805             :                  *
     806             :                  * If we don't have a remote attr, we skip the remote block
     807             :                  * removal state altogether with a second state increment.
     808             :                  */
     809    36991040 :                 xfs_attr_restore_rmt_blk(args);
     810    36989961 :                 if (args->rmtblkno) {
     811           4 :                         error = xfs_attr_rmtval_invalidate(args);
     812           4 :                         if (error)
     813           0 :                                 return error;
     814             :                 } else {
     815    36989957 :                         attr->xattri_dela_state++;
     816             :                 }
     817             : 
     818    36989961 :                 attr->xattri_dela_state++;
     819    36989961 :                 goto next_state;
     820             : 
     821          16 :         case XFS_DAS_LEAF_REMOVE_RMT:
     822             :         case XFS_DAS_NODE_REMOVE_RMT:
     823          16 :                 error = xfs_attr_rmtval_remove(attr);
     824          16 :                 if (error == -EAGAIN) {
     825             :                         error = 0;
     826             :                         break;
     827             :                 }
     828          16 :                 if (error)
     829             :                         return error;
     830             : 
     831             :                 /*
     832             :                  * We've finished removing the remote attr blocks, so commit the
     833             :                  * transaction and move on to removing the attr name from the
     834             :                  * leaf/node block. Removing the attr might require a full
     835             :                  * transaction reservation for btree block freeing, so we
     836             :                  * can't do that in the same transaction where we removed the
     837             :                  * remote attr blocks.
     838             :                  */
     839          16 :                 attr->xattri_dela_state++;
     840          16 :                 break;
     841             : 
     842    36207292 :         case XFS_DAS_LEAF_REMOVE_ATTR:
     843    36207292 :                 error = xfs_attr_leaf_remove_attr(attr);
     844    36208738 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     845             :                                                 xfs_attr_init_add_state(args));
     846    36208710 :                 break;
     847             : 
     848     2065826 :         case XFS_DAS_NODE_REMOVE_ATTR:
     849     2065826 :                 error = xfs_attr_node_remove_attr(attr);
     850     2065821 :                 if (!error)
     851     2065812 :                         error = xfs_attr_leaf_shrink(args);
     852     2065834 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     853             :                                                 xfs_attr_init_add_state(args));
     854     2065829 :                 break;
     855           0 :         default:
     856           0 :                 ASSERT(0);
     857           0 :                 break;
     858             :         }
     859             : 
     860   224372951 :         trace_xfs_attr_set_iter_return(attr->xattri_dela_state, args->dp);
     861   224372951 :         return error;
     862             : }
     863             : 
     864             : 
     865             : /*
     866             :  * Return EEXIST if attr is found, or ENOATTR if not
     867             :  */
     868             : static int
     869   340695211 : xfs_attr_lookup(
     870             :         struct xfs_da_args      *args)
     871             : {
     872   340695211 :         struct xfs_inode        *dp = args->dp;
     873   340695211 :         struct xfs_buf          *bp = NULL;
     874   340695211 :         struct xfs_da_state     *state;
     875   340695211 :         int                     error;
     876             : 
     877   340695211 :         if (!xfs_inode_hasattr(dp))
     878             :                 return -ENOATTR;
     879             : 
     880   340359116 :         if (dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
     881    89187327 :                 return xfs_attr_sf_findname(args, NULL, NULL);
     882             : 
     883   251171789 :         if (xfs_attr_is_leaf(dp)) {
     884   245799065 :                 error = xfs_attr_leaf_hasname(args, &bp);
     885             : 
     886   245771220 :                 if (bp)
     887   245771217 :                         xfs_trans_brelse(args->trans, bp);
     888             : 
     889   245823193 :                 return error;
     890             :         }
     891             : 
     892     5354612 :         state = xfs_da_state_alloc(args);
     893     5354599 :         error = xfs_attr_node_lookup(args, state);
     894     5354598 :         xfs_da_state_free(state);
     895     5354598 :         return error;
     896             : }
     897             : 
     898             : int
     899           0 : xfs_attr_intent_init(
     900             :         struct xfs_da_args      *args,
     901             :         unsigned int            op_flags,       /* op flag (set or remove) */
     902             :         struct xfs_attr_intent  **attr)         /* new xfs_attr_intent */
     903             : {
     904             : 
     905   420428648 :         struct xfs_attr_intent  *new;
     906             : 
     907           0 :         new = kmem_cache_zalloc(xfs_attr_intent_cache, GFP_NOFS | __GFP_NOFAIL);
     908   420434218 :         new->xattri_op_flags = op_flags;
     909   420434218 :         new->xattri_da_args = args;
     910             : 
     911   420434218 :         *attr = new;
     912   420434218 :         return 0;
     913             : }
     914             : 
     915             : /* Sets an attribute for an inode as a deferred operation */
     916             : int
     917   220844476 : xfs_attr_defer_add(
     918             :         struct xfs_da_args      *args)
     919             : {
     920   220844476 :         struct xfs_attr_intent  *new;
     921   220844476 :         int                     op_flag = XFS_ATTRI_OP_FLAGS_SET;
     922   220844476 :         int                     error = 0;
     923             : 
     924   220844476 :         if (args->op_flags & XFS_DA_OP_NVLOOKUP)
     925    69169824 :                 op_flag = XFS_ATTRI_OP_FLAGS_NVSET;
     926             : 
     927   220844476 :         error = xfs_attr_intent_init(args, op_flag, &new);
     928   220846819 :         if (error)
     929             :                 return error;
     930             : 
     931   220846819 :         new->xattri_dela_state = xfs_attr_init_add_state(args);
     932   220852654 :         xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
     933   220856629 :         trace_xfs_attr_defer_add(new->xattri_dela_state, args->dp);
     934             : 
     935   220857182 :         return 0;
     936             : }
     937             : 
     938             : /* Sets an attribute for an inode as a deferred operation */
     939             : int
     940    90269297 : xfs_attr_defer_replace(
     941             :         struct xfs_da_args      *args)
     942             : {
     943    90269297 :         struct xfs_attr_intent  *new;
     944    90269297 :         int                     op_flag = XFS_ATTRI_OP_FLAGS_REPLACE;
     945    90269297 :         int                     error = 0;
     946             : 
     947    90269297 :         if (args->op_flags & XFS_DA_OP_NVLOOKUP)
     948    39781117 :                 op_flag = XFS_ATTRI_OP_FLAGS_NVREPLACE;
     949             : 
     950    90269297 :         error = xfs_attr_intent_init(args, op_flag, &new);
     951    90268381 :         if (error)
     952             :                 return error;
     953             : 
     954    90268381 :         new->xattri_dela_state = xfs_attr_init_replace_state(args);
     955    90271120 :         xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
     956    90270813 :         trace_xfs_attr_defer_replace(new->xattri_dela_state, args->dp);
     957             : 
     958    90270811 :         return 0;
     959             : }
     960             : 
     961             : /* Removes an attribute for an inode as a deferred operation */
     962             : int
     963   109314875 : xfs_attr_defer_remove(
     964             :         struct xfs_da_args      *args)
     965             : {
     966             : 
     967   109314875 :         struct xfs_attr_intent  *new;
     968   109314875 :         int                     op_flag = XFS_ATTRI_OP_FLAGS_REMOVE;
     969   109314875 :         int                     error;
     970             : 
     971   109314875 :         if (args->op_flags & XFS_DA_OP_NVLOOKUP)
     972    39071803 :                 op_flag = XFS_ATTRI_OP_FLAGS_NVREMOVE;
     973             : 
     974   109314875 :         error  = xfs_attr_intent_init(args, op_flag, &new);
     975   109319018 :         if (error)
     976             :                 return error;
     977             : 
     978   109319018 :         new->xattri_dela_state = xfs_attr_init_remove_state(args);
     979   109322640 :         xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
     980   109322615 :         trace_xfs_attr_defer_remove(new->xattri_dela_state, args->dp);
     981             : 
     982   109322589 :         return 0;
     983             : }
     984             : 
     985             : int
     986             : xfs_attr_add_fork(
     987             :         struct xfs_inode        *ip,            /* incore inode pointer */
     988             :         int                     size,           /* space new attribute needs */
     989             :         int                     rsvd)           /* xact may use reserved blks */
     990   340738878 : {
     991             :         struct xfs_mount        *mp = ip->i_mount;
     992             :         struct xfs_trans        *tp;            /* transaction pointer */
     993   340738878 :         unsigned int            blks;           /* space reservation */
     994   340738878 :         int                     error;          /* error return value */
     995   340738878 : 
     996   340738878 :         if (xfs_is_metadir_inode(ip))
     997             :                 ASSERT(XFS_IS_DQDETACHED(ip->i_mount, ip));
     998   340738878 :         else
     999   340738878 :                 ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
    1000   340738878 : 
    1001   340738878 :         blks = XFS_ADDAFORK_SPACE_RES(mp);
    1002             : 
    1003   681477756 :         error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_addafork, blks, 0,
    1004             :                         rsvd, &tp);
    1005             :         if (error)
    1006   340738673 :                 return error;
    1007   340758975 : 
    1008             :         if (xfs_inode_has_attr_fork(ip))
    1009             :                 goto trans_cancel;
    1010   340685522 : 
    1011   340685522 :         error = xfs_bmap_add_attrfork(tp, ip, size, rsvd);
    1012   340685522 :         if (error)
    1013             :                 goto trans_cancel;
    1014             : 
    1015             :         error = xfs_trans_commit(tp);
    1016             :         xfs_iunlock(ip, XFS_ILOCK_EXCL);
    1017             :         return error;
    1018             : 
    1019             : trans_cancel:
    1020   340783032 :         xfs_trans_cancel(tp);
    1021   340783032 :         xfs_iunlock(ip, XFS_ILOCK_EXCL);
    1022             :         return error;
    1023   340783032 : }
    1024   234744960 : 
    1025   234744960 : /*
    1026             :  * Note: If args->value is NULL the attribute will be removed, just like the
    1027             :  * Linux ->setattr API.
    1028             :  */
    1029             : int
    1030             : xfs_attr_set(
    1031   234297025 :         struct xfs_da_args      *args)
    1032      317645 : {
    1033      317645 :         struct xfs_inode        *dp = args->dp;
    1034      317645 :         struct xfs_mount        *mp = dp->i_mount;
    1035             :         struct xfs_trans_res    tres;
    1036      317645 :         bool                    rsvd = (args->attr_filter & (XFS_ATTR_ROOT |
    1037      317661 :                                                              XFS_ATTR_PARENT));
    1038             :         bool                    is_remove = args->op_flags & XFS_DA_OP_REMOVE;
    1039             :         int                     error, local;
    1040             :         int                     rmt_blks = 0;
    1041   234297041 :         unsigned int            total;
    1042         705 : 
    1043             :         if (xfs_is_shutdown(dp->i_mount))
    1044   106038072 :                 return -EIO;
    1045   106038072 : 
    1046             :         error = xfs_qm_dqattach(dp);
    1047             :         if (error)
    1048             :                 return error;
    1049             : 
    1050             :         args->geo = mp->m_attr_geo;
    1051             :         args->whichfork = XFS_ATTR_FORK;
    1052   340331253 :         args->hashval = xfs_da_hashname(args->name, args->namelen);
    1053   340719904 : 
    1054   340793304 :         /*
    1055             :          * We have no control over the attribute names that userspace passes us
    1056             :          * to remove, so we have to allow the name lookup prior to attribute
    1057   340707930 :          * removal to fail as well.  Preserve the logged and vlookup flags,
    1058   340697783 :          * since we need to pass them through to the lower levels.
    1059   340697783 :          */
    1060   340655966 :         args->op_flags &= (XFS_DA_OP_LOGGED | XFS_DA_OP_NVLOOKUP);
    1061           4 :         args->op_flags |= XFS_DA_OP_OKNOENT;
    1062           4 : 
    1063   340655966 :         if (!is_remove) {
    1064           4 :                 XFS_STATS_INC(mp, xs_attr_set);
    1065             :                 args->total = xfs_attr_calc_size(args, &local);
    1066             : 
    1067   340666109 :                 /*
    1068   340667105 :                  * If the inode doesn't have an attribute fork, add one.
    1069   121414538 :                  * (inode must not be locked when we call this routine)
    1070             :                  */
    1071   121414538 :                 if (xfs_inode_has_attr_fork(dp) == 0) {
    1072    70250944 :                         int sf_size = sizeof(struct xfs_attr_sf_hdr) +
    1073    70250944 :                                 xfs_attr_sf_entsize_byname(args->namelen,
    1074             :                                                 args->valuelen);
    1075             : 
    1076    51163594 :                         error = xfs_attr_add_fork(dp, sf_size, rsvd);
    1077      675036 :                         if (error)
    1078             :                                 return error;
    1079    50488558 :                 }
    1080    50488558 : 
    1081   219252460 :                 if (!local)
    1082             :                         rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
    1083   219252460 :         } else {
    1084    35757116 :                 XFS_STATS_INC(mp, xs_attr_remove);
    1085             :                 rmt_blks = xfs_attr3_rmt_blocks(mp, XFS_XATTR_SIZE_MAX);
    1086             :         }
    1087   183495344 : 
    1088    31433068 :         /*
    1089             :          * Root fork attributes can use reserved data blocks for this
    1090   152062276 :          * operation if necessary
    1091   152062276 :          */
    1092         107 :         xfs_init_attr_trans(args, &tres, &total);
    1093         107 :         error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
    1094             :         if (error)
    1095   272829065 :                 return error;
    1096           0 : 
    1097             :         if (!is_remove || xfs_inode_hasattr(dp)) {
    1098             :                 error = xfs_iext_count_may_overflow(dp, XFS_ATTR_FORK,
    1099             :                                 XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
    1100             :                 if (error == -EFBIG)
    1101             :                         error = xfs_iext_count_upgrade(args->trans, dp,
    1102   272829065 :                                         XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
    1103           0 :                 if (error)
    1104             :                         goto out_trans_cancel;
    1105   272829065 :         }
    1106   272752212 : 
    1107             :         error = xfs_attr_lookup(args);
    1108             :         switch (error) {
    1109             :         case -EEXIST:
    1110             :                 /* if no value, we are performing a remove operation */
    1111   272888576 :                 if (is_remove) {
    1112   272837372 :                         error = xfs_attr_defer_remove(args);
    1113   340695725 :                         break;
    1114   340695725 :                 }
    1115   340695725 :                 /* Pure create fails if the attr already exists */
    1116             :                 if (args->attr_flags & XATTR_CREATE)
    1117    67865331 :                         goto out_trans_cancel;
    1118    67865331 : 
    1119    67865398 :                 error = xfs_attr_defer_replace(args);
    1120    67869078 :                 break;
    1121             :         case -ENOATTR:
    1122             :                 /* Can't remove what isn't there. */
    1123             :                 if (is_remove)
    1124             :                         goto out_trans_cancel;
    1125             : 
    1126             :                 /* Pure replace fails if no existing attr to replace. */
    1127      277448 :                 if (args->attr_flags & XATTR_REPLACE)
    1128             :                         goto out_trans_cancel;
    1129   165013619 : 
    1130             :                 error = xfs_attr_defer_add(args);
    1131   165013619 :                 break;
    1132   165013619 :         default:
    1133             :                 goto out_trans_cancel;
    1134             :         }
    1135             :         if (error)
    1136             :                 goto out_trans_cancel;
    1137             : 
    1138             :         /*
    1139             :          * If this is a synchronous mount, make sure that the
    1140   164732781 :          * transaction goes to disk before returning to the user.
    1141             :          */
    1142             :         if (xfs_has_wsync(mp))
    1143   164732781 :                 xfs_trans_set_sync(args->trans);
    1144   164732781 : 
    1145             :         if (!(args->op_flags & XFS_DA_OP_NOTIME))
    1146   164732781 :                 xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
    1147             : 
    1148   164738004 :         /*
    1149   164738115 :          * Commit the last in the sequence of transactions.
    1150   151234975 :          */
    1151   151234975 :         xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
    1152             :         error = xfs_trans_commit(args->trans);
    1153             : out_unlock:
    1154    13500237 :         xfs_iunlock(dp, XFS_ILOCK_EXCL);
    1155    13500237 :         return error;
    1156             : 
    1157             : out_trans_cancel:
    1158    13500237 :         if (args->trans)
    1159    13500336 :                 xfs_trans_cancel(args->trans);
    1160             :         goto out_unlock;
    1161             : }
    1162             : 
    1163             : /*========================================================================
    1164             :  * External routines when attribute list is inside the inode
    1165             :  *========================================================================*/
    1166             : 
    1167             : int xfs_attr_sf_totsize(struct xfs_inode *dp)
    1168    13500336 : {
    1169    13500336 :         struct xfs_attr_shortform *sf;
    1170             : 
    1171             :         sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data;
    1172             :         return be16_to_cpu(sf->hdr.totsize);
    1173             : }
    1174             : 
    1175             : /*
    1176   164738214 :  * Add a name to the shortform attribute list structure
    1177   164738214 :  * This is the external routine.
    1178             :  */
    1179             : static int
    1180   164736171 : xfs_attr_shortform_addname(
    1181   164736171 :         struct xfs_da_args      *args)
    1182             : {
    1183   164736171 :         int                     newsize, forkoff;
    1184   164735146 :         int                     error;
    1185             : 
    1186             :         trace_xfs_attr_sf_addname(args);
    1187   156150380 : 
    1188   156150380 :         error = xfs_attr_shortform_lookup(args);
    1189             :         switch (error) {
    1190             :         case -ENOATTR:
    1191             :                 if (args->op_flags & XFS_DA_OP_REPLACE)
    1192             :                         return error;
    1193             :                 break;
    1194             :         case -EEXIST:
    1195             :                 if (!(args->op_flags & XFS_DA_OP_REPLACE))
    1196             :                         return error;
    1197             : 
    1198             :                 error = xfs_attr_sf_removename(args);
    1199             :                 if (error)
    1200             :                         return error;
    1201    37010238 : 
    1202    37010238 :                 /*
    1203    37010238 :                  * Since we have removed the old attr, clear XFS_DA_OP_REPLACE
    1204    37010238 :                  * so that the new attr doesn't fit in shortform format, the
    1205    37010238 :                  * leaf format add routine won't trip over the attr not being
    1206    37010238 :                  * around.
    1207    37010238 :                  */
    1208    37010238 :                 args->op_flags &= ~XFS_DA_OP_REPLACE;
    1209    37010238 :                 break;
    1210             :         case 0:
    1211             :                 break;
    1212             :         default:
    1213    36990656 :                 return error;
    1214             :         }
    1215             : 
    1216    36990656 :         if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
    1217    36990656 :             args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
    1218    36990656 :                 return -ENOSPC;
    1219    36990656 : 
    1220    36990656 :         newsize = xfs_attr_sf_totsize(args->dp);
    1221    36990656 :         newsize += xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
    1222             : 
    1223             :         forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
    1224             :         if (!forkoff)
    1225             :                 return -ENOSPC;
    1226             : 
    1227             :         xfs_attr_shortform_add(args, forkoff);
    1228             :         return 0;
    1229             : }
    1230             : 
    1231             : 
    1232             : /*========================================================================
    1233             :  * External routines when attribute list is one block
    1234   151831395 :  *========================================================================*/
    1235             : 
    1236             : /* Save the current remote block info and clear the current pointers. */
    1237   151831395 : static void
    1238   151831395 : xfs_attr_save_rmt_blk(
    1239             :         struct xfs_da_args      *args)
    1240   151831395 : {
    1241   151827844 :         args->blkno2 = args->blkno;
    1242             :         args->index2 = args->index;
    1243             :         args->rmtblkno2 = args->rmtblkno;
    1244             :         args->rmtblkcnt2 = args->rmtblkcnt;
    1245             :         args->rmtvaluelen2 = args->rmtvaluelen;
    1246             :         args->rmtblkno = 0;
    1247   151855159 :         args->rmtblkcnt = 0;
    1248   151842505 :         args->rmtvaluelen = 0;
    1249   115616164 : }
    1250   115616164 : 
    1251           0 : /* Set stored info about a remote block */
    1252             : static void
    1253    36226341 : xfs_attr_restore_rmt_blk(
    1254    36226341 :         struct xfs_da_args      *args)
    1255           0 : {
    1256             :         args->blkno = args->blkno2;
    1257    36226341 :         args->index = args->index2;
    1258             :         args->rmtblkno = args->rmtblkno2;
    1259             :         args->rmtblkcnt = args->rmtblkcnt2;
    1260             :         args->rmtvaluelen = args->rmtvaluelen2;
    1261             : }
    1262             : 
    1263    36227742 : /*
    1264             :  * Tries to add an attribute to an inode in leaf form
    1265             :  *
    1266             :  * This function is meant to execute as part of a delayed operation and leaves
    1267           0 :  * the transaction handling to the caller.  On success the attribute is added
    1268           0 :  * and the inode and transaction are left dirty.  If there is not enough space,
    1269             :  * the attr data is converted to node format and -ENOSPC is returned. Caller is
    1270             :  * responsible for handling the dirty inode and transaction or adding the attr
    1271   151843906 :  * in node format.
    1272             :  */
    1273           0 : STATIC int
    1274           0 : xfs_attr_leaf_try_add(
    1275           0 :         struct xfs_da_args      *args)
    1276             : {
    1277             :         struct xfs_buf          *bp;
    1278             :         int                     error;
    1279             : 
    1280             :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
    1281             :         if (error)
    1282   337005190 :                 return error;
    1283             : 
    1284             :         /*
    1285             :          * Look up the xattr name to set the insertion point for the new xattr.
    1286   337005190 :          */
    1287             :         error = xfs_attr3_leaf_lookup_int(bp, args);
    1288   337005190 :         switch (error) {
    1289   336970003 :         case -ENOATTR:
    1290             :                 if (args->op_flags & XFS_DA_OP_REPLACE)
    1291             :                         goto out_brelse;
    1292   336967342 :                 break;
    1293   337082595 :         case -EEXIST:
    1294           0 :                 if (!(args->op_flags & XFS_DA_OP_REPLACE))
    1295             :                         goto out_brelse;
    1296             : 
    1297             :                 trace_xfs_attr_leaf_replace(args);
    1298             :                 /*
    1299             :                  * Save the existing remote attr state so that the current
    1300             :                  * values reflect the state of the new attribute we are about to
    1301             :                  * add, not the attribute we just found and will remove later.
    1302             :                  */
    1303             :                 xfs_attr_save_rmt_blk(args);
    1304             :                 break;
    1305             :         case 0:
    1306    58820960 :                 break;
    1307             :         default:
    1308             :                 goto out_brelse;
    1309    58820960 :         }
    1310    58820960 : 
    1311    58820960 :         return xfs_attr3_leaf_add(bp, args);
    1312             : 
    1313    58820960 : out_brelse:
    1314             :         xfs_trans_brelse(args->trans, bp);
    1315             :         return error;
    1316             : }
    1317             : 
    1318    58824698 : /*
    1319             :  * Return EEXIST if attr is found, or ENOATTR if not
    1320    58824698 :  */
    1321    58825765 : STATIC int
    1322           7 : xfs_attr_leaf_hasname(
    1323           7 :         struct xfs_da_args      *args,
    1324             :         struct xfs_buf          **bp)
    1325           0 : {
    1326    58825758 :         int                     error = 0;
    1327             : 
    1328             :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, bp);
    1329    58824863 :         if (error)
    1330             :                 return error;
    1331             : 
    1332             :         error = xfs_attr3_leaf_lookup_int(*bp, args);
    1333             :         if (error != -ENOATTR && error != -EEXIST)
    1334    58825633 :                 xfs_trans_brelse(args->trans, *bp);
    1335    58824684 : 
    1336     3697927 :         return error;
    1337             : }
    1338             : 
    1339             : /*
    1340             :  * Remove a name from the leaf attribute list structure
    1341             :  *
    1342             :  * This leaf block cannot have a "remote" value, we only call this routine
    1343             :  * if bmap_one_block() says there is only one block (ie: no remote blks).
    1344             :  */
    1345             : STATIC int
    1346             : xfs_attr_leaf_removename(
    1347             :         struct xfs_da_args      *args)
    1348             : {
    1349             :         struct xfs_inode        *dp;
    1350             :         struct xfs_buf          *bp;
    1351    32550007 :         int                     error, forkoff;
    1352             : 
    1353    32550007 :         trace_xfs_attr_leaf_removename(args);
    1354    32550007 : 
    1355             :         /*
    1356    32550007 :          * Remove the attribute.
    1357             :          */
    1358    32550784 :         dp = args->dp;
    1359             : 
    1360    32550632 :         error = xfs_attr_leaf_hasname(args, &bp);
    1361    12175168 :         if (error == -ENOATTR) {
    1362    12175168 :                 xfs_trans_brelse(args->trans, bp);
    1363    20375464 :                 if (args->op_flags & XFS_DA_OP_RECOVERY)
    1364             :                         return 0;
    1365             :                 return error;
    1366             :         } else if (error != -EEXIST)
    1367    20375454 :                 return error;
    1368    20375361 : 
    1369    20375361 :         xfs_attr3_leaf_remove(bp, args);
    1370             : 
    1371             :         /*
    1372             :          * If the result is small enough, shrink it all into the inode.
    1373             :          */
    1374    10644368 :         forkoff = xfs_attr_shortform_allfit(bp, dp);
    1375             :         if (forkoff)
    1376             :                 return xfs_attr3_leaf_to_shortform(bp, args, forkoff);
    1377             :                 /* bp is gone due to xfs_da_shrink_inode */
    1378    10644368 : 
    1379             :         return 0;
    1380             : }
    1381             : 
    1382             : /*
    1383    10644368 :  * Look up a name in a leaf attribute list structure.
    1384    10644502 :  *
    1385             :  * This leaf block cannot have a "remote" value, we only call this routine
    1386             :  * if bmap_one_block() says there is only one block (ie: no remote blks).
    1387    10644298 :  *
    1388             :  * Returns 0 on successful retrieval, otherwise an error.
    1389             :  */
    1390             : STATIC int
    1391             : xfs_attr_leaf_get(xfs_da_args_t *args)
    1392             : {
    1393             :         struct xfs_buf *bp;
    1394             :         int error;
    1395     3219820 : 
    1396             :         trace_xfs_attr_leaf_get(args);
    1397             : 
    1398     3219820 :         error = xfs_attr_leaf_hasname(args, &bp);
    1399     3219820 : 
    1400             :         if (error == -ENOATTR)  {
    1401             :                 xfs_trans_brelse(args->trans, bp);
    1402             :                 return error;
    1403             :         } else if (error != -EEXIST)
    1404             :                 return error;
    1405     3219820 : 
    1406     3219845 : 
    1407     3219848 :         error = xfs_attr3_leaf_getvalue(bp, args);
    1408     2437353 :         xfs_trans_brelse(args->trans, bp);
    1409     2437353 :         return error;
    1410           0 : }
    1411             : 
    1412      782495 : /* Return EEXIST if attr is found, or ENOATTR if not. */
    1413      782495 : STATIC int
    1414           0 : xfs_attr_node_lookup(
    1415             :         struct xfs_da_args      *args,
    1416             :         struct xfs_da_state     *state)
    1417      782495 : {
    1418             :         int                     retval, error;
    1419             : 
    1420             :         /*
    1421             :          * Search to see if name exists, and get back a pointer to it.
    1422             :          */
    1423      782496 :         error = xfs_da3_node_lookup_int(state, &retval);
    1424             :         if (error)
    1425             :                 return error;
    1426             : 
    1427           0 :         return retval;
    1428           0 : }
    1429             : 
    1430             : /*========================================================================
    1431             :  * External routines when attribute list size > geo->blksize
    1432           0 :  *========================================================================*/
    1433           0 : 
    1434           0 : STATIC int
    1435           0 : xfs_attr_node_addname_find_attr(
    1436             :          struct xfs_attr_intent *attr)
    1437             : {
    1438             :         struct xfs_da_args      *args = attr->xattri_da_args;
    1439             :         int                     error;
    1440             : 
    1441             :         /*
    1442             :          * Search to see if name already exists, and get back a pointer
    1443             :          * to where it should go.
    1444             :          */
    1445             :         xfs_attr_item_init_da_state(attr);
    1446             :         error = xfs_attr_node_lookup(args, attr->xattri_da_state);
    1447             :         switch (error) {
    1448     3219783 :         case -ENOATTR:
    1449             :                 if (args->op_flags & XFS_DA_OP_REPLACE)
    1450             :                         goto error;
    1451     3219783 :                 break;
    1452     3219783 :         case -EEXIST:
    1453     3219783 :                 if (!(args->op_flags & XFS_DA_OP_REPLACE))
    1454             :                         goto error;
    1455     3219783 : 
    1456             : 
    1457     3219844 :                 trace_xfs_attr_node_replace(args);
    1458     3219844 :                 /*
    1459             :                  * Save the existing remote attr state so that the current
    1460     3219844 :                  * values reflect the state of the new attribute we are about to
    1461     3219845 :                  * add, not the attribute we just found and will remove later.
    1462      108624 :                  */
    1463             :                 xfs_attr_save_rmt_blk(args);
    1464             :                 break;
    1465             :         case 0:
    1466             :                 break;
    1467             :         default:
    1468           0 :                 goto error;
    1469             :         }
    1470             : 
    1471             :         return 0;
    1472             : error:
    1473             :         if (attr->xattri_da_state) {
    1474             :                 xfs_da_state_free(attr->xattri_da_state);
    1475             :                 attr->xattri_da_state = NULL;
    1476             :         }
    1477      108624 :         return error;
    1478      108624 : }
    1479           2 : 
    1480             : /*
    1481             :  * Add a name to a Btree-format attribute list.
    1482             :  *
    1483             :  * This will involve walking down the Btree, and may involve splitting
    1484     3111221 :  * leaf nodes and even splitting intermediate nodes up to and including
    1485             :  * the root node (a special case of an intermediate node).
    1486             :  */
    1487     3219850 : static int
    1488     3219850 : xfs_attr_node_try_addname(
    1489     3219846 :         struct xfs_attr_intent          *attr)
    1490     3219846 : {
    1491             :         struct xfs_da_state             *state = attr->xattri_da_state;
    1492             :         struct xfs_da_state_blk         *blk;
    1493             :         int                             error;
    1494     2065822 : 
    1495             :         trace_xfs_attr_node_addname(state->args);
    1496             : 
    1497             :         blk = &state->path.blk[state->path.active-1];
    1498     2065822 :         ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
    1499     2065822 : 
    1500             :         error = xfs_attr3_leaf_add(blk->bp, state->args);
    1501             :         if (error == -ENOSPC) {
    1502             :                 if (state->path.active == 1) {
    1503             :                         /*
    1504     2065822 :                          * Its really a single leaf node, but it had
    1505     2065822 :                          * out-of-line values so it looked like it *might*
    1506     2065822 :                          * have been a b-tree. Let the caller deal with this.
    1507     2065824 :                          */
    1508             :                         goto out;
    1509     2065828 :                 }
    1510             : 
    1511             :                 /*
    1512             :                  * Split as many Btree elements as required.
    1513     2065829 :                  * This code tracks the new and old attr's location
    1514             :                  * in the index/blkno/rmtblkno/rmtblkcnt fields and
    1515             :                  * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields.
    1516     2065829 :                  */
    1517     2065829 :                 error = xfs_da3_split(state);
    1518     2065829 :                 if (error)
    1519     2065829 :                         goto out;
    1520             :         } else {
    1521             :                 /*
    1522             :                  * Addition succeeded, update Btree hashvals.
    1523             :                  */
    1524             :                 xfs_da3_fixhashpath(state, &state->path);
    1525             :         }
    1526     2065829 : 
    1527     2065829 : out:
    1528     2065820 :         xfs_da_state_free(state);
    1529           0 :         attr->xattri_da_state = NULL;
    1530             :         return error;
    1531     2065820 : }
    1532             : 
    1533             : static int
    1534             : xfs_attr_node_removename(
    1535             :         struct xfs_da_args      *args,
    1536     2065826 :         struct xfs_da_state     *state)
    1537     2065399 : {
    1538     2065401 :         struct xfs_da_state_blk *blk;
    1539           2 :         int                     retval;
    1540             : 
    1541     2065826 :         /*
    1542             :          * Remove the name and update the hashvals in the tree.
    1543     2065828 :          */
    1544     2065828 :         blk = &state->path.blk[state->path.active-1];
    1545     2065829 :         ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
    1546             :         retval = xfs_attr3_leaf_remove(blk->bp, args);
    1547     2065827 :         xfs_da3_fixhashpath(state, &state->path);
    1548             : 
    1549             :         return retval;
    1550             : }
    1551             : 
    1552             : static int
    1553             : xfs_attr_node_remove_attr(
    1554             :         struct xfs_attr_intent          *attr)
    1555             : {
    1556             :         struct xfs_da_args              *args = attr->xattri_da_args;
    1557             :         struct xfs_da_state             *state = xfs_da_state_alloc(args);
    1558             :         int                             retval = 0;
    1559             :         int                             error = 0;
    1560      786808 : 
    1561             :         /*
    1562             :          * The attr we are removing has already been marked incomplete, so
    1563      786808 :          * we need to set the filter appropriately to re-find the "old"
    1564      786808 :          * attribute entry after any split ops.
    1565      786808 :          */
    1566      786808 :         args->attr_filter |= XFS_ATTR_INCOMPLETE;
    1567             :         error = xfs_da3_node_lookup_int(state, &retval);
    1568      786808 :         if (error)
    1569             :                 goto out;
    1570             : 
    1571             :         error = xfs_attr_node_removename(args, state);
    1572             : 
    1573      786807 :         /*
    1574      786807 :          * Check to see if the tree needs to be collapsed.
    1575      786808 :          */
    1576      250363 :         if (retval && (state->path.active > 1)) {
    1577             :                 error = xfs_da3_join(state);
    1578             :                 if (error)
    1579             :                         goto out;
    1580             :         }
    1581      536445 :         retval = error = 0;
    1582      536445 : 
    1583             : out:
    1584             :         xfs_da_state_free(state);
    1585             :         if (error)
    1586             :                 return error;
    1587      786808 :         return retval;
    1588     2359666 : }
    1589     1572858 : 
    1590     1572858 : /*
    1591             :  * Retrieve the attribute data from a node attribute list.
    1592             :  *
    1593      786808 :  * This routine gets called for any attribute fork that has more than one
    1594      786808 :  * block, ie: both true Btree attr lists and for single-leaf-blocks with
    1595             :  * "remote" values taking up more blocks.
    1596             :  *
    1597             :  * Returns 0 on successful retrieval, otherwise an error.
    1598             :  */
    1599  7158034247 : STATIC int
    1600             : xfs_attr_node_get(
    1601             :         struct xfs_da_args      *args)
    1602             : {
    1603             :         struct xfs_da_state     *state;
    1604             :         struct xfs_da_state_blk *blk;
    1605  7158034247 :         int                     i;
    1606   389323140 :         int                     error;
    1607             : 
    1608             :         trace_xfs_attr_node_get(args);
    1609             : 
    1610             :         /*
    1611             :          * Search to see if name exists, and get back a pointer to it.
    1612  6768711107 :          */
    1613             :         state = xfs_da_state_alloc(args);
    1614             :         error = xfs_attr_node_lookup(args, state);
    1615             :         if (error != -EEXIST)
    1616 13537422214 :                 goto out_release;
    1617             : 
    1618             :         /*
    1619             :          * Get the value, local or "remote"
    1620          12 :          */
    1621             :         blk = &state->path.blk[state->path.active - 1];
    1622          12 :         error = xfs_attr3_leaf_getvalue(blk->bp, args);
    1623             : 
    1624             :         /*
    1625             :          * If not in a transaction, we have to release all the buffers.
    1626          12 :          */
    1627             : out_release:
    1628             :         for (i = 0; i < state->path.active; i++) {
    1629             :                 xfs_trans_brelse(args->trans, state->path.blk[i].bp);
    1630          12 :                 state->path.blk[i].bp = NULL;
    1631             :         }
    1632          12 : 
    1633          12 :         xfs_da_state_free(state);
    1634          12 :         return error;
    1635             : }
    1636             : 
    1637             : /* Returns true if the attribute entry name is valid. */
    1638             : bool
    1639             : xfs_attr_namecheck(
    1640             :         struct xfs_mount        *mp,
    1641             :         const void              *name,
    1642             :         size_t                  length,
    1643             :         unsigned int            flags)
    1644             : {
    1645             :         if (flags & XFS_ATTR_PARENT)
    1646             :                 return xfs_parent_namecheck(mp, name, length, flags);
    1647             : 
    1648             :         /*
    1649             :          * MAXNAMELEN includes the trailing null, but (name/length) leave it
    1650             :          * out, so use >= for the length check.
    1651             :          */
    1652             :         if (length >= MAXNAMELEN)
    1653             :                 return false;
    1654             : 
    1655             :         /* There shouldn't be any nulls here */
    1656             :         return !memchr(name, 0, length);
    1657             : }
    1658             : 
    1659             : int __init
    1660             : xfs_attr_intent_init_cache(void)
    1661             : {
    1662             :         xfs_attr_intent_cache = kmem_cache_create("xfs_attr_intent",
    1663             :                         sizeof(struct xfs_attr_intent),
    1664             :                         0, 0, NULL);
    1665             : 
    1666             :         return xfs_attr_intent_cache != NULL ? 0 : -ENOMEM;
    1667             : }
    1668             : 
    1669             : void
    1670             : xfs_attr_intent_destroy_cache(void)
    1671             : {
    1672             :         kmem_cache_destroy(xfs_attr_intent_cache);
    1673             :         xfs_attr_intent_cache = NULL;
    1674             : }

Generated by: LCOV version 1.14