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-acha @ Mon Jul 31 20:08:06 PDT 2023 Lines: 581 618 94.0 %
Date: 2023-07-31 20:08:07 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  2579979311 : xfs_inode_hasattr(
      69             :         struct xfs_inode        *ip)
      70             : {
      71  2631918085 :         if (!xfs_inode_has_attr_fork(ip))
      72             :                 return 0;
      73  2968630306 :         if (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
      74   251533902 :             ip->i_af.if_nextents == 0)
      75    22534582 :                 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   403809731 : xfs_attr_is_leaf(
      85             :         struct xfs_inode        *ip)
      86             : {
      87   403809731 :         struct xfs_ifork        *ifp = &ip->i_af;
      88   403809731 :         struct xfs_iext_cursor  icur;
      89   403809731 :         struct xfs_bmbt_irec    imap;
      90             : 
      91   403809731 :         if (ifp->if_nextents != 1 || ifp->if_format != XFS_DINODE_FMT_EXTENTS)
      92             :                 return false;
      93             : 
      94   396175096 :         xfs_iext_first(ifp, &icur);
      95   396207933 :         xfs_iext_get_extent(ifp, &icur, &imap);
      96   396384997 :         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   171303429 : xfs_attr_get_ilocked(
     226             :         struct xfs_da_args      *args)
     227             : {
     228   171303429 :         ASSERT(xfs_isilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
     229             : 
     230   171297309 :         if (!xfs_inode_hasattr(args->dp))
     231             :                 return -ENOATTR;
     232             : 
     233   171270255 :         if (args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
     234   154741486 :                 return xfs_attr_shortform_getvalue(args);
     235    16528769 :         if (xfs_attr_is_leaf(args->dp))
     236    16077496 :                 return xfs_attr_leaf_get(args);
     237      450587 :         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    48599384 : xfs_attr_get(
     258             :         struct xfs_da_args      *args)
     259             : {
     260    48599384 :         uint                    lock_mode;
     261    48599384 :         int                     error;
     262             : 
     263    48599384 :         XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
     264             : 
     265    97198768 :         if (xfs_is_shutdown(args->dp->i_mount))
     266             :                 return -EIO;
     267             : 
     268    48598546 :         args->geo = args->dp->i_mount->m_attr_geo;
     269    48598546 :         args->whichfork = XFS_ATTR_FORK;
     270    48598546 :         args->hashval = xfs_da_hashname(args->name, args->namelen);
     271             : 
     272             :         /* Entirely possible to look up a name which doesn't exist */
     273    48597085 :         args->op_flags = XFS_DA_OP_OKNOENT;
     274             : 
     275    48597085 :         lock_mode = xfs_ilock_attr_map_shared(args->dp);
     276    48596492 :         error = xfs_attr_get_ilocked(args);
     277    48595611 :         xfs_iunlock(args->dp, lock_mode);
     278             : 
     279    48595611 :         return error;
     280             : }
     281             : 
     282             : /*
     283             :  * Calculate how many blocks we need for the new attribute,
     284             :  */
     285             : int
     286   113654109 : xfs_attr_calc_size(
     287             :         struct xfs_da_args      *args,
     288             :         int                     *local)
     289             : {
     290   113654109 :         struct xfs_mount        *mp = args->dp->i_mount;
     291   113654109 :         int                     size;
     292   113654109 :         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   113654109 :         size = xfs_attr_leaf_newentsize(args, local);
     299   113658638 :         nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
     300   113658638 :         if (*local) {
     301   113657981 :                 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         657 :                 uint    dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
     311         657 :                 nblks += dblocks;
     312         657 :                 nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
     313             :         }
     314             : 
     315   113658638 :         return nblks;
     316             : }
     317             : 
     318             : /* Initialize transaction reservation for attr operations */
     319             : void
     320   165605534 : xfs_init_attr_trans(
     321             :         struct xfs_da_args      *args,
     322             :         struct xfs_trans_res    *tres,
     323             :         unsigned int            *total)
     324             : {
     325   165605534 :         struct xfs_mount        *mp = args->dp->i_mount;
     326             : 
     327   165605534 :         if (args->value) {
     328   113651420 :                 tres->tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
     329   113651420 :                                  M_RES(mp)->tr_attrsetrt.tr_logres *
     330   113651420 :                                  args->total;
     331   113651420 :                 tres->tr_logcount = XFS_ATTRSET_LOG_COUNT;
     332   113651420 :                 tres->tr_logflags = XFS_TRANS_PERM_LOG_RES;
     333   113651420 :                 *total = args->total;
     334             :         } else {
     335    51954114 :                 *tres = M_RES(mp)->tr_attrrm;
     336    51954114 :                 *total = XFS_ATTRRM_SPACE_RES(mp);
     337             :         }
     338   165605534 : }
     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   131249080 : xfs_attr_try_sf_addname(
     347             :         struct xfs_inode        *dp,
     348             :         struct xfs_da_args      *args)
     349             : {
     350             : 
     351   131249080 :         int                     error;
     352             : 
     353             :         /*
     354             :          * Build initial attribute list (if required).
     355             :          */
     356   131249080 :         if (dp->i_af.if_format == XFS_DINODE_FMT_EXTENTS)
     357    60502032 :                 xfs_attr_shortform_create(args);
     358             : 
     359   131250721 :         error = xfs_attr_shortform_addname(args);
     360   131249137 :         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   126986460 :         if (!error && !(args->op_flags & XFS_DA_OP_NOTIME))
     368   126989997 :                 xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
     369             : 
     370   126984611 :         if (xfs_has_wsync(dp->i_mount))
     371         236 :                 xfs_trans_set_sync(args->trans);
     372             : 
     373             :         return error;
     374             : }
     375             : 
     376             : static int
     377   131248145 : xfs_attr_sf_addname(
     378             :         struct xfs_attr_intent          *attr)
     379             : {
     380   131248145 :         struct xfs_da_args              *args = attr->xattri_da_args;
     381   131248145 :         struct xfs_inode                *dp = args->dp;
     382   131248145 :         int                             error = 0;
     383             : 
     384   131248145 :         error = xfs_attr_try_sf_addname(dp, args);
     385   131253299 :         if (error != -ENOSPC) {
     386   126990603 :                 ASSERT(!error || error == -EEXIST);
     387   126990603 :                 attr->xattri_dela_state = XFS_DAS_DONE;
     388   126990603 :                 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     4262696 :         error = xfs_attr_shortform_to_leaf(args);
     396     4262651 :         if (error)
     397             :                 return error;
     398             : 
     399     4262649 :         attr->xattri_dela_state = XFS_DAS_LEAF_ADD;
     400   131253252 : out:
     401   131253252 :         trace_xfs_attr_sf_addname_return(attr->xattri_dela_state, args->dp);
     402   131253252 :         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   204240555 : xfs_attr_complete_op(
     418             :         struct xfs_attr_intent  *attr,
     419             :         enum xfs_delattr_state  replace_state)
     420             : {
     421   204240555 :         struct xfs_da_args      *args = attr->xattri_da_args;
     422   204240555 :         bool                    do_replace = args->op_flags & XFS_DA_OP_REPLACE;
     423             : 
     424   204240555 :         args->op_flags &= ~XFS_DA_OP_REPLACE;
     425   204240555 :         if (!do_replace)
     426             :                 return XFS_DAS_DONE;
     427             : 
     428    54814124 :         args->attr_filter &= ~XFS_ATTR_INCOMPLETE;
     429    54814124 :         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    37416947 :         ASSERT(args->new_namelen > 0);
     437             : 
     438    37416947 :         args->name = args->new_name;
     439    37416947 :         args->namelen = args->new_namelen;
     440    37416947 :         args->hashval = xfs_da_hashname(args->name, args->namelen);
     441    37416944 :         args->value = args->new_value;
     442    37416944 :         args->valuelen = args->new_valuelen;
     443    37416944 :         return replace_state;
     444             : }
     445             : 
     446             : static int
     447    73244563 : xfs_attr_leaf_addname(
     448             :         struct xfs_attr_intent  *attr)
     449             : {
     450    73244563 :         struct xfs_da_args      *args = attr->xattri_da_args;
     451    73244563 :         int                     error;
     452             : 
     453    73244563 :         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    73247282 :         error = xfs_attr_leaf_try_add(args);
     460             : 
     461    73248373 :         if (error == -ENOSPC) {
     462       38363 :                 error = xfs_attr3_leaf_to_node(args);
     463       38363 :                 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       38361 :                 attr->xattri_dela_state = XFS_DAS_NODE_ADD;
     471       38361 :                 goto out;
     472             :         }
     473    73210010 :         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    73210010 :         if (args->rmtblkno)
     482         523 :                 attr->xattri_dela_state = XFS_DAS_LEAF_SET_RMT;
     483             :         else
     484    73209487 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     485             :                                                         XFS_DAS_LEAF_REPLACE);
     486    73251792 : out:
     487    73251792 :         trace_xfs_attr_leaf_addname_return(attr->xattri_dela_state, args->dp);
     488    73251792 :         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     1601972 : xfs_attr_node_addname(
     500             :         struct xfs_attr_intent  *attr)
     501             : {
     502     1601972 :         struct xfs_da_args      *args = attr->xattri_da_args;
     503     1601972 :         int                     error;
     504             : 
     505     1601972 :         error = xfs_attr_node_addname_find_attr(attr);
     506     1601983 :         if (error)
     507             :                 return error;
     508             : 
     509     1601976 :         error = xfs_attr_node_try_addname(attr);
     510     1601984 :         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     1601984 :         if (error)
     521             :                 return error;
     522             : 
     523     1601982 :         if (args->rmtblkno)
     524           4 :                 attr->xattri_dela_state = XFS_DAS_NODE_SET_RMT;
     525             :         else
     526     1601978 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     527             :                                                         XFS_DAS_NODE_REPLACE);
     528     1601979 : out:
     529     1601979 :         trace_xfs_attr_node_addname_return(attr->xattri_dela_state, args->dp);
     530     1601979 :         return error;
     531             : }
     532             : 
     533             : static int
     534         527 : xfs_attr_rmtval_alloc(
     535             :         struct xfs_attr_intent          *attr)
     536             : {
     537         527 :         struct xfs_da_args              *args = attr->xattri_da_args;
     538         527 :         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         527 :         if (attr->xattri_blkcnt > 0) {
     547         527 :                 error = xfs_attr_rmtval_set_blk(attr);
     548         527 :                 if (error)
     549             :                         return error;
     550             :                 /* Roll the transaction only if there is more to allocate. */
     551         527 :                 if (attr->xattri_blkcnt > 0)
     552           0 :                         goto out;
     553             :         }
     554             : 
     555         527 :         error = xfs_attr_rmtval_set_value(args);
     556         527 :         if (error)
     557             :                 return error;
     558             : 
     559        1054 :         attr->xattri_dela_state = xfs_attr_complete_op(attr,
     560         527 :                                                 ++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         527 :         if (attr->xattri_dela_state == XFS_DAS_DONE)
     567         525 :                 error = xfs_attr3_leaf_clearflag(args);
     568           2 : out:
     569         527 :         trace_xfs_attr_rmtval_alloc(attr->xattri_dela_state, args->dp);
     570         527 :         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      600437 :         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      600437 :         error = xfs_attr_fillstate(state);
     590      600437 :         if (error)
     591             :                 return error;
     592             : 
     593             :         /*
     594             :          * Mark the attribute as INCOMPLETE
     595             :          */
     596      600437 :         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     2202417 : xfs_attr_item_init_da_state(
     602             :         struct xfs_attr_intent  *attr)
     603             : {
     604     2202417 :         struct xfs_da_args      *args = attr->xattri_da_args;
     605             : 
     606     2202417 :         if (!attr->xattri_da_state)
     607     2190272 :                 attr->xattri_da_state = xfs_da_state_alloc(args);
     608             :         else
     609       12145 :                 xfs_da_state_reset(attr->xattri_da_state, args);
     610     2202422 : }
     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      600443 : int xfs_attr_node_removename_setup(
     619             :         struct xfs_attr_intent          *attr)
     620             : {
     621      600443 :         struct xfs_da_args              *args = attr->xattri_da_args;
     622      600443 :         struct xfs_da_state             *state;
     623      600443 :         int                             error;
     624             : 
     625      600443 :         xfs_attr_item_init_da_state(attr);
     626      600443 :         error = xfs_attr_node_lookup(args, attr->xattri_da_state);
     627      600443 :         if (error != -EEXIST)
     628           6 :                 goto out;
     629      600437 :         error = 0;
     630             : 
     631      600437 :         state = attr->xattri_da_state;
     632      600437 :         ASSERT(state->path.blk[state->path.active - 1].bp != NULL);
     633      600437 :         ASSERT(state->path.blk[state->path.active - 1].magic ==
     634             :                 XFS_ATTR_LEAF_MAGIC);
     635             : 
     636      600437 :         error = xfs_attr_leaf_mark_incomplete(args, state);
     637      600437 :         if (error)
     638           0 :                 goto out;
     639      600437 :         if (args->rmtblkno > 0)
     640          12 :                 error = xfs_attr_rmtval_invalidate(args);
     641      600425 : out:
     642      600443 :         if (error) {
     643           6 :                 xfs_da_state_free(attr->xattri_da_state);
     644           6 :                 attr->xattri_da_state = NULL;
     645             :         }
     646             : 
     647      600443 :         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    17050029 : xfs_attr_leaf_remove_attr(
     657             :         struct xfs_attr_intent          *attr)
     658             : {
     659    17050029 :         struct xfs_da_args              *args = attr->xattri_da_args;
     660    17050029 :         struct xfs_inode                *dp = args->dp;
     661    17050029 :         struct xfs_buf                  *bp = NULL;
     662    17050029 :         int                             forkoff;
     663    17050029 :         int                             error;
     664             : 
     665    17050029 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
     666             :                         args->blkno, &bp);
     667    17049902 :         if (error)
     668             :                 return error;
     669             : 
     670    17050242 :         xfs_attr3_leaf_remove(bp, args);
     671             : 
     672    17050352 :         forkoff = xfs_attr_shortform_allfit(bp, dp);
     673    17050317 :         if (forkoff)
     674      388711 :                 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      947430 : xfs_attr_leaf_shrink(
     687             :         struct xfs_da_args      *args)
     688             : {
     689      947430 :         struct xfs_inode        *dp = args->dp;
     690      947430 :         struct xfs_buf          *bp;
     691      947430 :         int                     forkoff;
     692      947430 :         int                     error;
     693             : 
     694      947430 :         if (!xfs_attr_is_leaf(dp))
     695             :                 return 0;
     696             : 
     697          35 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
     698          35 :         if (error)
     699             :                 return error;
     700             : 
     701          35 :         forkoff = xfs_attr_shortform_allfit(bp, dp);
     702          35 :         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          25 :                 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   353531552 : xfs_attr_set_iter(
     722             :         struct xfs_attr_intent          *attr)
     723             : {
     724   353531552 :         struct xfs_da_args              *args = attr->xattri_da_args;
     725   353531552 :         int                             error = 0;
     726             : 
     727             :         /* State machine switch */
     728             : next_state:
     729   370928964 :         switch (attr->xattri_dela_state) {
     730           0 :         case XFS_DAS_UNINIT:
     731           0 :                 ASSERT(0);
     732           0 :                 return -EFSCORRUPTED;
     733   131246055 :         case XFS_DAS_SF_ADD:
     734   131246055 :                 return xfs_attr_sf_addname(attr);
     735    73242030 :         case XFS_DAS_LEAF_ADD:
     736    73242030 :                 return xfs_attr_leaf_addname(attr);
     737     1601962 :         case XFS_DAS_NODE_ADD:
     738     1601962 :                 return xfs_attr_node_addname(attr);
     739             : 
     740    82992333 :         case XFS_DAS_SF_REMOVE:
     741    82992333 :                 error = xfs_attr_sf_removename(args);
     742    82992550 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     743             :                                                 xfs_attr_init_add_state(args));
     744    82993093 :                 break;
     745    28454227 :         case XFS_DAS_LEAF_REMOVE:
     746    28454227 :                 error = xfs_attr_leaf_removename(args);
     747    28453341 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     748             :                                                 xfs_attr_init_add_state(args));
     749    28454206 :                 break;
     750      600443 :         case XFS_DAS_NODE_REMOVE:
     751      600443 :                 error = xfs_attr_node_removename_setup(attr);
     752      600443 :                 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      600437 :                 if (error)
     760             :                         return error;
     761      600437 :                 attr->xattri_dela_state = XFS_DAS_NODE_REMOVE_RMT;
     762      600437 :                 if (args->rmtblkno == 0)
     763      600425 :                         attr->xattri_dela_state++;
     764             :                 break;
     765             : 
     766         527 :         case XFS_DAS_LEAF_SET_RMT:
     767             :         case XFS_DAS_NODE_SET_RMT:
     768         527 :                 error = xfs_attr_rmtval_find_space(attr);
     769         527 :                 if (error)
     770           0 :                         return error;
     771         527 :                 attr->xattri_dela_state++;
     772         527 :                 fallthrough;
     773             : 
     774         527 :         case XFS_DAS_LEAF_ALLOC_RMT:
     775             :         case XFS_DAS_NODE_ALLOC_RMT:
     776         527 :                 error = xfs_attr_rmtval_alloc(attr);
     777         527 :                 if (error)
     778           0 :                         return error;
     779         527 :                 if (attr->xattri_dela_state == XFS_DAS_DONE)
     780             :                         break;
     781           2 :                 goto next_state;
     782             : 
     783    17396713 :         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    17396713 :                 error = xfs_attr3_leaf_flipflags(args);
     791    17396890 :                 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    17396890 :                 attr->xattri_dela_state++;
     798    17396890 :                 break;
     799             : 
     800    17397309 :         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    17397309 :                 xfs_attr_restore_rmt_blk(args);
     810    17397410 :                 if (args->rmtblkno) {
     811           4 :                         error = xfs_attr_rmtval_invalidate(args);
     812           4 :                         if (error)
     813           0 :                                 return error;
     814             :                 } else {
     815    17397406 :                         attr->xattri_dela_state++;
     816             :                 }
     817             : 
     818    17397410 :                 attr->xattri_dela_state++;
     819    17397410 :                 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    17049910 :         case XFS_DAS_LEAF_REMOVE_ATTR:
     843    17049910 :                 error = xfs_attr_leaf_remove_attr(attr);
     844    17049926 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     845             :                                                 xfs_attr_init_add_state(args));
     846    17050320 :                 break;
     847             : 
     848      947439 :         case XFS_DAS_NODE_REMOVE_ATTR:
     849      947439 :                 error = xfs_attr_node_remove_attr(attr);
     850      947439 :                 if (!error)
     851      947430 :                         error = xfs_attr_leaf_shrink(args);
     852      947446 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     853             :                                                 xfs_attr_init_add_state(args));
     854      947438 :                 break;
     855           0 :         default:
     856           0 :                 ASSERT(0);
     857           0 :                 break;
     858             :         }
     859             : 
     860   147442931 :         trace_xfs_attr_set_iter_return(attr->xattri_dela_state, args->dp);
     861   147442931 :         return error;
     862             : }
     863             : 
     864             : 
     865             : /*
     866             :  * Return EEXIST if attr is found, or ENOATTR if not
     867             :  */
     868             : static int
     869   165548062 : xfs_attr_lookup(
     870             :         struct xfs_da_args      *args)
     871             : {
     872   165548062 :         struct xfs_inode        *dp = args->dp;
     873   165548062 :         struct xfs_buf          *bp = NULL;
     874   165548062 :         struct xfs_da_state     *state;
     875   165548062 :         int                     error;
     876             : 
     877   165548062 :         if (!xfs_inode_hasattr(dp))
     878             :                 return -ENOATTR;
     879             : 
     880   165332693 :         if (dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
     881    45574482 :                 return xfs_attr_sf_findname(args, NULL, NULL);
     882             : 
     883   119758211 :         if (xfs_attr_is_leaf(dp)) {
     884   117184415 :                 error = xfs_attr_leaf_hasname(args, &bp);
     885             : 
     886   117195524 :                 if (bp)
     887   117195522 :                         xfs_trans_brelse(args->trans, bp);
     888             : 
     889   117211236 :                 return error;
     890             :         }
     891             : 
     892     2555697 :         state = xfs_da_state_alloc(args);
     893     2555702 :         error = xfs_attr_node_lookup(args, state);
     894     2555687 :         xfs_da_state_free(state);
     895     2555687 :         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   276416452 :         struct xfs_attr_intent  *new;
     906             : 
     907           0 :         new = kmem_cache_zalloc(xfs_attr_intent_cache, GFP_NOFS | __GFP_NOFAIL);
     908   276420772 :         new->xattri_op_flags = op_flags;
     909   276420772 :         new->xattri_da_args = args;
     910             : 
     911   276420772 :         *attr = new;
     912   276420772 :         return 0;
     913             : }
     914             : 
     915             : /* Sets an attribute for an inode as a deferred operation */
     916             : int
     917   140316861 : xfs_attr_defer_add(
     918             :         struct xfs_da_args      *args)
     919             : {
     920   140316861 :         struct xfs_attr_intent  *new;
     921   140316861 :         int                     op_flag = XFS_ATTRI_OP_FLAGS_SET;
     922   140316861 :         int                     error = 0;
     923             : 
     924   140316861 :         if (args->op_flags & XFS_DA_OP_NVLOOKUP)
     925    66287415 :                 op_flag = XFS_ATTRI_OP_FLAGS_NVSET;
     926             : 
     927   140316861 :         error = xfs_attr_intent_init(args, op_flag, &new);
     928   140320991 :         if (error)
     929             :                 return error;
     930             : 
     931   140320991 :         new->xattri_dela_state = xfs_attr_init_add_state(args);
     932   140316801 :         xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
     933   140318448 :         trace_xfs_attr_defer_add(new->xattri_dela_state, args->dp);
     934             : 
     935   140325232 :         return 0;
     936             : }
     937             : 
     938             : /* Sets an attribute for an inode as a deferred operation */
     939             : int
     940    61472817 : xfs_attr_defer_replace(
     941             :         struct xfs_da_args      *args)
     942             : {
     943    61472817 :         struct xfs_attr_intent  *new;
     944    61472817 :         int                     op_flag = XFS_ATTRI_OP_FLAGS_REPLACE;
     945    61472817 :         int                     error = 0;
     946             : 
     947    61472817 :         if (args->op_flags & XFS_DA_OP_NVLOOKUP)
     948    37416936 :                 op_flag = XFS_ATTRI_OP_FLAGS_NVREPLACE;
     949             : 
     950    61472817 :         error = xfs_attr_intent_init(args, op_flag, &new);
     951    61473782 :         if (error)
     952             :                 return error;
     953             : 
     954    61473782 :         new->xattri_dela_state = xfs_attr_init_replace_state(args);
     955    61473485 :         xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
     956    61473664 :         trace_xfs_attr_defer_replace(new->xattri_dela_state, args->dp);
     957             : 
     958    61473578 :         return 0;
     959             : }
     960             : 
     961             : /* Removes an attribute for an inode as a deferred operation */
     962             : int
     963    74626774 : xfs_attr_defer_remove(
     964             :         struct xfs_da_args      *args)
     965             : {
     966             : 
     967    74626774 :         struct xfs_attr_intent  *new;
     968    74626774 :         int                     op_flag = XFS_ATTRI_OP_FLAGS_REMOVE;
     969    74626774 :         int                     error;
     970             : 
     971    74626774 :         if (args->op_flags & XFS_DA_OP_NVLOOKUP)
     972    41084224 :                 op_flag = XFS_ATTRI_OP_FLAGS_NVREMOVE;
     973             : 
     974    74626774 :         error  = xfs_attr_intent_init(args, op_flag, &new);
     975    74625999 :         if (error)
     976             :                 return error;
     977             : 
     978    74625999 :         new->xattri_dela_state = xfs_attr_init_remove_state(args);
     979    74627691 :         xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
     980    74627260 :         trace_xfs_attr_defer_remove(new->xattri_dela_state, args->dp);
     981             : 
     982    74627121 :         return 0;
     983             : }
     984             : 
     985             : /*
     986             :  * Note: If args->value is NULL the attribute will be removed, just like the
     987             :  * Linux ->setattr API.
     988             :  */
     989             : int
     990   165570872 : xfs_attr_set(
     991             :         struct xfs_da_args      *args)
     992             : {
     993   165570872 :         struct xfs_inode        *dp = args->dp;
     994   165570872 :         struct xfs_mount        *mp = dp->i_mount;
     995   165570872 :         struct xfs_trans_res    tres;
     996   165570872 :         bool                    rsvd = (args->attr_filter & (XFS_ATTR_ROOT |
     997             :                                                              XFS_ATTR_PARENT));
     998   165570872 :         bool                    is_remove = args->op_flags & XFS_DA_OP_REMOVE;
     999   165570872 :         int                     error, local;
    1000   165570872 :         int                     rmt_blks = 0;
    1001   165570872 :         unsigned int            total;
    1002             : 
    1003   331141744 :         if (xfs_is_shutdown(dp->i_mount))
    1004             :                 return -EIO;
    1005             : 
    1006   165570668 :         error = xfs_qm_dqattach(dp);
    1007   165597700 :         if (error)
    1008             :                 return error;
    1009             : 
    1010   165607159 :         args->geo = mp->m_attr_geo;
    1011   165607159 :         args->whichfork = XFS_ATTR_FORK;
    1012   165607159 :         args->hashval = xfs_da_hashname(args->name, args->namelen);
    1013             : 
    1014             :         /*
    1015             :          * We have no control over the attribute names that userspace passes us
    1016             :          * to remove, so we have to allow the name lookup prior to attribute
    1017             :          * removal to fail as well.  Preserve the logged and vlookup flags,
    1018             :          * since we need to pass them through to the lower levels.
    1019             :          */
    1020   165609294 :         args->op_flags &= (XFS_DA_OP_LOGGED | XFS_DA_OP_NVLOOKUP);
    1021   165609294 :         args->op_flags |= XFS_DA_OP_OKNOENT;
    1022             : 
    1023   165609294 :         if (!is_remove) {
    1024   113655729 :                 XFS_STATS_INC(mp, xs_attr_set);
    1025   113655729 :                 args->total = xfs_attr_calc_size(args, &local);
    1026             : 
    1027             :                 /*
    1028             :                  * If the inode doesn't have an attribute fork, add one.
    1029             :                  * (inode must not be locked when we call this routine)
    1030             :                  */
    1031   113654487 :                 if (xfs_inode_has_attr_fork(dp) == 0) {
    1032      197182 :                         int sf_size = sizeof(struct xfs_attr_sf_hdr) +
    1033      197182 :                                 xfs_attr_sf_entsize_byname(args->namelen,
    1034      197182 :                                                 args->valuelen);
    1035             : 
    1036      197182 :                         error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
    1037      197185 :                         if (error)
    1038             :                                 return error;
    1039             :                 }
    1040             : 
    1041   113654490 :                 if (!local)
    1042         647 :                         rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
    1043             :         } else {
    1044    51953565 :                 XFS_STATS_INC(mp, xs_attr_remove);
    1045    51953565 :                 rmt_blks = xfs_attr3_rmt_blocks(mp, XFS_XATTR_SIZE_MAX);
    1046             :         }
    1047             : 
    1048             :         /*
    1049             :          * Root fork attributes can use reserved data blocks for this
    1050             :          * operation if necessary
    1051             :          */
    1052   165607883 :         xfs_init_attr_trans(args, &tres, &total);
    1053   165588336 :         error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
    1054   165613614 :         if (error)
    1055             :                 return error;
    1056             : 
    1057   165552841 :         if (!is_remove || xfs_inode_hasattr(dp)) {
    1058   165543194 :                 error = xfs_iext_count_may_overflow(dp, XFS_ATTR_FORK,
    1059   165543194 :                                 XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
    1060   165541574 :                 if (error == -EFBIG)
    1061           4 :                         error = xfs_iext_count_upgrade(args->trans, dp,
    1062           4 :                                         XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
    1063   165541574 :                 if (error)
    1064           4 :                         goto out_trans_cancel;
    1065             :         }
    1066             : 
    1067   165551217 :         error = xfs_attr_lookup(args);
    1068   165539402 :         switch (error) {
    1069    57822057 :         case -EEXIST:
    1070             :                 /* if no value, we are performing a remove operation */
    1071    57822057 :                 if (is_remove) {
    1072    33542981 :                         error = xfs_attr_defer_remove(args);
    1073    33542981 :                         break;
    1074             :                 }
    1075             :                 /* Pure create fails if the attr already exists */
    1076    24279076 :                 if (args->attr_flags & XATTR_CREATE)
    1077      222858 :                         goto out_trans_cancel;
    1078             : 
    1079    24056218 :                 error = xfs_attr_defer_replace(args);
    1080    24056218 :                 break;
    1081   107717239 :         case -ENOATTR:
    1082             :                 /* Can't remove what isn't there. */
    1083   107717239 :                 if (is_remove)
    1084    18392523 :                         goto out_trans_cancel;
    1085             : 
    1086             :                 /* Pure replace fails if no existing attr to replace. */
    1087    89324716 :                 if (args->attr_flags & XATTR_REPLACE)
    1088    15050671 :                         goto out_trans_cancel;
    1089             : 
    1090    74274045 :                 error = xfs_attr_defer_add(args);
    1091    74274045 :                 break;
    1092         106 :         default:
    1093         106 :                 goto out_trans_cancel;
    1094             :         }
    1095   131888686 :         if (error)
    1096           0 :                 goto out_trans_cancel;
    1097             : 
    1098             :         /*
    1099             :          * If this is a synchronous mount, make sure that the
    1100             :          * transaction goes to disk before returning to the user.
    1101             :          */
    1102   131888686 :         if (xfs_has_wsync(mp))
    1103           0 :                 xfs_trans_set_sync(args->trans);
    1104             : 
    1105   131888686 :         if (!(args->op_flags & XFS_DA_OP_NOTIME))
    1106   131867567 :                 xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
    1107             : 
    1108             :         /*
    1109             :          * Commit the last in the sequence of transactions.
    1110             :          */
    1111   131899278 :         xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
    1112   131891458 :         error = xfs_trans_commit(args->trans);
    1113   165557654 : out_unlock:
    1114   165557654 :         xfs_iunlock(dp, XFS_ILOCK_EXCL);
    1115   165557654 :         return error;
    1116             : 
    1117    33666162 : out_trans_cancel:
    1118    33666162 :         if (args->trans)
    1119    33665536 :                 xfs_trans_cancel(args->trans);
    1120    33667536 :         goto out_unlock;
    1121             : }
    1122             : 
    1123             : /*========================================================================
    1124             :  * External routines when attribute list is inside the inode
    1125             :  *========================================================================*/
    1126             : 
    1127      156159 : int xfs_attr_sf_totsize(struct xfs_inode *dp)
    1128             : {
    1129   131403564 :         struct xfs_attr_shortform *sf;
    1130             : 
    1131   131403564 :         sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data;
    1132   131403564 :         return be16_to_cpu(sf->hdr.totsize);
    1133             : }
    1134             : 
    1135             : /*
    1136             :  * Add a name to the shortform attribute list structure
    1137             :  * This is the external routine.
    1138             :  */
    1139             : static int
    1140   131248584 : xfs_attr_shortform_addname(
    1141             :         struct xfs_da_args      *args)
    1142             : {
    1143   131248584 :         int                     newsize, forkoff;
    1144   131248584 :         int                     error;
    1145             : 
    1146   131248584 :         trace_xfs_attr_sf_addname(args);
    1147             : 
    1148   131252001 :         error = xfs_attr_shortform_lookup(args);
    1149   131249343 :         switch (error) {
    1150   124591388 :         case -ENOATTR:
    1151   124591388 :                 if (args->op_flags & XFS_DA_OP_REPLACE)
    1152             :                         return error;
    1153             :                 break;
    1154     6660271 :         case -EEXIST:
    1155     6660271 :                 if (!(args->op_flags & XFS_DA_OP_REPLACE))
    1156             :                         return error;
    1157             : 
    1158     6660271 :                 error = xfs_attr_sf_removename(args);
    1159     6660333 :                 if (error)
    1160             :                         return error;
    1161             : 
    1162             :                 /*
    1163             :                  * Since we have removed the old attr, clear XFS_DA_OP_REPLACE
    1164             :                  * so that the new attr doesn't fit in shortform format, the
    1165             :                  * leaf format add routine won't trip over the attr not being
    1166             :                  * around.
    1167             :                  */
    1168     6660333 :                 args->op_flags &= ~XFS_DA_OP_REPLACE;
    1169     6660333 :                 break;
    1170             :         case 0:
    1171             :                 break;
    1172             :         default:
    1173             :                 return error;
    1174             :         }
    1175             : 
    1176   131249405 :         if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
    1177   131249405 :             args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
    1178             :                 return -ENOSPC;
    1179             : 
    1180   131247405 :         newsize = xfs_attr_sf_totsize(args->dp);
    1181   131247405 :         newsize += xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
    1182             : 
    1183   131247405 :         forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
    1184   131247990 :         if (!forkoff)
    1185             :                 return -ENOSPC;
    1186             : 
    1187   126987289 :         xfs_attr_shortform_add(args, forkoff);
    1188   126987289 :         return 0;
    1189             : }
    1190             : 
    1191             : 
    1192             : /*========================================================================
    1193             :  * External routines when attribute list is one block
    1194             :  *========================================================================*/
    1195             : 
    1196             : /* Save the current remote block info and clear the current pointers. */
    1197             : static void
    1198             : xfs_attr_save_rmt_blk(
    1199             :         struct xfs_da_args      *args)
    1200             : {
    1201    17406518 :         args->blkno2 = args->blkno;
    1202    17406518 :         args->index2 = args->index;
    1203    17406518 :         args->rmtblkno2 = args->rmtblkno;
    1204    17406518 :         args->rmtblkcnt2 = args->rmtblkcnt;
    1205    17406518 :         args->rmtvaluelen2 = args->rmtvaluelen;
    1206    17406518 :         args->rmtblkno = 0;
    1207    17406518 :         args->rmtblkcnt = 0;
    1208    17406518 :         args->rmtvaluelen = 0;
    1209    17406518 : }
    1210             : 
    1211             : /* Set stored info about a remote block */
    1212             : static void
    1213    17396964 : xfs_attr_restore_rmt_blk(
    1214             :         struct xfs_da_args      *args)
    1215             : {
    1216    17396964 :         args->blkno = args->blkno2;
    1217    17396964 :         args->index = args->index2;
    1218    17396964 :         args->rmtblkno = args->rmtblkno2;
    1219    17396964 :         args->rmtblkcnt = args->rmtblkcnt2;
    1220    17396964 :         args->rmtvaluelen = args->rmtvaluelen2;
    1221    17396964 : }
    1222             : 
    1223             : /*
    1224             :  * Tries to add an attribute to an inode in leaf form
    1225             :  *
    1226             :  * This function is meant to execute as part of a delayed operation and leaves
    1227             :  * the transaction handling to the caller.  On success the attribute is added
    1228             :  * and the inode and transaction are left dirty.  If there is not enough space,
    1229             :  * the attr data is converted to node format and -ENOSPC is returned. Caller is
    1230             :  * responsible for handling the dirty inode and transaction or adding the attr
    1231             :  * in node format.
    1232             :  */
    1233             : STATIC int
    1234    73243131 : xfs_attr_leaf_try_add(
    1235             :         struct xfs_da_args      *args)
    1236             : {
    1237    73243131 :         struct xfs_buf          *bp;
    1238    73243131 :         int                     error;
    1239             : 
    1240    73243131 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
    1241    73252721 :         if (error)
    1242             :                 return error;
    1243             : 
    1244             :         /*
    1245             :          * Look up the xattr name to set the insertion point for the new xattr.
    1246             :          */
    1247    73253062 :         error = xfs_attr3_leaf_lookup_int(bp, args);
    1248    73251488 :         switch (error) {
    1249    56192654 :         case -ENOATTR:
    1250    56192654 :                 if (args->op_flags & XFS_DA_OP_REPLACE)
    1251           0 :                         goto out_brelse;
    1252             :                 break;
    1253    17058834 :         case -EEXIST:
    1254    17058834 :                 if (!(args->op_flags & XFS_DA_OP_REPLACE))
    1255           0 :                         goto out_brelse;
    1256             : 
    1257    17058834 :                 trace_xfs_attr_leaf_replace(args);
    1258             :                 /*
    1259             :                  * Save the existing remote attr state so that the current
    1260             :                  * values reflect the state of the new attribute we are about to
    1261             :                  * add, not the attribute we just found and will remove later.
    1262             :                  */
    1263    17059516 :                 xfs_attr_save_rmt_blk(args);
    1264             :                 break;
    1265             :         case 0:
    1266             :                 break;
    1267           0 :         default:
    1268           0 :                 goto out_brelse;
    1269             :         }
    1270             : 
    1271    73252170 :         return xfs_attr3_leaf_add(bp, args);
    1272             : 
    1273           0 : out_brelse:
    1274           0 :         xfs_trans_brelse(args->trans, bp);
    1275           0 :         return error;
    1276             : }
    1277             : 
    1278             : /*
    1279             :  * Return EEXIST if attr is found, or ENOATTR if not
    1280             :  */
    1281             : STATIC int
    1282   161652206 : xfs_attr_leaf_hasname(
    1283             :         struct xfs_da_args      *args,
    1284             :         struct xfs_buf          **bp)
    1285             : {
    1286   161652206 :         int                     error = 0;
    1287             : 
    1288   161652206 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, bp);
    1289   161595611 :         if (error)
    1290             :                 return error;
    1291             : 
    1292   161598804 :         error = xfs_attr3_leaf_lookup_int(*bp, args);
    1293   161691070 :         if (error != -ENOATTR && error != -EEXIST)
    1294           0 :                 xfs_trans_brelse(args->trans, *bp);
    1295             : 
    1296             :         return error;
    1297             : }
    1298             : 
    1299             : /*
    1300             :  * Remove a name from the leaf attribute list structure
    1301             :  *
    1302             :  * This leaf block cannot have a "remote" value, we only call this routine
    1303             :  * if bmap_one_block() says there is only one block (ie: no remote blks).
    1304             :  */
    1305             : STATIC int
    1306    28452981 : xfs_attr_leaf_removename(
    1307             :         struct xfs_da_args      *args)
    1308             : {
    1309    28452981 :         struct xfs_inode        *dp;
    1310    28452981 :         struct xfs_buf          *bp;
    1311    28452981 :         int                     error, forkoff;
    1312             : 
    1313    28452981 :         trace_xfs_attr_leaf_removename(args);
    1314             : 
    1315             :         /*
    1316             :          * Remove the attribute.
    1317             :          */
    1318    28454629 :         dp = args->dp;
    1319             : 
    1320    28454629 :         error = xfs_attr_leaf_hasname(args, &bp);
    1321    28453485 :         if (error == -ENOATTR) {
    1322           6 :                 xfs_trans_brelse(args->trans, bp);
    1323           6 :                 if (args->op_flags & XFS_DA_OP_RECOVERY)
    1324             :                         return 0;
    1325           0 :                 return error;
    1326    28453479 :         } else if (error != -EEXIST)
    1327             :                 return error;
    1328             : 
    1329    28454915 :         xfs_attr3_leaf_remove(bp, args);
    1330             : 
    1331             :         /*
    1332             :          * If the result is small enough, shrink it all into the inode.
    1333             :          */
    1334    28454578 :         forkoff = xfs_attr_shortform_allfit(bp, dp);
    1335    28454357 :         if (forkoff)
    1336     1854555 :                 return xfs_attr3_leaf_to_shortform(bp, args, forkoff);
    1337             :                 /* bp is gone due to xfs_da_shrink_inode */
    1338             : 
    1339             :         return 0;
    1340             : }
    1341             : 
    1342             : /*
    1343             :  * Look up a name in a leaf attribute list structure.
    1344             :  *
    1345             :  * This leaf block cannot have a "remote" value, we only call this routine
    1346             :  * if bmap_one_block() says there is only one block (ie: no remote blks).
    1347             :  *
    1348             :  * Returns 0 on successful retrieval, otherwise an error.
    1349             :  */
    1350             : STATIC int
    1351    16077361 : xfs_attr_leaf_get(xfs_da_args_t *args)
    1352             : {
    1353    16077361 :         struct xfs_buf *bp;
    1354    16077361 :         int error;
    1355             : 
    1356    16077361 :         trace_xfs_attr_leaf_get(args);
    1357             : 
    1358    16077737 :         error = xfs_attr_leaf_hasname(args, &bp);
    1359             : 
    1360    16077833 :         if (error == -ENOATTR)  {
    1361     5852714 :                 xfs_trans_brelse(args->trans, bp);
    1362     5852714 :                 return error;
    1363    10225119 :         } else if (error != -EEXIST)
    1364             :                 return error;
    1365             : 
    1366             : 
    1367    10225111 :         error = xfs_attr3_leaf_getvalue(bp, args);
    1368    10224935 :         xfs_trans_brelse(args->trans, bp);
    1369    10224935 :         return error;
    1370             : }
    1371             : 
    1372             : /* Return EEXIST if attr is found, or ENOATTR if not. */
    1373             : STATIC int
    1374     5208638 : xfs_attr_node_lookup(
    1375             :         struct xfs_da_args      *args,
    1376             :         struct xfs_da_state     *state)
    1377             : {
    1378     5208638 :         int                     retval, error;
    1379             : 
    1380             :         /*
    1381             :          * Search to see if name exists, and get back a pointer to it.
    1382             :          */
    1383     5208638 :         error = xfs_da3_node_lookup_int(state, &retval);
    1384     5208658 :         if (error)
    1385             :                 return error;
    1386             : 
    1387     5208454 :         return retval;
    1388             : }
    1389             : 
    1390             : /*========================================================================
    1391             :  * External routines when attribute list size > geo->blksize
    1392             :  *========================================================================*/
    1393             : 
    1394             : STATIC int
    1395     1601980 : xfs_attr_node_addname_find_attr(
    1396             :          struct xfs_attr_intent *attr)
    1397             : {
    1398     1601980 :         struct xfs_da_args      *args = attr->xattri_da_args;
    1399     1601980 :         int                     error;
    1400             : 
    1401             :         /*
    1402             :          * Search to see if name already exists, and get back a pointer
    1403             :          * to where it should go.
    1404             :          */
    1405     1601980 :         xfs_attr_item_init_da_state(attr);
    1406     1601981 :         error = xfs_attr_node_lookup(args, attr->xattri_da_state);
    1407     1601985 :         switch (error) {
    1408     1254983 :         case -ENOATTR:
    1409     1254983 :                 if (args->op_flags & XFS_DA_OP_REPLACE)
    1410           0 :                         goto error;
    1411             :                 break;
    1412      347002 :         case -EEXIST:
    1413      347002 :                 if (!(args->op_flags & XFS_DA_OP_REPLACE))
    1414           0 :                         goto error;
    1415             : 
    1416             : 
    1417      347002 :                 trace_xfs_attr_node_replace(args);
    1418             :                 /*
    1419             :                  * Save the existing remote attr state so that the current
    1420             :                  * values reflect the state of the new attribute we are about to
    1421             :                  * add, not the attribute we just found and will remove later.
    1422             :                  */
    1423      347002 :                 xfs_attr_save_rmt_blk(args);
    1424             :                 break;
    1425             :         case 0:
    1426             :                 break;
    1427           0 :         default:
    1428           0 :                 goto error;
    1429             :         }
    1430             : 
    1431             :         return 0;
    1432           0 : error:
    1433           0 :         if (attr->xattri_da_state) {
    1434           0 :                 xfs_da_state_free(attr->xattri_da_state);
    1435           0 :                 attr->xattri_da_state = NULL;
    1436             :         }
    1437             :         return error;
    1438             : }
    1439             : 
    1440             : /*
    1441             :  * Add a name to a Btree-format attribute list.
    1442             :  *
    1443             :  * This will involve walking down the Btree, and may involve splitting
    1444             :  * leaf nodes and even splitting intermediate nodes up to and including
    1445             :  * the root node (a special case of an intermediate node).
    1446             :  */
    1447             : static int
    1448     1601974 : xfs_attr_node_try_addname(
    1449             :         struct xfs_attr_intent          *attr)
    1450             : {
    1451     1601974 :         struct xfs_da_state             *state = attr->xattri_da_state;
    1452     1601974 :         struct xfs_da_state_blk         *blk;
    1453     1601974 :         int                             error;
    1454             : 
    1455     1601974 :         trace_xfs_attr_node_addname(state->args);
    1456             : 
    1457     1601982 :         blk = &state->path.blk[state->path.active-1];
    1458     1601982 :         ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
    1459             : 
    1460     1601982 :         error = xfs_attr3_leaf_add(blk->bp, state->args);
    1461     1601980 :         if (error == -ENOSPC) {
    1462       60325 :                 if (state->path.active == 1) {
    1463             :                         /*
    1464             :                          * Its really a single leaf node, but it had
    1465             :                          * out-of-line values so it looked like it *might*
    1466             :                          * have been a b-tree. Let the caller deal with this.
    1467             :                          */
    1468           0 :                         goto out;
    1469             :                 }
    1470             : 
    1471             :                 /*
    1472             :                  * Split as many Btree elements as required.
    1473             :                  * This code tracks the new and old attr's location
    1474             :                  * in the index/blkno/rmtblkno/rmtblkcnt fields and
    1475             :                  * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields.
    1476             :                  */
    1477       60325 :                 error = xfs_da3_split(state);
    1478       60324 :                 if (error)
    1479           2 :                         goto out;
    1480             :         } else {
    1481             :                 /*
    1482             :                  * Addition succeeded, update Btree hashvals.
    1483             :                  */
    1484     1541655 :                 xfs_da3_fixhashpath(state, &state->path);
    1485             :         }
    1486             : 
    1487     1601980 : out:
    1488     1601980 :         xfs_da_state_free(state);
    1489     1601978 :         attr->xattri_da_state = NULL;
    1490     1601978 :         return error;
    1491             : }
    1492             : 
    1493             : static int
    1494      947437 : xfs_attr_node_removename(
    1495             :         struct xfs_da_args      *args,
    1496             :         struct xfs_da_state     *state)
    1497             : {
    1498      947437 :         struct xfs_da_state_blk *blk;
    1499      947437 :         int                     retval;
    1500             : 
    1501             :         /*
    1502             :          * Remove the name and update the hashvals in the tree.
    1503             :          */
    1504      947437 :         blk = &state->path.blk[state->path.active-1];
    1505      947437 :         ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
    1506      947437 :         retval = xfs_attr3_leaf_remove(blk->bp, args);
    1507      947439 :         xfs_da3_fixhashpath(state, &state->path);
    1508             : 
    1509      947438 :         return retval;
    1510             : }
    1511             : 
    1512             : static int
    1513      947435 : xfs_attr_node_remove_attr(
    1514             :         struct xfs_attr_intent          *attr)
    1515             : {
    1516      947435 :         struct xfs_da_args              *args = attr->xattri_da_args;
    1517      947435 :         struct xfs_da_state             *state = xfs_da_state_alloc(args);
    1518      947439 :         int                             retval = 0;
    1519      947439 :         int                             error = 0;
    1520             : 
    1521             :         /*
    1522             :          * The attr we are removing has already been marked incomplete, so
    1523             :          * we need to set the filter appropriately to re-find the "old"
    1524             :          * attribute entry after any split ops.
    1525             :          */
    1526      947439 :         args->attr_filter |= XFS_ATTR_INCOMPLETE;
    1527      947439 :         error = xfs_da3_node_lookup_int(state, &retval);
    1528      947437 :         if (error)
    1529           0 :                 goto out;
    1530             : 
    1531      947437 :         error = xfs_attr_node_removename(args, state);
    1532             : 
    1533             :         /*
    1534             :          * Check to see if the tree needs to be collapsed.
    1535             :          */
    1536      947435 :         if (retval && (state->path.active > 1)) {
    1537      947008 :                 error = xfs_da3_join(state);
    1538      947010 :                 if (error)
    1539           2 :                         goto out;
    1540             :         }
    1541      947435 :         retval = error = 0;
    1542             : 
    1543      947437 : out:
    1544      947437 :         xfs_da_state_free(state);
    1545      947438 :         if (error)
    1546             :                 return error;
    1547      947436 :         return retval;
    1548             : }
    1549             : 
    1550             : /*
    1551             :  * Retrieve the attribute data from a node attribute list.
    1552             :  *
    1553             :  * This routine gets called for any attribute fork that has more than one
    1554             :  * block, ie: both true Btree attr lists and for single-leaf-blocks with
    1555             :  * "remote" values taking up more blocks.
    1556             :  *
    1557             :  * Returns 0 on successful retrieval, otherwise an error.
    1558             :  */
    1559             : STATIC int
    1560      450587 : xfs_attr_node_get(
    1561             :         struct xfs_da_args      *args)
    1562             : {
    1563      450587 :         struct xfs_da_state     *state;
    1564      450587 :         struct xfs_da_state_blk *blk;
    1565      450587 :         int                     i;
    1566      450587 :         int                     error;
    1567             : 
    1568      450587 :         trace_xfs_attr_node_get(args);
    1569             : 
    1570             :         /*
    1571             :          * Search to see if name exists, and get back a pointer to it.
    1572             :          */
    1573      450587 :         state = xfs_da_state_alloc(args);
    1574      450587 :         error = xfs_attr_node_lookup(args, state);
    1575      450587 :         if (error != -EEXIST)
    1576      115762 :                 goto out_release;
    1577             : 
    1578             :         /*
    1579             :          * Get the value, local or "remote"
    1580             :          */
    1581      334825 :         blk = &state->path.blk[state->path.active - 1];
    1582      334825 :         error = xfs_attr3_leaf_getvalue(blk->bp, args);
    1583             : 
    1584             :         /*
    1585             :          * If not in a transaction, we have to release all the buffers.
    1586             :          */
    1587      450587 : out_release:
    1588     1351151 :         for (i = 0; i < state->path.active; i++) {
    1589      900564 :                 xfs_trans_brelse(args->trans, state->path.blk[i].bp);
    1590      900564 :                 state->path.blk[i].bp = NULL;
    1591             :         }
    1592             : 
    1593      450587 :         xfs_da_state_free(state);
    1594      450587 :         return error;
    1595             : }
    1596             : 
    1597             : /* Returns true if the attribute entry name is valid. */
    1598             : bool
    1599  6459563672 : xfs_attr_namecheck(
    1600             :         struct xfs_mount        *mp,
    1601             :         const void              *name,
    1602             :         size_t                  length,
    1603             :         unsigned int            flags)
    1604             : {
    1605  6459563672 :         if (flags & XFS_ATTR_PARENT)
    1606   581527977 :                 return xfs_parent_namecheck(mp, name, length, flags);
    1607             : 
    1608             :         /*
    1609             :          * MAXNAMELEN includes the trailing null, but (name/length) leave it
    1610             :          * out, so use >= for the length check.
    1611             :          */
    1612  5878035695 :         if (length >= MAXNAMELEN)
    1613             :                 return false;
    1614             : 
    1615             :         /* There shouldn't be any nulls here */
    1616 11756071390 :         return !memchr(name, 0, length);
    1617             : }
    1618             : 
    1619             : int __init
    1620          12 : xfs_attr_intent_init_cache(void)
    1621             : {
    1622          12 :         xfs_attr_intent_cache = kmem_cache_create("xfs_attr_intent",
    1623             :                         sizeof(struct xfs_attr_intent),
    1624             :                         0, 0, NULL);
    1625             : 
    1626          12 :         return xfs_attr_intent_cache != NULL ? 0 : -ENOMEM;
    1627             : }
    1628             : 
    1629             : void
    1630          12 : xfs_attr_intent_destroy_cache(void)
    1631             : {
    1632          12 :         kmem_cache_destroy(xfs_attr_intent_cache);
    1633          12 :         xfs_attr_intent_cache = NULL;
    1634          12 : }

Generated by: LCOV version 1.14