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-rc3-djwx @ Mon Jul 31 20:08:22 PDT 2023 Lines: 560 596 94.0 %
Date: 2023-07-31 20:08:22 Functions: 36 36 100.0 %

          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             : 
      30             : struct kmem_cache               *xfs_attr_intent_cache;
      31             : 
      32             : /*
      33             :  * xfs_attr.c
      34             :  *
      35             :  * Provide the external interfaces to manage attribute lists.
      36             :  */
      37             : 
      38             : /*========================================================================
      39             :  * Function prototypes for the kernel.
      40             :  *========================================================================*/
      41             : 
      42             : /*
      43             :  * Internal routines when attribute list fits inside the inode.
      44             :  */
      45             : STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
      46             : 
      47             : /*
      48             :  * Internal routines when attribute list is one block.
      49             :  */
      50             : STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
      51             : STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
      52             : STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp);
      53             : STATIC int xfs_attr_leaf_try_add(struct xfs_da_args *args);
      54             : 
      55             : /*
      56             :  * Internal routines when attribute list is more than one block.
      57             :  */
      58             : STATIC int xfs_attr_node_get(xfs_da_args_t *args);
      59             : STATIC void xfs_attr_restore_rmt_blk(struct xfs_da_args *args);
      60             : static int xfs_attr_node_try_addname(struct xfs_attr_intent *attr);
      61             : STATIC int xfs_attr_node_addname_find_attr(struct xfs_attr_intent *attr);
      62             : STATIC int xfs_attr_node_remove_attr(struct xfs_attr_intent *attr);
      63             : STATIC int xfs_attr_node_lookup(struct xfs_da_args *args,
      64             :                 struct xfs_da_state *state);
      65             : 
      66             : int
      67   398573590 : xfs_inode_hasattr(
      68             :         struct xfs_inode        *ip)
      69             : {
      70   443562164 :         if (!xfs_inode_has_attr_fork(ip))
      71             :                 return 0;
      72   299184395 :         if (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
      73   151453146 :             ip->i_af.if_nextents == 0)
      74      485618 :                 return 0;
      75             :         return 1;
      76             : }
      77             : 
      78             : /*
      79             :  * Returns true if the there is exactly only block in the attr fork, in which
      80             :  * case the attribute fork consists of a single leaf block entry.
      81             :  */
      82             : bool
      83   257182762 : xfs_attr_is_leaf(
      84             :         struct xfs_inode        *ip)
      85             : {
      86   257182762 :         struct xfs_ifork        *ifp = &ip->i_af;
      87   257182762 :         struct xfs_iext_cursor  icur;
      88   257182762 :         struct xfs_bmbt_irec    imap;
      89             : 
      90   257182762 :         if (ifp->if_nextents != 1 || ifp->if_format != XFS_DINODE_FMT_EXTENTS)
      91             :                 return false;
      92             : 
      93   252210630 :         xfs_iext_first(ifp, &icur);
      94   252191012 :         xfs_iext_get_extent(ifp, &icur, &imap);
      95   253022930 :         return imap.br_startoff == 0 && imap.br_blockcount == 1;
      96             : }
      97             : 
      98             : /*
      99             :  * XXX (dchinner): name path state saving and refilling is an optimisation to
     100             :  * avoid needing to look up name entries after rolling transactions removing
     101             :  * remote xattr blocks between the name entry lookup and name entry removal.
     102             :  * This optimisation got sidelined when combining the set and remove state
     103             :  * machines, but the code has been left in place because it is worthwhile to
     104             :  * restore the optimisation once the combined state machine paths have settled.
     105             :  *
     106             :  * This comment is a public service announcement to remind Future Dave that he
     107             :  * still needs to restore this code to working order.
     108             :  */
     109             : #if 0
     110             : /*
     111             :  * Fill in the disk block numbers in the state structure for the buffers
     112             :  * that are attached to the state structure.
     113             :  * This is done so that we can quickly reattach ourselves to those buffers
     114             :  * after some set of transaction commits have released these buffers.
     115             :  */
     116             : static int
     117             : xfs_attr_fillstate(xfs_da_state_t *state)
     118             : {
     119             :         xfs_da_state_path_t *path;
     120             :         xfs_da_state_blk_t *blk;
     121             :         int level;
     122             : 
     123             :         trace_xfs_attr_fillstate(state->args);
     124             : 
     125             :         /*
     126             :          * Roll down the "path" in the state structure, storing the on-disk
     127             :          * block number for those buffers in the "path".
     128             :          */
     129             :         path = &state->path;
     130             :         ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
     131             :         for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
     132             :                 if (blk->bp) {
     133             :                         blk->disk_blkno = xfs_buf_daddr(blk->bp);
     134             :                         blk->bp = NULL;
     135             :                 } else {
     136             :                         blk->disk_blkno = 0;
     137             :                 }
     138             :         }
     139             : 
     140             :         /*
     141             :          * Roll down the "altpath" in the state structure, storing the on-disk
     142             :          * block number for those buffers in the "altpath".
     143             :          */
     144             :         path = &state->altpath;
     145             :         ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
     146             :         for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
     147             :                 if (blk->bp) {
     148             :                         blk->disk_blkno = xfs_buf_daddr(blk->bp);
     149             :                         blk->bp = NULL;
     150             :                 } else {
     151             :                         blk->disk_blkno = 0;
     152             :                 }
     153             :         }
     154             : 
     155             :         return 0;
     156             : }
     157             : 
     158             : /*
     159             :  * Reattach the buffers to the state structure based on the disk block
     160             :  * numbers stored in the state structure.
     161             :  * This is done after some set of transaction commits have released those
     162             :  * buffers from our grip.
     163             :  */
     164             : static int
     165             : xfs_attr_refillstate(xfs_da_state_t *state)
     166             : {
     167             :         xfs_da_state_path_t *path;
     168             :         xfs_da_state_blk_t *blk;
     169             :         int level, error;
     170             : 
     171             :         trace_xfs_attr_refillstate(state->args);
     172             : 
     173             :         /*
     174             :          * Roll down the "path" in the state structure, storing the on-disk
     175             :          * block number for those buffers in the "path".
     176             :          */
     177             :         path = &state->path;
     178             :         ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
     179             :         for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
     180             :                 if (blk->disk_blkno) {
     181             :                         error = xfs_da3_node_read_mapped(state->args->trans,
     182             :                                         state->args->dp, blk->disk_blkno,
     183             :                                         &blk->bp, XFS_ATTR_FORK);
     184             :                         if (error)
     185             :                                 return error;
     186             :                 } else {
     187             :                         blk->bp = NULL;
     188             :                 }
     189             :         }
     190             : 
     191             :         /*
     192             :          * Roll down the "altpath" in the state structure, storing the on-disk
     193             :          * block number for those buffers in the "altpath".
     194             :          */
     195             :         path = &state->altpath;
     196             :         ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
     197             :         for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
     198             :                 if (blk->disk_blkno) {
     199             :                         error = xfs_da3_node_read_mapped(state->args->trans,
     200             :                                         state->args->dp, blk->disk_blkno,
     201             :                                         &blk->bp, XFS_ATTR_FORK);
     202             :                         if (error)
     203             :                                 return error;
     204             :                 } else {
     205             :                         blk->bp = NULL;
     206             :                 }
     207             :         }
     208             : 
     209             :         return 0;
     210             : }
     211             : #else
     212             : static int xfs_attr_fillstate(xfs_da_state_t *state) { return 0; }
     213             : #endif
     214             : 
     215             : /*========================================================================
     216             :  * Overall external interface routines.
     217             :  *========================================================================*/
     218             : 
     219             : /*
     220             :  * Retrieve an extended attribute and its value.  Must have ilock.
     221             :  * Returns 0 on successful retrieval, otherwise an error.
     222             :  */
     223             : int
     224    50595915 : xfs_attr_get_ilocked(
     225             :         struct xfs_da_args      *args)
     226             : {
     227    50595915 :         ASSERT(xfs_isilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
     228             : 
     229    50550478 :         if (!xfs_inode_hasattr(args->dp))
     230             :                 return -ENOATTR;
     231             : 
     232    35286906 :         if (args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
     233    25729305 :                 return xfs_attr_shortform_getvalue(args);
     234     9557601 :         if (xfs_attr_is_leaf(args->dp))
     235     9332536 :                 return xfs_attr_leaf_get(args);
     236      225812 :         return xfs_attr_node_get(args);
     237             : }
     238             : 
     239             : /*
     240             :  * Retrieve an extended attribute by name, and its value if requested.
     241             :  *
     242             :  * If args->valuelen is zero, then the caller does not want the value, just an
     243             :  * indication whether the attribute exists and the size of the value if it
     244             :  * exists. The size is returned in args.valuelen.
     245             :  *
     246             :  * If args->value is NULL but args->valuelen is non-zero, allocate the buffer
     247             :  * for the value after existence of the attribute has been determined. The
     248             :  * caller always has to free args->value if it is set, no matter if this
     249             :  * function was successful or not.
     250             :  *
     251             :  * If the attribute is found, but exceeds the size limit set by the caller in
     252             :  * args->valuelen, return -ERANGE with the size of the attribute that was found
     253             :  * in args->valuelen.
     254             :  */
     255             : int
     256    30740815 : xfs_attr_get(
     257             :         struct xfs_da_args      *args)
     258             : {
     259    30740815 :         uint                    lock_mode;
     260    30740815 :         int                     error;
     261             : 
     262    30740815 :         XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
     263             : 
     264    61368550 :         if (xfs_is_shutdown(args->dp->i_mount))
     265             :                 return -EIO;
     266             : 
     267    30683546 :         args->geo = args->dp->i_mount->m_attr_geo;
     268    30683546 :         args->whichfork = XFS_ATTR_FORK;
     269    30683546 :         args->hashval = xfs_da_hashname(args->name, args->namelen);
     270             : 
     271             :         /* Entirely possible to look up a name which doesn't exist */
     272    30676879 :         args->op_flags = XFS_DA_OP_OKNOENT;
     273             : 
     274    30676879 :         lock_mode = xfs_ilock_attr_map_shared(args->dp);
     275    30694752 :         error = xfs_attr_get_ilocked(args);
     276    30684950 :         xfs_iunlock(args->dp, lock_mode);
     277             : 
     278    30684950 :         return error;
     279             : }
     280             : 
     281             : /*
     282             :  * Calculate how many blocks we need for the new attribute,
     283             :  */
     284             : int
     285    80041989 : xfs_attr_calc_size(
     286             :         struct xfs_da_args      *args,
     287             :         int                     *local)
     288             : {
     289    80041989 :         struct xfs_mount        *mp = args->dp->i_mount;
     290    80041989 :         int                     size;
     291    80041989 :         int                     nblks;
     292             : 
     293             :         /*
     294             :          * Determine space new attribute will use, and if it would be
     295             :          * "local" or "remote" (note: local != inline).
     296             :          */
     297    80041989 :         size = xfs_attr_leaf_newentsize(args, local);
     298    80033856 :         nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
     299    80033856 :         if (*local) {
     300    80030670 :                 if (size > (args->geo->blksize / 2)) {
     301             :                         /* Double split possible */
     302          11 :                         nblks *= 2;
     303             :                 }
     304             :         } else {
     305             :                 /*
     306             :                  * Out of line attribute, cannot double split, but
     307             :                  * make room for the attribute value itself.
     308             :                  */
     309        3186 :                 uint    dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
     310        3186 :                 nblks += dblocks;
     311        3186 :                 nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
     312             :         }
     313             : 
     314    80033856 :         return nblks;
     315             : }
     316             : 
     317             : /* Initialize transaction reservation for attr operations */
     318             : void
     319   124960773 : xfs_init_attr_trans(
     320             :         struct xfs_da_args      *args,
     321             :         struct xfs_trans_res    *tres,
     322             :         unsigned int            *total)
     323             : {
     324   124960773 :         struct xfs_mount        *mp = args->dp->i_mount;
     325             : 
     326   124960773 :         if (args->value) {
     327    80043313 :                 tres->tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
     328    80043313 :                                  M_RES(mp)->tr_attrsetrt.tr_logres *
     329    80043313 :                                  args->total;
     330    80043313 :                 tres->tr_logcount = XFS_ATTRSET_LOG_COUNT;
     331    80043313 :                 tres->tr_logflags = XFS_TRANS_PERM_LOG_RES;
     332    80043313 :                 *total = args->total;
     333             :         } else {
     334    44917460 :                 *tres = M_RES(mp)->tr_attrrm;
     335    44917460 :                 *total = XFS_ATTRRM_SPACE_RES(mp);
     336             :         }
     337   124960773 : }
     338             : 
     339             : /*
     340             :  * Add an attr to a shortform fork. If there is no space,
     341             :  * xfs_attr_shortform_addname() will convert to leaf format and return -ENOSPC.
     342             :  * to use.
     343             :  */
     344             : STATIC int
     345    24030559 : xfs_attr_try_sf_addname(
     346             :         struct xfs_inode        *dp,
     347             :         struct xfs_da_args      *args)
     348             : {
     349             : 
     350    24030559 :         int                     error;
     351             : 
     352             :         /*
     353             :          * Build initial attribute list (if required).
     354             :          */
     355    24030559 :         if (dp->i_af.if_format == XFS_DINODE_FMT_EXTENTS)
     356     4888605 :                 xfs_attr_shortform_create(args);
     357             : 
     358    24031740 :         error = xfs_attr_shortform_addname(args);
     359    24052740 :         if (error == -ENOSPC)
     360             :                 return error;
     361             : 
     362             :         /*
     363             :          * Commit the shortform mods, and we're done.
     364             :          * NOTE: this is also the error path (EEXIST, etc).
     365             :          */
     366    21208421 :         if (!error && !(args->op_flags & XFS_DA_OP_NOTIME))
     367    21208048 :                 xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
     368             : 
     369    21209285 :         if (xfs_has_wsync(dp->i_mount))
     370           0 :                 xfs_trans_set_sync(args->trans);
     371             : 
     372             :         return error;
     373             : }
     374             : 
     375             : static int
     376    24034325 : xfs_attr_sf_addname(
     377             :         struct xfs_attr_intent          *attr)
     378             : {
     379    24034325 :         struct xfs_da_args              *args = attr->xattri_da_args;
     380    24034325 :         struct xfs_inode                *dp = args->dp;
     381    24034325 :         int                             error = 0;
     382             : 
     383    24034325 :         error = xfs_attr_try_sf_addname(dp, args);
     384    24049403 :         if (error != -ENOSPC) {
     385    21205150 :                 ASSERT(!error || error == -EEXIST);
     386    21205150 :                 attr->xattri_dela_state = XFS_DAS_DONE;
     387    21205150 :                 goto out;
     388             :         }
     389             : 
     390             :         /*
     391             :          * It won't fit in the shortform, transform to a leaf block.  GROT:
     392             :          * another possible req'mt for a double-split btree op.
     393             :          */
     394     2844253 :         error = xfs_attr_shortform_to_leaf(args);
     395     2844485 :         if (error)
     396             :                 return error;
     397             : 
     398     2844478 :         attr->xattri_dela_state = XFS_DAS_LEAF_ADD;
     399    24049628 : out:
     400    24049628 :         trace_xfs_attr_sf_addname_return(attr->xattri_dela_state, args->dp);
     401    24049628 :         return error;
     402             : }
     403             : 
     404             : /*
     405             :  * Handle the state change on completion of a multi-state attr operation.
     406             :  *
     407             :  * If the XFS_DA_OP_REPLACE flag is set, this means the operation was the first
     408             :  * modification in a attr replace operation and we still have to do the second
     409             :  * state, indicated by @replace_state.
     410             :  *
     411             :  * We consume the XFS_DA_OP_REPLACE flag so that when we are called again on
     412             :  * completion of the second half of the attr replace operation we correctly
     413             :  * signal that it is done.
     414             :  */
     415             : static enum xfs_delattr_state
     416             : xfs_attr_complete_op(
     417             :         struct xfs_attr_intent  *attr,
     418             :         enum xfs_delattr_state  replace_state)
     419             : {
     420    82818578 :         struct xfs_da_args      *args = attr->xattri_da_args;
     421    82818578 :         bool                    do_replace = args->op_flags & XFS_DA_OP_REPLACE;
     422             : 
     423    82818578 :         args->op_flags &= ~XFS_DA_OP_REPLACE;
     424    34535359 :         if (do_replace) {
     425    11491122 :                 args->attr_filter &= ~XFS_ATTR_INCOMPLETE;
     426    11491122 :                 return replace_state;
     427             :         }
     428             :         return XFS_DAS_DONE;
     429             : }
     430             : 
     431             : static int
     432    46993310 : xfs_attr_leaf_addname(
     433             :         struct xfs_attr_intent  *attr)
     434             : {
     435    46993310 :         struct xfs_da_args      *args = attr->xattri_da_args;
     436    46993310 :         int                     error;
     437             : 
     438    46993310 :         ASSERT(xfs_attr_is_leaf(args->dp));
     439             : 
     440             :         /*
     441             :          * Use the leaf buffer we may already hold locked as a result of
     442             :          * a sf-to-leaf conversion.
     443             :          */
     444    47036953 :         error = xfs_attr_leaf_try_add(args);
     445             : 
     446    47033737 :         if (error == -ENOSPC) {
     447       24559 :                 error = xfs_attr3_leaf_to_node(args);
     448       24559 :                 if (error)
     449             :                         return error;
     450             : 
     451             :                 /*
     452             :                  * We're not in leaf format anymore, so roll the transaction and
     453             :                  * retry the add to the newly allocated node block.
     454             :                  */
     455       24548 :                 attr->xattri_dela_state = XFS_DAS_NODE_ADD;
     456       24548 :                 goto out;
     457             :         }
     458    47009178 :         if (error)
     459             :                 return error;
     460             : 
     461             :         /*
     462             :          * We need to commit and roll if we need to allocate remote xattr blocks
     463             :          * or perform more xattr manipulations. Otherwise there is nothing more
     464             :          * to do and we can return success.
     465             :          */
     466    47009177 :         if (args->rmtblkno)
     467        2735 :                 attr->xattri_dela_state = XFS_DAS_LEAF_SET_RMT;
     468             :         else
     469    58024334 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     470             :                                                         XFS_DAS_LEAF_REPLACE);
     471    47033725 : out:
     472    47033725 :         trace_xfs_attr_leaf_addname_return(attr->xattri_dela_state, args->dp);
     473    47033725 :         return error;
     474             : }
     475             : 
     476             : /*
     477             :  * Add an entry to a node format attr tree.
     478             :  *
     479             :  * Note that we might still have a leaf here - xfs_attr_is_leaf() cannot tell
     480             :  * the difference between leaf + remote attr blocks and a node format tree,
     481             :  * so we may still end up having to convert from leaf to node format here.
     482             :  */
     483             : static int
     484     1274110 : xfs_attr_node_addname(
     485             :         struct xfs_attr_intent  *attr)
     486             : {
     487     1274110 :         struct xfs_da_args      *args = attr->xattri_da_args;
     488     1274110 :         int                     error;
     489             : 
     490     1274110 :         error = xfs_attr_node_addname_find_attr(attr);
     491     1274133 :         if (error)
     492             :                 return error;
     493             : 
     494     1274135 :         error = xfs_attr_node_try_addname(attr);
     495     1274053 :         if (error == -ENOSPC) {
     496           0 :                 error = xfs_attr3_leaf_to_node(args);
     497           0 :                 if (error)
     498             :                         return error;
     499             :                 /*
     500             :                  * No state change, we really are in node form now
     501             :                  * but we need the transaction rolled to continue.
     502             :                  */
     503           0 :                 goto out;
     504             :         }
     505     1274053 :         if (error)
     506             :                 return error;
     507             : 
     508     1274042 :         if (args->rmtblkno)
     509         101 :                 attr->xattri_dela_state = XFS_DAS_NODE_SET_RMT;
     510             :         else
     511     1495044 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     512             :                                                         XFS_DAS_NODE_REPLACE);
     513     1274042 : out:
     514     1274042 :         trace_xfs_attr_node_addname_return(attr->xattri_dela_state, args->dp);
     515     1274042 :         return error;
     516             : }
     517             : 
     518             : static int
     519        2836 : xfs_attr_rmtval_alloc(
     520             :         struct xfs_attr_intent          *attr)
     521             : {
     522        2836 :         struct xfs_da_args              *args = attr->xattri_da_args;
     523        2836 :         int                             error = 0;
     524             : 
     525             :         /*
     526             :          * If there was an out-of-line value, allocate the blocks we
     527             :          * identified for its storage and copy the value.  This is done
     528             :          * after we create the attribute so that we don't overflow the
     529             :          * maximum size of a transaction and/or hit a deadlock.
     530             :          */
     531        2836 :         if (attr->xattri_blkcnt > 0) {
     532        2836 :                 error = xfs_attr_rmtval_set_blk(attr);
     533        2836 :                 if (error)
     534             :                         return error;
     535             :                 /* Roll the transaction only if there is more to allocate. */
     536        2836 :                 if (attr->xattri_blkcnt > 0)
     537           0 :                         goto out;
     538             :         }
     539             : 
     540        2836 :         error = xfs_attr_rmtval_set_value(args);
     541        2836 :         if (error)
     542             :                 return error;
     543             : 
     544        5672 :         attr->xattri_dela_state = xfs_attr_complete_op(attr,
     545        2836 :                                                 ++attr->xattri_dela_state);
     546             :         /*
     547             :          * If we are not doing a rename, we've finished the operation but still
     548             :          * have to clear the incomplete flag protecting the new attr from
     549             :          * exposing partially initialised state if we crash during creation.
     550             :          */
     551        2836 :         if (attr->xattri_dela_state == XFS_DAS_DONE)
     552        2826 :                 error = xfs_attr3_leaf_clearflag(args);
     553          10 : out:
     554        2836 :         trace_xfs_attr_rmtval_alloc(attr->xattri_dela_state, args->dp);
     555        2836 :         return error;
     556             : }
     557             : 
     558             : /*
     559             :  * Mark an attribute entry INCOMPLETE and save pointers to the relevant buffers
     560             :  * for later deletion of the entry.
     561             :  */
     562             : static int
     563             : xfs_attr_leaf_mark_incomplete(
     564             :         struct xfs_da_args      *args,
     565             :         struct xfs_da_state     *state)
     566             : {
     567      382784 :         int                     error;
     568             : 
     569             :         /*
     570             :          * Fill in disk block numbers in the state structure
     571             :          * so that we can get the buffers back after we commit
     572             :          * several transactions in the following calls.
     573             :          */
     574      382784 :         error = xfs_attr_fillstate(state);
     575      382784 :         if (error)
     576             :                 return error;
     577             : 
     578             :         /*
     579             :          * Mark the attribute as INCOMPLETE
     580             :          */
     581      382784 :         return xfs_attr3_leaf_setflag(args);
     582             : }
     583             : 
     584             : /* Ensure the da state of an xattr deferred work item is ready to go. */
     585             : static inline void
     586     1656830 : xfs_attr_item_init_da_state(
     587             :         struct xfs_attr_intent  *attr)
     588             : {
     589     1656830 :         struct xfs_da_args      *args = attr->xattri_da_args;
     590             : 
     591     1656830 :         if (!attr->xattri_da_state)
     592     1654691 :                 attr->xattri_da_state = xfs_da_state_alloc(args);
     593             :         else
     594        2139 :                 xfs_da_state_reset(attr->xattri_da_state, args);
     595     1656894 : }
     596             : 
     597             : /*
     598             :  * Initial setup for xfs_attr_node_removename.  Make sure the attr is there and
     599             :  * the blocks are valid.  Attr keys with remote blocks will be marked
     600             :  * incomplete.
     601             :  */
     602             : static
     603      382807 : int xfs_attr_node_removename_setup(
     604             :         struct xfs_attr_intent          *attr)
     605             : {
     606      382807 :         struct xfs_da_args              *args = attr->xattri_da_args;
     607      382807 :         struct xfs_da_state             *state;
     608      382807 :         int                             error;
     609             : 
     610      382807 :         xfs_attr_item_init_da_state(attr);
     611      382808 :         error = xfs_attr_node_lookup(args, attr->xattri_da_state);
     612      382817 :         if (error != -EEXIST)
     613          33 :                 goto out;
     614      382784 :         error = 0;
     615             : 
     616      382784 :         state = attr->xattri_da_state;
     617      382784 :         ASSERT(state->path.blk[state->path.active - 1].bp != NULL);
     618      382784 :         ASSERT(state->path.blk[state->path.active - 1].magic ==
     619             :                 XFS_ATTR_LEAF_MAGIC);
     620             : 
     621      382784 :         error = xfs_attr_leaf_mark_incomplete(args, state);
     622      382777 :         if (error)
     623           0 :                 goto out;
     624      382777 :         if (args->rmtblkno > 0)
     625          68 :                 error = xfs_attr_rmtval_invalidate(args);
     626      382709 : out:
     627      382810 :         if (error) {
     628          33 :                 xfs_da_state_free(attr->xattri_da_state);
     629          33 :                 attr->xattri_da_state = NULL;
     630             :         }
     631             : 
     632      382810 :         return error;
     633             : }
     634             : 
     635             : /*
     636             :  * Remove the original attr we have just replaced. This is dependent on the
     637             :  * original lookup and insert placing the old attr in args->blkno/args->index
     638             :  * and the new attr in args->blkno2/args->index2.
     639             :  */
     640             : static int
     641    11016222 : xfs_attr_leaf_remove_attr(
     642             :         struct xfs_attr_intent          *attr)
     643             : {
     644    11016222 :         struct xfs_da_args              *args = attr->xattri_da_args;
     645    11016222 :         struct xfs_inode                *dp = args->dp;
     646    11016222 :         struct xfs_buf                  *bp = NULL;
     647    11016222 :         int                             forkoff;
     648    11016222 :         int                             error;
     649             : 
     650    11016222 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno,
     651             :                                    &bp);
     652    11017958 :         if (error)
     653             :                 return error;
     654             : 
     655    11017813 :         xfs_attr3_leaf_remove(bp, args);
     656             : 
     657    11021509 :         forkoff = xfs_attr_shortform_allfit(bp, dp);
     658    11019599 :         if (forkoff)
     659      258997 :                 error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
     660             :                 /* bp is gone due to xfs_da_shrink_inode */
     661             : 
     662             :         return error;
     663             : }
     664             : 
     665             : /*
     666             :  * Shrink an attribute from leaf to shortform. Used by the node format remove
     667             :  * path when the node format collapses to a single block and so we have to check
     668             :  * if it can be collapsed further.
     669             :  */
     670             : static int
     671      603876 : xfs_attr_leaf_shrink(
     672             :         struct xfs_da_args      *args)
     673             : {
     674      603876 :         struct xfs_inode        *dp = args->dp;
     675      603876 :         struct xfs_buf          *bp;
     676      603876 :         int                     forkoff;
     677      603876 :         int                     error;
     678             : 
     679      603876 :         if (!xfs_attr_is_leaf(dp))
     680             :                 return 0;
     681             : 
     682          85 :         error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp);
     683          85 :         if (error)
     684             :                 return error;
     685             : 
     686          85 :         forkoff = xfs_attr_shortform_allfit(bp, dp);
     687          85 :         if (forkoff) {
     688          56 :                 error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
     689             :                 /* bp is gone due to xfs_da_shrink_inode */
     690             :         } else {
     691          29 :                 xfs_trans_brelse(args->trans, bp);
     692             :         }
     693             : 
     694             :         return error;
     695             : }
     696             : 
     697             : /*
     698             :  * Run the attribute operation specified in @attr.
     699             :  *
     700             :  * This routine is meant to function as a delayed operation and will set the
     701             :  * state to XFS_DAS_DONE when the operation is complete.  Calling functions will
     702             :  * need to handle this, and recall the function until either an error or
     703             :  * XFS_DAS_DONE is detected.
     704             :  */
     705             : int
     706   118521376 : xfs_attr_set_iter(
     707             :         struct xfs_attr_intent          *attr)
     708             : {
     709   118521376 :         struct xfs_da_args              *args = attr->xattri_da_args;
     710   118521376 :         int                             error = 0;
     711             : 
     712             :         /* State machine switch */
     713             : next_state:
     714   129759065 :         switch (attr->xattri_dela_state) {
     715           0 :         case XFS_DAS_UNINIT:
     716           0 :                 ASSERT(0);
     717           0 :                 return -EFSCORRUPTED;
     718    24038189 :         case XFS_DAS_SF_ADD:
     719    24038189 :                 return xfs_attr_sf_addname(attr);
     720    47034933 :         case XFS_DAS_LEAF_ADD:
     721    47034933 :                 return xfs_attr_leaf_addname(attr);
     722     1274118 :         case XFS_DAS_NODE_ADD:
     723     1274118 :                 return xfs_attr_node_addname(attr);
     724             : 
     725     5432690 :         case XFS_DAS_SF_REMOVE:
     726     5432690 :                 error = xfs_attr_sf_removename(args);
     727     5433282 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     728             :                                                 xfs_attr_init_add_state(args));
     729     5432055 :                 break;
     730    17494010 :         case XFS_DAS_LEAF_REMOVE:
     731    17494010 :                 error = xfs_attr_leaf_removename(args);
     732    17494399 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     733             :                                                 xfs_attr_init_add_state(args));
     734    17481247 :                 break;
     735      382809 :         case XFS_DAS_NODE_REMOVE:
     736      382809 :                 error = xfs_attr_node_removename_setup(attr);
     737      382798 :                 if (error == -ENOATTR &&
     738          33 :                     (args->op_flags & XFS_DA_OP_RECOVERY)) {
     739          33 :                         attr->xattri_dela_state = xfs_attr_complete_op(attr,
     740             :                                                 xfs_attr_init_add_state(args));
     741          33 :                         error = 0;
     742          33 :                         break;
     743             :                 }
     744      382765 :                 if (error)
     745             :                         return error;
     746      382765 :                 attr->xattri_dela_state = XFS_DAS_NODE_REMOVE_RMT;
     747      382765 :                 if (args->rmtblkno == 0)
     748      382697 :                         attr->xattri_dela_state++;
     749             :                 break;
     750             : 
     751        2836 :         case XFS_DAS_LEAF_SET_RMT:
     752             :         case XFS_DAS_NODE_SET_RMT:
     753        2836 :                 error = xfs_attr_rmtval_find_space(attr);
     754        2836 :                 if (error)
     755           0 :                         return error;
     756        2836 :                 attr->xattri_dela_state++;
     757        2836 :                 fallthrough;
     758             : 
     759        2836 :         case XFS_DAS_LEAF_ALLOC_RMT:
     760             :         case XFS_DAS_NODE_ALLOC_RMT:
     761        2836 :                 error = xfs_attr_rmtval_alloc(attr);
     762        2836 :                 if (error)
     763           0 :                         return error;
     764        2836 :                 if (attr->xattri_dela_state == XFS_DAS_DONE)
     765             :                         break;
     766          10 :                 goto next_state;
     767             : 
     768    11238107 :         case XFS_DAS_LEAF_REPLACE:
     769             :         case XFS_DAS_NODE_REPLACE:
     770             :                 /*
     771             :                  * We must "flip" the incomplete flags on the "new" and "old"
     772             :                  * attribute/value pairs so that one disappears and one appears
     773             :                  * atomically.
     774             :                  */
     775    11238107 :                 error = xfs_attr3_leaf_flipflags(args);
     776    11238010 :                 if (error)
     777             :                         return error;
     778             :                 /*
     779             :                  * We must commit the flag value change now to make it atomic
     780             :                  * and then we can start the next trans in series at REMOVE_OLD.
     781             :                  */
     782    11238010 :                 attr->xattri_dela_state++;
     783    11238010 :                 break;
     784             : 
     785    11240817 :         case XFS_DAS_LEAF_REMOVE_OLD:
     786             :         case XFS_DAS_NODE_REMOVE_OLD:
     787             :                 /*
     788             :                  * If we have a remote attr, start the process of removing it
     789             :                  * by invalidating any cached buffers.
     790             :                  *
     791             :                  * If we don't have a remote attr, we skip the remote block
     792             :                  * removal state altogether with a second state increment.
     793             :                  */
     794    11240817 :                 xfs_attr_restore_rmt_blk(args);
     795    11237679 :                 if (args->rmtblkno) {
     796          20 :                         error = xfs_attr_rmtval_invalidate(args);
     797          20 :                         if (error)
     798           0 :                                 return error;
     799             :                 } else {
     800    11237659 :                         attr->xattri_dela_state++;
     801             :                 }
     802             : 
     803    11237679 :                 attr->xattri_dela_state++;
     804    11237679 :                 goto next_state;
     805             : 
     806          88 :         case XFS_DAS_LEAF_REMOVE_RMT:
     807             :         case XFS_DAS_NODE_REMOVE_RMT:
     808          88 :                 error = xfs_attr_rmtval_remove(attr);
     809          88 :                 if (error == -EAGAIN) {
     810             :                         error = 0;
     811             :                         break;
     812             :                 }
     813          88 :                 if (error)
     814             :                         return error;
     815             : 
     816             :                 /*
     817             :                  * We've finished removing the remote attr blocks, so commit the
     818             :                  * transaction and move on to removing the attr name from the
     819             :                  * leaf/node block. Removing the attr might require a full
     820             :                  * transaction reservation for btree block freeing, so we
     821             :                  * can't do that in the same transaction where we removed the
     822             :                  * remote attr blocks.
     823             :                  */
     824          88 :                 attr->xattri_dela_state++;
     825          88 :                 break;
     826             : 
     827    11016567 :         case XFS_DAS_LEAF_REMOVE_ATTR:
     828    11016567 :                 error = xfs_attr_leaf_remove_attr(attr);
     829    11018310 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     830             :                                                 xfs_attr_init_add_state(args));
     831    11018139 :                 break;
     832             : 
     833      603901 :         case XFS_DAS_NODE_REMOVE_ATTR:
     834      603901 :                 error = xfs_attr_node_remove_attr(attr);
     835      603901 :                 if (!error)
     836      603882 :                         error = xfs_attr_leaf_shrink(args);
     837      603888 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     838             :                                                 xfs_attr_init_add_state(args));
     839      603885 :                 break;
     840           0 :         default:
     841           0 :                 ASSERT(0);
     842           0 :                 break;
     843             :         }
     844             : 
     845    46159048 :         trace_xfs_attr_set_iter_return(attr->xattri_dela_state, args->dp);
     846    46159048 :         return error;
     847             : }
     848             : 
     849             : 
     850             : /*
     851             :  * Return EEXIST if attr is found, or ENOATTR if not
     852             :  */
     853             : static int
     854   124800974 : xfs_attr_lookup(
     855             :         struct xfs_da_args      *args)
     856             : {
     857   124800974 :         struct xfs_inode        *dp = args->dp;
     858   124800974 :         struct xfs_buf          *bp = NULL;
     859   124800974 :         struct xfs_da_state     *state;
     860   124800974 :         int                     error;
     861             : 
     862   124800974 :         if (!xfs_inode_hasattr(dp))
     863             :                 return -ENOATTR;
     864             : 
     865   107882434 :         if (dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
     866    29694406 :                 return xfs_attr_sf_findname(args, NULL, NULL);
     867             : 
     868    78188028 :         if (xfs_attr_is_leaf(dp)) {
     869    76334333 :                 error = xfs_attr_leaf_hasname(args, &bp);
     870             : 
     871    76349107 :                 if (bp)
     872    76349097 :                         xfs_trans_brelse(args->trans, bp);
     873             : 
     874    76400254 :                 return error;
     875             :         }
     876             : 
     877     1934068 :         state = xfs_da_state_alloc(args);
     878     1934104 :         error = xfs_attr_node_lookup(args, state);
     879     1934066 :         xfs_da_state_free(state);
     880     1934066 :         return error;
     881             : }
     882             : 
     883             : static int
     884             : xfs_attr_intent_init(
     885             :         struct xfs_da_args      *args,
     886             :         unsigned int            op_flags,       /* op flag (set or remove) */
     887             :         struct xfs_attr_intent  **attr)         /* new xfs_attr_intent */
     888             : {
     889             : 
     890    92576000 :         struct xfs_attr_intent  *new;
     891             : 
     892    92576000 :         new = kmem_cache_zalloc(xfs_attr_intent_cache, GFP_NOFS | __GFP_NOFAIL);
     893    92602194 :         new->xattri_op_flags = op_flags;
     894    92602194 :         new->xattri_da_args = args;
     895             : 
     896    92602194 :         *attr = new;
     897    92602194 :         return 0;
     898             : }
     899             : 
     900             : /* Sets an attribute for an inode as a deferred operation */
     901             : static int
     902    52683829 : xfs_attr_defer_add(
     903             :         struct xfs_da_args      *args)
     904             : {
     905    52683829 :         struct xfs_attr_intent  *new;
     906    52683829 :         int                     error = 0;
     907             : 
     908    52683829 :         error = xfs_attr_intent_init(args, XFS_ATTRI_OP_FLAGS_SET, &new);
     909    52705205 :         if (error)
     910             :                 return error;
     911             : 
     912    52705205 :         new->xattri_dela_state = xfs_attr_init_add_state(args);
     913    52688076 :         xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
     914    52670986 :         trace_xfs_attr_defer_add(new->xattri_dela_state, args->dp);
     915             : 
     916    52647248 :         return 0;
     917             : }
     918             : 
     919             : /* Sets an attribute for an inode as a deferred operation */
     920             : static int
     921    16833910 : xfs_attr_defer_replace(
     922             :         struct xfs_da_args      *args)
     923             : {
     924    16833910 :         struct xfs_attr_intent  *new;
     925    16833910 :         int                     error = 0;
     926             : 
     927    16833910 :         error = xfs_attr_intent_init(args, XFS_ATTRI_OP_FLAGS_REPLACE, &new);
     928    16834943 :         if (error)
     929             :                 return error;
     930             : 
     931    16834943 :         new->xattri_dela_state = xfs_attr_init_replace_state(args);
     932    16831706 :         xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
     933    16831109 :         trace_xfs_attr_defer_replace(new->xattri_dela_state, args->dp);
     934             : 
     935    16825855 :         return 0;
     936             : }
     937             : 
     938             : /* Removes an attribute for an inode as a deferred operation */
     939             : static int
     940    23058261 : xfs_attr_defer_remove(
     941             :         struct xfs_da_args      *args)
     942             : {
     943             : 
     944    23058261 :         struct xfs_attr_intent  *new;
     945    23058261 :         int                     error;
     946             : 
     947    23058261 :         error  = xfs_attr_intent_init(args, XFS_ATTRI_OP_FLAGS_REMOVE, &new);
     948    23062046 :         if (error)
     949             :                 return error;
     950             : 
     951    23062046 :         new->xattri_dela_state = xfs_attr_init_remove_state(args);
     952    23055954 :         xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
     953    23051785 :         trace_xfs_attr_defer_remove(new->xattri_dela_state, args->dp);
     954             : 
     955    23045874 :         return 0;
     956             : }
     957             : 
     958             : /*
     959             :  * Note: If args->value is NULL the attribute will be removed, just like the
     960             :  * Linux ->setattr API.
     961             :  */
     962             : int
     963   125001920 : xfs_attr_set(
     964             :         struct xfs_da_args      *args)
     965             : {
     966   125001920 :         struct xfs_inode        *dp = args->dp;
     967   125001920 :         struct xfs_mount        *mp = dp->i_mount;
     968   125001920 :         struct xfs_trans_res    tres;
     969   125001920 :         bool                    rsvd = (args->attr_filter & XFS_ATTR_ROOT);
     970   125001920 :         int                     error, local;
     971   125001920 :         int                     rmt_blks = 0;
     972   125001920 :         unsigned int            total;
     973             : 
     974   250003840 :         if (xfs_is_shutdown(dp->i_mount))
     975             :                 return -EIO;
     976             : 
     977   125000927 :         error = xfs_qm_dqattach(dp);
     978   124947472 :         if (error)
     979             :                 return error;
     980             : 
     981   124948112 :         args->geo = mp->m_attr_geo;
     982   124948112 :         args->whichfork = XFS_ATTR_FORK;
     983   124948112 :         args->hashval = xfs_da_hashname(args->name, args->namelen);
     984             : 
     985             :         /*
     986             :          * We have no control over the attribute names that userspace passes us
     987             :          * to remove, so we have to allow the name lookup prior to attribute
     988             :          * removal to fail as well.  Preserve the logged flag, since we need
     989             :          * to pass that through to the logging code.
     990             :          */
     991   124952476 :         args->op_flags = XFS_DA_OP_OKNOENT |
     992   124952476 :                                         (args->op_flags & XFS_DA_OP_LOGGED);
     993             : 
     994   124952476 :         if (args->value) {
     995    80054656 :                 XFS_STATS_INC(mp, xs_attr_set);
     996    80065790 :                 args->total = xfs_attr_calc_size(args, &local);
     997             : 
     998             :                 /*
     999             :                  * If the inode doesn't have an attribute fork, add one.
    1000             :                  * (inode must not be locked when we call this routine)
    1001             :                  */
    1002    80035502 :                 if (xfs_inode_has_attr_fork(dp) == 0) {
    1003     4776220 :                         int sf_size = sizeof(struct xfs_attr_sf_hdr) +
    1004     4776220 :                                 xfs_attr_sf_entsize_byname(args->namelen,
    1005     4776220 :                                                 args->valuelen);
    1006             : 
    1007     4776220 :                         error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
    1008     4776418 :                         if (error)
    1009             :                                 return error;
    1010             :                 }
    1011             : 
    1012    80016258 :                 if (!local)
    1013        3131 :                         rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
    1014             :         } else {
    1015    44897820 :                 XFS_STATS_INC(mp, xs_attr_remove);
    1016    44950592 :                 rmt_blks = xfs_attr3_rmt_blocks(mp, XFS_XATTR_SIZE_MAX);
    1017             :         }
    1018             : 
    1019             :         /*
    1020             :          * Root fork attributes can use reserved data blocks for this
    1021             :          * operation if necessary
    1022             :          */
    1023   124944126 :         xfs_init_attr_trans(args, &tres, &total);
    1024   124816008 :         error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
    1025   124810781 :         if (error)
    1026             :                 return error;
    1027             : 
    1028   124701430 :         if (args->value || xfs_inode_hasattr(dp)) {
    1029   112904464 :                 error = xfs_iext_count_may_overflow(dp, XFS_ATTR_FORK,
    1030   112904464 :                                 XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
    1031   112879751 :                 if (error == -EFBIG)
    1032          22 :                         error = xfs_iext_count_upgrade(args->trans, dp,
    1033          22 :                                         XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
    1034   112879751 :                 if (error)
    1035          22 :                         goto out_trans_cancel;
    1036             :         }
    1037             : 
    1038   124676695 :         error = xfs_attr_lookup(args);
    1039   125011427 :         switch (error) {
    1040    40040695 :         case -EEXIST:
    1041             :                 /* if no value, we are performing a remove operation */
    1042    40040695 :                 if (!args->value) {
    1043    23062920 :                         error = xfs_attr_defer_remove(args);
    1044    23062920 :                         break;
    1045             :                 }
    1046             :                 /* Pure create fails if the attr already exists */
    1047    16977775 :                 if (args->attr_flags & XATTR_CREATE)
    1048      142570 :                         goto out_trans_cancel;
    1049             : 
    1050    16835205 :                 error = xfs_attr_defer_replace(args);
    1051    16835205 :                 break;
    1052    84970702 :         case -ENOATTR:
    1053             :                 /* Can't remove what isn't there. */
    1054    84970702 :                 if (!args->value)
    1055    21930090 :                         goto out_trans_cancel;
    1056             : 
    1057             :                 /* Pure replace fails if no existing attr to replace. */
    1058    63040612 :                 if (args->attr_flags & XATTR_REPLACE)
    1059    10335634 :                         goto out_trans_cancel;
    1060             : 
    1061    52704978 :                 error = xfs_attr_defer_add(args);
    1062    52704978 :                 break;
    1063          30 :         default:
    1064          30 :                 goto out_trans_cancel;
    1065             :         }
    1066    92509487 :         if (error)
    1067           0 :                 goto out_trans_cancel;
    1068             : 
    1069             :         /*
    1070             :          * If this is a synchronous mount, make sure that the
    1071             :          * transaction goes to disk before returning to the user.
    1072             :          */
    1073    92509487 :         if (xfs_has_wsync(mp))
    1074           0 :                 xfs_trans_set_sync(args->trans);
    1075             : 
    1076    92509487 :         if (!(args->op_flags & XFS_DA_OP_NOTIME))
    1077    92415378 :                 xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
    1078             : 
    1079             :         /*
    1080             :          * Commit the last in the sequence of transactions.
    1081             :          */
    1082    92420853 :         xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
    1083    92562671 :         error = xfs_trans_commit(args->trans);
    1084   124917236 : out_unlock:
    1085   124917236 :         xfs_iunlock(dp, XFS_ILOCK_EXCL);
    1086   124917236 :         return error;
    1087             : 
    1088    32408346 : out_trans_cancel:
    1089    32408346 :         if (args->trans)
    1090    32400331 :                 xfs_trans_cancel(args->trans);
    1091    32405060 :         goto out_unlock;
    1092             : }
    1093             : 
    1094             : /*========================================================================
    1095             :  * External routines when attribute list is inside the inode
    1096             :  *========================================================================*/
    1097             : 
    1098             : static inline int xfs_attr_sf_totsize(struct xfs_inode *dp)
    1099             : {
    1100    24039124 :         struct xfs_attr_shortform *sf;
    1101             : 
    1102    24039124 :         sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data;
    1103    24039124 :         return be16_to_cpu(sf->hdr.totsize);
    1104             : }
    1105             : 
    1106             : /*
    1107             :  * Add a name to the shortform attribute list structure
    1108             :  * This is the external routine.
    1109             :  */
    1110             : static int
    1111    24030714 : xfs_attr_shortform_addname(
    1112             :         struct xfs_da_args      *args)
    1113             : {
    1114    24030714 :         int                     newsize, forkoff;
    1115    24030714 :         int                     error;
    1116             : 
    1117    24030714 :         trace_xfs_attr_sf_addname(args);
    1118             : 
    1119    24028435 :         error = xfs_attr_shortform_lookup(args);
    1120    24048175 :         switch (error) {
    1121    18708309 :         case -ENOATTR:
    1122    18708309 :                 if (args->op_flags & XFS_DA_OP_REPLACE)
    1123             :                         return error;
    1124             :                 break;
    1125     5339866 :         case -EEXIST:
    1126     5339866 :                 if (!(args->op_flags & XFS_DA_OP_REPLACE))
    1127             :                         return error;
    1128             : 
    1129     5339866 :                 error = xfs_attr_sf_removename(args);
    1130     5341375 :                 if (error)
    1131             :                         return error;
    1132             : 
    1133             :                 /*
    1134             :                  * Since we have removed the old attr, clear XFS_DA_OP_REPLACE
    1135             :                  * so that the new attr doesn't fit in shortform format, the
    1136             :                  * leaf format add routine won't trip over the attr not being
    1137             :                  * around.
    1138             :                  */
    1139     5341375 :                 args->op_flags &= ~XFS_DA_OP_REPLACE;
    1140     5341375 :                 break;
    1141             :         case 0:
    1142             :                 break;
    1143             :         default:
    1144             :                 return error;
    1145             :         }
    1146             : 
    1147    24049684 :         if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
    1148    24049684 :             args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
    1149             :                 return -ENOSPC;
    1150             : 
    1151    24039124 :         newsize = xfs_attr_sf_totsize(args->dp);
    1152    24039124 :         newsize += xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
    1153             : 
    1154    24039124 :         forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
    1155    24038118 :         if (!forkoff)
    1156             :                 return -ENOSPC;
    1157             : 
    1158    21204351 :         xfs_attr_shortform_add(args, forkoff);
    1159    21204351 :         return 0;
    1160             : }
    1161             : 
    1162             : 
    1163             : /*========================================================================
    1164             :  * External routines when attribute list is one block
    1165             :  *========================================================================*/
    1166             : 
    1167             : /* Save the current remote block info and clear the current pointers. */
    1168             : static void
    1169             : xfs_attr_save_rmt_blk(
    1170             :         struct xfs_da_args      *args)
    1171             : {
    1172    11244166 :         args->blkno2 = args->blkno;
    1173    11244166 :         args->index2 = args->index;
    1174    11244166 :         args->rmtblkno2 = args->rmtblkno;
    1175    11244166 :         args->rmtblkcnt2 = args->rmtblkcnt;
    1176    11244166 :         args->rmtvaluelen2 = args->rmtvaluelen;
    1177    11244166 :         args->rmtblkno = 0;
    1178    11244166 :         args->rmtblkcnt = 0;
    1179    11244166 :         args->rmtvaluelen = 0;
    1180    11244166 : }
    1181             : 
    1182             : /* Set stored info about a remote block */
    1183             : static void
    1184    11240801 : xfs_attr_restore_rmt_blk(
    1185             :         struct xfs_da_args      *args)
    1186             : {
    1187    11240801 :         args->blkno = args->blkno2;
    1188    11240801 :         args->index = args->index2;
    1189    11240801 :         args->rmtblkno = args->rmtblkno2;
    1190    11240801 :         args->rmtblkcnt = args->rmtblkcnt2;
    1191    11240801 :         args->rmtvaluelen = args->rmtvaluelen2;
    1192    11240801 : }
    1193             : 
    1194             : /*
    1195             :  * Tries to add an attribute to an inode in leaf form
    1196             :  *
    1197             :  * This function is meant to execute as part of a delayed operation and leaves
    1198             :  * the transaction handling to the caller.  On success the attribute is added
    1199             :  * and the inode and transaction are left dirty.  If there is not enough space,
    1200             :  * the attr data is converted to node format and -ENOSPC is returned. Caller is
    1201             :  * responsible for handling the dirty inode and transaction or adding the attr
    1202             :  * in node format.
    1203             :  */
    1204             : STATIC int
    1205    47054174 : xfs_attr_leaf_try_add(
    1206             :         struct xfs_da_args      *args)
    1207             : {
    1208    47054174 :         struct xfs_buf          *bp;
    1209    47054174 :         int                     error;
    1210             : 
    1211    47054174 :         error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp);
    1212    47070351 :         if (error)
    1213             :                 return error;
    1214             : 
    1215             :         /*
    1216             :          * Look up the xattr name to set the insertion point for the new xattr.
    1217             :          */
    1218    47070715 :         error = xfs_attr3_leaf_lookup_int(bp, args);
    1219    47090338 :         switch (error) {
    1220    36064179 :         case -ENOATTR:
    1221    36064179 :                 if (args->op_flags & XFS_DA_OP_REPLACE)
    1222           0 :                         goto out_brelse;
    1223             :                 break;
    1224    11026159 :         case -EEXIST:
    1225    11026159 :                 if (!(args->op_flags & XFS_DA_OP_REPLACE))
    1226           0 :                         goto out_brelse;
    1227             : 
    1228    11026159 :                 trace_xfs_attr_leaf_replace(args);
    1229             :                 /*
    1230             :                  * Save the existing remote attr state so that the current
    1231             :                  * values reflect the state of the new attribute we are about to
    1232             :                  * add, not the attribute we just found and will remove later.
    1233             :                  */
    1234    11023048 :                 xfs_attr_save_rmt_blk(args);
    1235             :                 break;
    1236             :         case 0:
    1237             :                 break;
    1238           0 :         default:
    1239           0 :                 goto out_brelse;
    1240             :         }
    1241             : 
    1242    47087227 :         return xfs_attr3_leaf_add(bp, args);
    1243             : 
    1244           0 : out_brelse:
    1245           0 :         xfs_trans_brelse(args->trans, bp);
    1246           0 :         return error;
    1247             : }
    1248             : 
    1249             : /*
    1250             :  * Return EEXIST if attr is found, or ENOATTR if not
    1251             :  */
    1252             : STATIC int
    1253   103124391 : xfs_attr_leaf_hasname(
    1254             :         struct xfs_da_args      *args,
    1255             :         struct xfs_buf          **bp)
    1256             : {
    1257   103124391 :         int                     error = 0;
    1258             : 
    1259   103124391 :         error = xfs_attr3_leaf_read(args->trans, args->dp, 0, bp);
    1260   103065519 :         if (error)
    1261             :                 return error;
    1262             : 
    1263   103067215 :         error = xfs_attr3_leaf_lookup_int(*bp, args);
    1264   103129675 :         if (error != -ENOATTR && error != -EEXIST)
    1265           0 :                 xfs_trans_brelse(args->trans, *bp);
    1266             : 
    1267             :         return error;
    1268             : }
    1269             : 
    1270             : /*
    1271             :  * Remove a name from the leaf attribute list structure
    1272             :  *
    1273             :  * This leaf block cannot have a "remote" value, we only call this routine
    1274             :  * if bmap_one_block() says there is only one block (ie: no remote blks).
    1275             :  */
    1276             : STATIC int
    1277    17482500 : xfs_attr_leaf_removename(
    1278             :         struct xfs_da_args      *args)
    1279             : {
    1280    17482500 :         struct xfs_inode        *dp;
    1281    17482500 :         struct xfs_buf          *bp;
    1282    17482500 :         int                     error, forkoff;
    1283             : 
    1284    17482500 :         trace_xfs_attr_leaf_removename(args);
    1285             : 
    1286             :         /*
    1287             :          * Remove the attribute.
    1288             :          */
    1289    17473788 :         dp = args->dp;
    1290             : 
    1291    17473788 :         error = xfs_attr_leaf_hasname(args, &bp);
    1292    17501627 :         if (error == -ENOATTR) {
    1293          33 :                 xfs_trans_brelse(args->trans, bp);
    1294          33 :                 if (args->op_flags & XFS_DA_OP_RECOVERY)
    1295             :                         return 0;
    1296           0 :                 return error;
    1297    17501594 :         } else if (error != -EEXIST)
    1298             :                 return error;
    1299             : 
    1300    17501005 :         xfs_attr3_leaf_remove(bp, args);
    1301             : 
    1302             :         /*
    1303             :          * If the result is small enough, shrink it all into the inode.
    1304             :          */
    1305    17498369 :         forkoff = xfs_attr_shortform_allfit(bp, dp);
    1306    17495287 :         if (forkoff)
    1307     1160981 :                 return xfs_attr3_leaf_to_shortform(bp, args, forkoff);
    1308             :                 /* bp is gone due to xfs_da_shrink_inode */
    1309             : 
    1310             :         return 0;
    1311             : }
    1312             : 
    1313             : /*
    1314             :  * Look up a name in a leaf attribute list structure.
    1315             :  *
    1316             :  * This leaf block cannot have a "remote" value, we only call this routine
    1317             :  * if bmap_one_block() says there is only one block (ie: no remote blks).
    1318             :  *
    1319             :  * Returns 0 on successful retrieval, otherwise an error.
    1320             :  */
    1321             : STATIC int
    1322     9332393 : xfs_attr_leaf_get(xfs_da_args_t *args)
    1323             : {
    1324     9332393 :         struct xfs_buf *bp;
    1325     9332393 :         int error;
    1326             : 
    1327     9332393 :         trace_xfs_attr_leaf_get(args);
    1328             : 
    1329     9331900 :         error = xfs_attr_leaf_hasname(args, &bp);
    1330             : 
    1331     9332874 :         if (error == -ENOATTR)  {
    1332     3777366 :                 xfs_trans_brelse(args->trans, bp);
    1333     3777366 :                 return error;
    1334     5555508 :         } else if (error != -EEXIST)
    1335             :                 return error;
    1336             : 
    1337             : 
    1338     5555290 :         error = xfs_attr3_leaf_getvalue(bp, args);
    1339     5554958 :         xfs_trans_brelse(args->trans, bp);
    1340     5554958 :         return error;
    1341             : }
    1342             : 
    1343             : /* Return EEXIST if attr is found, or ENOATTR if not. */
    1344             : STATIC int
    1345     3816744 : xfs_attr_node_lookup(
    1346             :         struct xfs_da_args      *args,
    1347             :         struct xfs_da_state     *state)
    1348             : {
    1349     3816744 :         int                     retval, error;
    1350             : 
    1351             :         /*
    1352             :          * Search to see if name exists, and get back a pointer to it.
    1353             :          */
    1354     3816744 :         error = xfs_da3_node_lookup_int(state, &retval);
    1355     3816797 :         if (error)
    1356             :                 return error;
    1357             : 
    1358     3816777 :         return retval;
    1359             : }
    1360             : 
    1361             : /*========================================================================
    1362             :  * External routines when attribute list size > geo->blksize
    1363             :  *========================================================================*/
    1364             : 
    1365             : STATIC int
    1366     1274081 : xfs_attr_node_addname_find_attr(
    1367             :          struct xfs_attr_intent *attr)
    1368             : {
    1369     1274081 :         struct xfs_da_args      *args = attr->xattri_da_args;
    1370     1274081 :         int                     error;
    1371             : 
    1372             :         /*
    1373             :          * Search to see if name already exists, and get back a pointer
    1374             :          * to where it should go.
    1375             :          */
    1376     1274081 :         xfs_attr_item_init_da_state(attr);
    1377     1274100 :         error = xfs_attr_node_lookup(args, attr->xattri_da_state);
    1378     1274145 :         switch (error) {
    1379     1053025 :         case -ENOATTR:
    1380     1053025 :                 if (args->op_flags & XFS_DA_OP_REPLACE)
    1381           0 :                         goto error;
    1382             :                 break;
    1383      221120 :         case -EEXIST:
    1384      221120 :                 if (!(args->op_flags & XFS_DA_OP_REPLACE))
    1385           0 :                         goto error;
    1386             : 
    1387             : 
    1388      221120 :                 trace_xfs_attr_node_replace(args);
    1389             :                 /*
    1390             :                  * Save the existing remote attr state so that the current
    1391             :                  * values reflect the state of the new attribute we are about to
    1392             :                  * add, not the attribute we just found and will remove later.
    1393             :                  */
    1394      221118 :                 xfs_attr_save_rmt_blk(args);
    1395             :                 break;
    1396             :         case 0:
    1397             :                 break;
    1398           0 :         default:
    1399           0 :                 goto error;
    1400             :         }
    1401             : 
    1402             :         return 0;
    1403           0 : error:
    1404           0 :         if (attr->xattri_da_state) {
    1405           0 :                 xfs_da_state_free(attr->xattri_da_state);
    1406           0 :                 attr->xattri_da_state = NULL;
    1407             :         }
    1408             :         return error;
    1409             : }
    1410             : 
    1411             : /*
    1412             :  * Add a name to a Btree-format attribute list.
    1413             :  *
    1414             :  * This will involve walking down the Btree, and may involve splitting
    1415             :  * leaf nodes and even splitting intermediate nodes up to and including
    1416             :  * the root node (a special case of an intermediate node).
    1417             :  */
    1418             : static int
    1419     1274102 : xfs_attr_node_try_addname(
    1420             :         struct xfs_attr_intent          *attr)
    1421             : {
    1422     1274102 :         struct xfs_da_state             *state = attr->xattri_da_state;
    1423     1274102 :         struct xfs_da_state_blk         *blk;
    1424     1274102 :         int                             error;
    1425             : 
    1426     1274102 :         trace_xfs_attr_node_addname(state->args);
    1427             : 
    1428     1274077 :         blk = &state->path.blk[state->path.active-1];
    1429     1274076 :         ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
    1430             : 
    1431     1274076 :         error = xfs_attr3_leaf_add(blk->bp, state->args);
    1432     1274113 :         if (error == -ENOSPC) {
    1433       88864 :                 if (state->path.active == 1) {
    1434             :                         /*
    1435             :                          * Its really a single leaf node, but it had
    1436             :                          * out-of-line values so it looked like it *might*
    1437             :                          * have been a b-tree. Let the caller deal with this.
    1438             :                          */
    1439           0 :                         goto out;
    1440             :                 }
    1441             : 
    1442             :                 /*
    1443             :                  * Split as many Btree elements as required.
    1444             :                  * This code tracks the new and old attr's location
    1445             :                  * in the index/blkno/rmtblkno/rmtblkcnt fields and
    1446             :                  * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields.
    1447             :                  */
    1448       88864 :                 error = xfs_da3_split(state);
    1449       88864 :                 if (error)
    1450          11 :                         goto out;
    1451             :         } else {
    1452             :                 /*
    1453             :                  * Addition succeeded, update Btree hashvals.
    1454             :                  */
    1455     1185249 :                 xfs_da3_fixhashpath(state, &state->path);
    1456             :         }
    1457             : 
    1458     1274134 : out:
    1459     1274134 :         xfs_da_state_free(state);
    1460     1274116 :         attr->xattri_da_state = NULL;
    1461     1274116 :         return error;
    1462             : }
    1463             : 
    1464             : static int
    1465      603892 : xfs_attr_node_removename(
    1466             :         struct xfs_da_args      *args,
    1467             :         struct xfs_da_state     *state)
    1468             : {
    1469      603892 :         struct xfs_da_state_blk *blk;
    1470      603892 :         int                     retval;
    1471             : 
    1472             :         /*
    1473             :          * Remove the name and update the hashvals in the tree.
    1474             :          */
    1475      603892 :         blk = &state->path.blk[state->path.active-1];
    1476      603892 :         ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
    1477      603892 :         retval = xfs_attr3_leaf_remove(blk->bp, args);
    1478      603897 :         xfs_da3_fixhashpath(state, &state->path);
    1479             : 
    1480      603894 :         return retval;
    1481             : }
    1482             : 
    1483             : static int
    1484      603890 : xfs_attr_node_remove_attr(
    1485             :         struct xfs_attr_intent          *attr)
    1486             : {
    1487      603890 :         struct xfs_da_args              *args = attr->xattri_da_args;
    1488      603890 :         struct xfs_da_state             *state = xfs_da_state_alloc(args);
    1489      603910 :         int                             retval = 0;
    1490      603910 :         int                             error = 0;
    1491             : 
    1492             :         /*
    1493             :          * The attr we are removing has already been marked incomplete, so
    1494             :          * we need to set the filter appropriately to re-find the "old"
    1495             :          * attribute entry after any split ops.
    1496             :          */
    1497      603910 :         args->attr_filter |= XFS_ATTR_INCOMPLETE;
    1498      603910 :         error = xfs_da3_node_lookup_int(state, &retval);
    1499      603900 :         if (error)
    1500           0 :                 goto out;
    1501             : 
    1502      603900 :         error = xfs_attr_node_removename(args, state);
    1503             : 
    1504             :         /*
    1505             :          * Check to see if the tree needs to be collapsed.
    1506             :          */
    1507      603886 :         if (retval && (state->path.active > 1)) {
    1508      603788 :                 error = xfs_da3_join(state);
    1509      603784 :                 if (error)
    1510          10 :                         goto out;
    1511             :         }
    1512      603872 :         retval = error = 0;
    1513             : 
    1514      603882 : out:
    1515      603882 :         xfs_da_state_free(state);
    1516      603896 :         if (error)
    1517             :                 return error;
    1518      603886 :         return retval;
    1519             : }
    1520             : 
    1521             : /*
    1522             :  * Retrieve the attribute data from a node attribute list.
    1523             :  *
    1524             :  * This routine gets called for any attribute fork that has more than one
    1525             :  * block, ie: both true Btree attr lists and for single-leaf-blocks with
    1526             :  * "remote" values taking up more blocks.
    1527             :  *
    1528             :  * Returns 0 on successful retrieval, otherwise an error.
    1529             :  */
    1530             : STATIC int
    1531      225812 : xfs_attr_node_get(
    1532             :         struct xfs_da_args      *args)
    1533             : {
    1534      225812 :         struct xfs_da_state     *state;
    1535      225812 :         struct xfs_da_state_blk *blk;
    1536      225812 :         int                     i;
    1537      225812 :         int                     error;
    1538             : 
    1539      225812 :         trace_xfs_attr_node_get(args);
    1540             : 
    1541             :         /*
    1542             :          * Search to see if name exists, and get back a pointer to it.
    1543             :          */
    1544      225810 :         state = xfs_da_state_alloc(args);
    1545      225812 :         error = xfs_attr_node_lookup(args, state);
    1546      225812 :         if (error != -EEXIST)
    1547       74829 :                 goto out_release;
    1548             : 
    1549             :         /*
    1550             :          * Get the value, local or "remote"
    1551             :          */
    1552      150983 :         blk = &state->path.blk[state->path.active - 1];
    1553      150982 :         error = xfs_attr3_leaf_getvalue(blk->bp, args);
    1554             : 
    1555             :         /*
    1556             :          * If not in a transaction, we have to release all the buffers.
    1557             :          */
    1558      225811 : out_release:
    1559      676375 :         for (i = 0; i < state->path.active; i++) {
    1560      450563 :                 xfs_trans_brelse(args->trans, state->path.blk[i].bp);
    1561      450565 :                 state->path.blk[i].bp = NULL;
    1562             :         }
    1563             : 
    1564      225812 :         xfs_da_state_free(state);
    1565      225813 :         return error;
    1566             : }
    1567             : 
    1568             : /* Returns true if the attribute entry name is valid. */
    1569             : bool
    1570   681164078 : xfs_attr_namecheck(
    1571             :         const void      *name,
    1572             :         size_t          length)
    1573             : {
    1574             :         /*
    1575             :          * MAXNAMELEN includes the trailing null, but (name/length) leave it
    1576             :          * out, so use >= for the length check.
    1577             :          */
    1578   681164078 :         if (length >= MAXNAMELEN)
    1579             :                 return false;
    1580             : 
    1581             :         /* There shouldn't be any nulls here */
    1582  1362328156 :         return !memchr(name, 0, length);
    1583             : }
    1584             : 
    1585             : int __init
    1586          50 : xfs_attr_intent_init_cache(void)
    1587             : {
    1588          50 :         xfs_attr_intent_cache = kmem_cache_create("xfs_attr_intent",
    1589             :                         sizeof(struct xfs_attr_intent),
    1590             :                         0, 0, NULL);
    1591             : 
    1592          50 :         return xfs_attr_intent_cache != NULL ? 0 : -ENOMEM;
    1593             : }
    1594             : 
    1595             : void
    1596          49 : xfs_attr_intent_destroy_cache(void)
    1597             : {
    1598          49 :         kmem_cache_destroy(xfs_attr_intent_cache);
    1599          49 :         xfs_attr_intent_cache = NULL;
    1600          49 : }

Generated by: LCOV version 1.14