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-achx @ Mon Jul 31 20:08:12 PDT 2023 Lines: 581 618 94.0 %
Date: 2023-07-31 20:08:12 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  6487815318 : xfs_inode_hasattr(
      69             :         struct xfs_inode        *ip)
      70             : {
      71  6551212943 :         if (!xfs_inode_has_attr_fork(ip))
      72             :                 return 0;
      73  7002531582 :         if (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
      74   450802294 :             ip->i_af.if_nextents == 0)
      75    79850805 :                 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   550845783 : xfs_attr_is_leaf(
      85             :         struct xfs_inode        *ip)
      86             : {
      87   550845783 :         struct xfs_ifork        *ifp = &ip->i_af;
      88   550845783 :         struct xfs_iext_cursor  icur;
      89   550845783 :         struct xfs_bmbt_irec    imap;
      90             : 
      91   550845783 :         if (ifp->if_nextents != 1 || ifp->if_format != XFS_DINODE_FMT_EXTENTS)
      92             :                 return false;
      93             : 
      94   541668378 :         xfs_iext_first(ifp, &icur);
      95   541689285 :         xfs_iext_get_extent(ifp, &icur, &imap);
      96   542658355 :         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   270537951 : xfs_attr_get_ilocked(
     226             :         struct xfs_da_args      *args)
     227             : {
     228   270537951 :         ASSERT(xfs_isilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
     229             : 
     230   270226994 :         if (!xfs_inode_hasattr(args->dp))
     231             :                 return -ENOATTR;
     232             : 
     233   268965432 :         if (args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
     234   251183031 :                 return xfs_attr_shortform_getvalue(args);
     235    17782401 :         if (xfs_attr_is_leaf(args->dp))
     236    17112445 :                 return xfs_attr_leaf_get(args);
     237      683472 :         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    69497376 : xfs_attr_get(
     258             :         struct xfs_da_args      *args)
     259             : {
     260    69497376 :         uint                    lock_mode;
     261    69497376 :         int                     error;
     262             : 
     263    69497376 :         XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
     264             : 
     265   138759136 :         if (xfs_is_shutdown(args->dp->i_mount))
     266             :                 return -EIO;
     267             : 
     268    69378657 :         args->geo = args->dp->i_mount->m_attr_geo;
     269    69378657 :         args->whichfork = XFS_ATTR_FORK;
     270    69378657 :         args->hashval = xfs_da_hashname(args->name, args->namelen);
     271             : 
     272             :         /* Entirely possible to look up a name which doesn't exist */
     273    69383448 :         args->op_flags = XFS_DA_OP_OKNOENT;
     274             : 
     275    69383448 :         lock_mode = xfs_ilock_attr_map_shared(args->dp);
     276    69391397 :         error = xfs_attr_get_ilocked(args);
     277    69370960 :         xfs_iunlock(args->dp, lock_mode);
     278             : 
     279    69370960 :         return error;
     280             : }
     281             : 
     282             : /*
     283             :  * Calculate how many blocks we need for the new attribute,
     284             :  */
     285             : int
     286   126725940 : xfs_attr_calc_size(
     287             :         struct xfs_da_args      *args,
     288             :         int                     *local)
     289             : {
     290   126725940 :         struct xfs_mount        *mp = args->dp->i_mount;
     291   126725940 :         int                     size;
     292   126725940 :         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   126725940 :         size = xfs_attr_leaf_newentsize(args, local);
     299   126716710 :         nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
     300   126716710 :         if (*local) {
     301   126713397 :                 if (size > (args->geo->blksize / 2)) {
     302             :                         /* Double split possible */
     303          11 :                         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        3313 :                 uint    dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
     311        3313 :                 nblks += dblocks;
     312        3313 :                 nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
     313             :         }
     314             : 
     315   126716710 :         return nblks;
     316             : }
     317             : 
     318             : /* Initialize transaction reservation for attr operations */
     319             : void
     320   190013675 : xfs_init_attr_trans(
     321             :         struct xfs_da_args      *args,
     322             :         struct xfs_trans_res    *tres,
     323             :         unsigned int            *total)
     324             : {
     325   190013675 :         struct xfs_mount        *mp = args->dp->i_mount;
     326             : 
     327   190013675 :         if (args->value) {
     328   126721992 :                 tres->tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
     329   126721992 :                                  M_RES(mp)->tr_attrsetrt.tr_logres *
     330   126721992 :                                  args->total;
     331   126721992 :                 tres->tr_logcount = XFS_ATTRSET_LOG_COUNT;
     332   126721992 :                 tres->tr_logflags = XFS_TRANS_PERM_LOG_RES;
     333   126721992 :                 *total = args->total;
     334             :         } else {
     335    63291683 :                 *tres = M_RES(mp)->tr_attrrm;
     336    63291683 :                 *total = XFS_ATTRRM_SPACE_RES(mp);
     337             :         }
     338   190013675 : }
     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   199664250 : xfs_attr_try_sf_addname(
     347             :         struct xfs_inode        *dp,
     348             :         struct xfs_da_args      *args)
     349             : {
     350             : 
     351   199664250 :         int                     error;
     352             : 
     353             :         /*
     354             :          * Build initial attribute list (if required).
     355             :          */
     356   199664250 :         if (dp->i_af.if_format == XFS_DINODE_FMT_EXTENTS)
     357    98650909 :                 xfs_attr_shortform_create(args);
     358             : 
     359   199869430 :         error = xfs_attr_shortform_addname(args);
     360   199761883 :         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   195081820 :         if (!error && !(args->op_flags & XFS_DA_OP_NOTIME))
     368   195077906 :                 xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
     369             : 
     370   195057400 :         if (xfs_has_wsync(dp->i_mount))
     371         708 :                 xfs_trans_set_sync(args->trans);
     372             : 
     373             :         return error;
     374             : }
     375             : 
     376             : static int
     377   199669665 : xfs_attr_sf_addname(
     378             :         struct xfs_attr_intent          *attr)
     379             : {
     380   199669665 :         struct xfs_da_args              *args = attr->xattri_da_args;
     381   199669665 :         struct xfs_inode                *dp = args->dp;
     382   199669665 :         int                             error = 0;
     383             : 
     384   199669665 :         error = xfs_attr_try_sf_addname(dp, args);
     385   199725990 :         if (error != -ENOSPC) {
     386   195046015 :                 ASSERT(!error || error == -EEXIST);
     387   195046015 :                 attr->xattri_dela_state = XFS_DAS_DONE;
     388   195046015 :                 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     4679975 :         error = xfs_attr_shortform_to_leaf(args);
     396     4680191 :         if (error)
     397             :                 return error;
     398             : 
     399     4680184 :         attr->xattri_dela_state = XFS_DAS_LEAF_ADD;
     400   199726199 : out:
     401   199726199 :         trace_xfs_attr_sf_addname_return(attr->xattri_dela_state, args->dp);
     402   199726199 :         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   251163941 : xfs_attr_complete_op(
     418             :         struct xfs_attr_intent  *attr,
     419             :         enum xfs_delattr_state  replace_state)
     420             : {
     421   251163941 :         struct xfs_da_args      *args = attr->xattri_da_args;
     422   251163941 :         bool                    do_replace = args->op_flags & XFS_DA_OP_REPLACE;
     423             : 
     424   251163941 :         args->op_flags &= ~XFS_DA_OP_REPLACE;
     425   251163941 :         if (!do_replace)
     426             :                 return XFS_DAS_DONE;
     427             : 
     428    75582339 :         args->attr_filter &= ~XFS_ATTR_INCOMPLETE;
     429    75582339 :         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    57239629 :         ASSERT(args->new_namelen > 0);
     437             : 
     438    57239629 :         args->name = args->new_name;
     439    57239629 :         args->namelen = args->new_namelen;
     440    57239629 :         args->hashval = xfs_da_hashname(args->name, args->namelen);
     441    57239524 :         args->value = args->new_value;
     442    57239524 :         args->valuelen = args->new_valuelen;
     443    57239524 :         return replace_state;
     444             : }
     445             : 
     446             : static int
     447    76960479 : xfs_attr_leaf_addname(
     448             :         struct xfs_attr_intent  *attr)
     449             : {
     450    76960479 :         struct xfs_da_args      *args = attr->xattri_da_args;
     451    76960479 :         int                     error;
     452             : 
     453    76960479 :         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    77009153 :         error = xfs_attr_leaf_try_add(args);
     460             : 
     461    77008538 :         if (error == -ENOSPC) {
     462       41036 :                 error = xfs_attr3_leaf_to_node(args);
     463       41036 :                 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       41025 :                 attr->xattri_dela_state = XFS_DAS_NODE_ADD;
     471       41025 :                 goto out;
     472             :         }
     473    76967502 :         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    76967502 :         if (args->rmtblkno)
     482        2862 :                 attr->xattri_dela_state = XFS_DAS_LEAF_SET_RMT;
     483             :         else
     484    76964640 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     485             :                                                         XFS_DAS_LEAF_REPLACE);
     486    76930141 : out:
     487    76930141 :         trace_xfs_attr_leaf_addname_return(attr->xattri_dela_state, args->dp);
     488    76930141 :         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     2160705 : xfs_attr_node_addname(
     500             :         struct xfs_attr_intent  *attr)
     501             : {
     502     2160705 :         struct xfs_da_args      *args = attr->xattri_da_args;
     503     2160705 :         int                     error;
     504             : 
     505     2160705 :         error = xfs_attr_node_addname_find_attr(attr);
     506     2160787 :         if (error)
     507             :                 return error;
     508             : 
     509     2160769 :         error = xfs_attr_node_try_addname(attr);
     510     2160642 :         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     2160642 :         if (error)
     521             :                 return error;
     522             : 
     523     2160631 :         if (args->rmtblkno)
     524         101 :                 attr->xattri_dela_state = XFS_DAS_NODE_SET_RMT;
     525             :         else
     526     2160530 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     527             :                                                         XFS_DAS_NODE_REPLACE);
     528     2160638 : out:
     529     2160638 :         trace_xfs_attr_node_addname_return(attr->xattri_dela_state, args->dp);
     530     2160638 :         return error;
     531             : }
     532             : 
     533             : static int
     534        2963 : xfs_attr_rmtval_alloc(
     535             :         struct xfs_attr_intent          *attr)
     536             : {
     537        2963 :         struct xfs_da_args              *args = attr->xattri_da_args;
     538        2963 :         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        2963 :         if (attr->xattri_blkcnt > 0) {
     547        2963 :                 error = xfs_attr_rmtval_set_blk(attr);
     548        2963 :                 if (error)
     549             :                         return error;
     550             :                 /* Roll the transaction only if there is more to allocate. */
     551        2963 :                 if (attr->xattri_blkcnt > 0)
     552           0 :                         goto out;
     553             :         }
     554             : 
     555        2963 :         error = xfs_attr_rmtval_set_value(args);
     556        2963 :         if (error)
     557             :                 return error;
     558             : 
     559        5926 :         attr->xattri_dela_state = xfs_attr_complete_op(attr,
     560        2963 :                                                 ++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        2963 :         if (attr->xattri_dela_state == XFS_DAS_DONE)
     567        2953 :                 error = xfs_attr3_leaf_clearflag(args);
     568          10 : out:
     569        2963 :         trace_xfs_attr_rmtval_alloc(attr->xattri_dela_state, args->dp);
     570        2963 :         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      688950 :         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      688950 :         error = xfs_attr_fillstate(state);
     590      688950 :         if (error)
     591             :                 return error;
     592             : 
     593             :         /*
     594             :          * Mark the attribute as INCOMPLETE
     595             :          */
     596      688950 :         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     2849571 : xfs_attr_item_init_da_state(
     602             :         struct xfs_attr_intent  *attr)
     603             : {
     604     2849571 :         struct xfs_da_args      *args = attr->xattri_da_args;
     605             : 
     606     2849571 :         if (!attr->xattri_da_state)
     607     2843363 :                 attr->xattri_da_state = xfs_da_state_alloc(args);
     608             :         else
     609        6208 :                 xfs_da_state_reset(attr->xattri_da_state, args);
     610     2849674 : }
     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      688977 : int xfs_attr_node_removename_setup(
     619             :         struct xfs_attr_intent          *attr)
     620             : {
     621      688977 :         struct xfs_da_args              *args = attr->xattri_da_args;
     622      688977 :         struct xfs_da_state             *state;
     623      688977 :         int                             error;
     624             : 
     625      688977 :         xfs_attr_item_init_da_state(attr);
     626      688974 :         error = xfs_attr_node_lookup(args, attr->xattri_da_state);
     627      688987 :         if (error != -EEXIST)
     628          33 :                 goto out;
     629      688954 :         error = 0;
     630             : 
     631      688954 :         state = attr->xattri_da_state;
     632      688954 :         ASSERT(state->path.blk[state->path.active - 1].bp != NULL);
     633      688952 :         ASSERT(state->path.blk[state->path.active - 1].magic ==
     634             :                 XFS_ATTR_LEAF_MAGIC);
     635             : 
     636      688950 :         error = xfs_attr_leaf_mark_incomplete(args, state);
     637      688937 :         if (error)
     638           0 :                 goto out;
     639      688937 :         if (args->rmtblkno > 0)
     640          68 :                 error = xfs_attr_rmtval_invalidate(args);
     641      688869 : out:
     642      688970 :         if (error) {
     643          33 :                 xfs_da_state_free(attr->xattri_da_state);
     644          33 :                 attr->xattri_da_state = NULL;
     645             :         }
     646             : 
     647      688970 :         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    17555110 : xfs_attr_leaf_remove_attr(
     657             :         struct xfs_attr_intent          *attr)
     658             : {
     659    17555110 :         struct xfs_da_args              *args = attr->xattri_da_args;
     660    17555110 :         struct xfs_inode                *dp = args->dp;
     661    17555110 :         struct xfs_buf                  *bp = NULL;
     662    17555110 :         int                             forkoff;
     663    17555110 :         int                             error;
     664             : 
     665    17555110 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
     666             :                         args->blkno, &bp);
     667    17556138 :         if (error)
     668             :                 return error;
     669             : 
     670    17556099 :         xfs_attr3_leaf_remove(bp, args);
     671             : 
     672    17555179 :         forkoff = xfs_attr_shortform_allfit(bp, dp);
     673    17555776 :         if (forkoff)
     674      411129 :                 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     1047041 : xfs_attr_leaf_shrink(
     687             :         struct xfs_da_args      *args)
     688             : {
     689     1047041 :         struct xfs_inode        *dp = args->dp;
     690     1047041 :         struct xfs_buf          *bp;
     691     1047041 :         int                     forkoff;
     692     1047041 :         int                     error;
     693             : 
     694     1047041 :         if (!xfs_attr_is_leaf(dp))
     695             :                 return 0;
     696             : 
     697         117 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
     698         117 :         if (error)
     699             :                 return error;
     700             : 
     701         117 :         forkoff = xfs_attr_shortform_allfit(bp, dp);
     702         117 :         if (forkoff) {
     703          56 :                 error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
     704             :                 /* bp is gone due to xfs_da_shrink_inode */
     705             :         } else {
     706          61 :                 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   469544133 : xfs_attr_set_iter(
     722             :         struct xfs_attr_intent          *attr)
     723             : {
     724   469544133 :         struct xfs_da_args              *args = attr->xattri_da_args;
     725   469544133 :         int                             error = 0;
     726             : 
     727             :         /* State machine switch */
     728             : next_state:
     729   487458098 :         switch (attr->xattri_dela_state) {
     730           0 :         case XFS_DAS_UNINIT:
     731           0 :                 ASSERT(0);
     732           0 :                 return -EFSCORRUPTED;
     733   199720262 :         case XFS_DAS_SF_ADD:
     734   199720262 :                 return xfs_attr_sf_addname(attr);
     735    76995733 :         case XFS_DAS_LEAF_ADD:
     736    76995733 :                 return xfs_attr_leaf_addname(attr);
     737     2160730 :         case XFS_DAS_NODE_ADD:
     738     2160730 :                 return xfs_attr_node_addname(attr);
     739             : 
     740   123107278 :         case XFS_DAS_SF_REMOVE:
     741   123107278 :                 error = xfs_attr_sf_removename(args);
     742   123125989 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     743             :                                                 xfs_attr_init_add_state(args));
     744   123092570 :                 break;
     745    30351993 :         case XFS_DAS_LEAF_REMOVE:
     746    30351993 :                 error = xfs_attr_leaf_removename(args);
     747    30358470 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     748             :                                                 xfs_attr_init_add_state(args));
     749    30349242 :                 break;
     750      688974 :         case XFS_DAS_NODE_REMOVE:
     751      688974 :                 error = xfs_attr_node_removename_setup(attr);
     752      688958 :                 if (error == -ENOATTR &&
     753          33 :                     (args->op_flags & XFS_DA_OP_RECOVERY)) {
     754          33 :                         attr->xattri_dela_state = xfs_attr_complete_op(attr,
     755             :                                                 xfs_attr_init_add_state(args));
     756          33 :                         error = 0;
     757          33 :                         break;
     758             :                 }
     759      688925 :                 if (error)
     760             :                         return error;
     761      688925 :                 attr->xattri_dela_state = XFS_DAS_NODE_REMOVE_RMT;
     762      688925 :                 if (args->rmtblkno == 0)
     763      688853 :                         attr->xattri_dela_state++;
     764             :                 break;
     765             : 
     766        2963 :         case XFS_DAS_LEAF_SET_RMT:
     767             :         case XFS_DAS_NODE_SET_RMT:
     768        2963 :                 error = xfs_attr_rmtval_find_space(attr);
     769        2963 :                 if (error)
     770           0 :                         return error;
     771        2963 :                 attr->xattri_dela_state++;
     772        2963 :                 fallthrough;
     773             : 
     774        2963 :         case XFS_DAS_LEAF_ALLOC_RMT:
     775             :         case XFS_DAS_NODE_ALLOC_RMT:
     776        2963 :                 error = xfs_attr_rmtval_alloc(attr);
     777        2963 :                 if (error)
     778           0 :                         return error;
     779        2963 :                 if (attr->xattri_dela_state == XFS_DAS_DONE)
     780             :                         break;
     781          10 :                 goto next_state;
     782             : 
     783    17912971 :         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    17912971 :                 error = xfs_attr3_leaf_flipflags(args);
     791    17912750 :                 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    17912750 :                 attr->xattri_dela_state++;
     798    17912750 :                 break;
     799             : 
     800    17914843 :         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    17914843 :                 xfs_attr_restore_rmt_blk(args);
     810    17913955 :                 if (args->rmtblkno) {
     811          20 :                         error = xfs_attr_rmtval_invalidate(args);
     812          20 :                         if (error)
     813           0 :                                 return error;
     814             :                 } else {
     815    17913935 :                         attr->xattri_dela_state++;
     816             :                 }
     817             : 
     818    17913955 :                 attr->xattri_dela_state++;
     819    17913955 :                 goto next_state;
     820             : 
     821          88 :         case XFS_DAS_LEAF_REMOVE_RMT:
     822             :         case XFS_DAS_NODE_REMOVE_RMT:
     823          88 :                 error = xfs_attr_rmtval_remove(attr);
     824          88 :                 if (error == -EAGAIN) {
     825             :                         error = 0;
     826             :                         break;
     827             :                 }
     828          88 :                 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          88 :                 attr->xattri_dela_state++;
     840          88 :                 break;
     841             : 
     842    17555193 :         case XFS_DAS_LEAF_REMOVE_ATTR:
     843    17555193 :                 error = xfs_attr_leaf_remove_attr(attr);
     844    17555403 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     845             :                                                 xfs_attr_init_add_state(args));
     846    17553261 :                 break;
     847             : 
     848     1047070 :         case XFS_DAS_NODE_REMOVE_ATTR:
     849     1047070 :                 error = xfs_attr_node_remove_attr(attr);
     850     1047067 :                 if (!error)
     851     1047041 :                         error = xfs_attr_leaf_shrink(args);
     852     1047072 :                 attr->xattri_dela_state = xfs_attr_complete_op(attr,
     853             :                                                 xfs_attr_init_add_state(args));
     854     1047053 :                 break;
     855           0 :         default:
     856           0 :                 ASSERT(0);
     857           0 :                 break;
     858             :         }
     859             : 
     860   190646875 :         trace_xfs_attr_set_iter_return(attr->xattri_dela_state, args->dp);
     861   190646875 :         return error;
     862             : }
     863             : 
     864             : 
     865             : /*
     866             :  * Return EEXIST if attr is found, or ENOATTR if not
     867             :  */
     868             : static int
     869   189814031 : xfs_attr_lookup(
     870             :         struct xfs_da_args      *args)
     871             : {
     872   189814031 :         struct xfs_inode        *dp = args->dp;
     873   189814031 :         struct xfs_buf          *bp = NULL;
     874   189814031 :         struct xfs_da_state     *state;
     875   189814031 :         int                     error;
     876             : 
     877   189814031 :         if (!xfs_inode_hasattr(dp))
     878             :                 return -ENOATTR;
     879             : 
     880   184239616 :         if (dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
     881    58901610 :                 return xfs_attr_sf_findname(args, NULL, NULL);
     882             : 
     883   125338006 :         if (xfs_attr_is_leaf(dp)) {
     884   122314164 :                 error = xfs_attr_leaf_hasname(args, &bp);
     885             : 
     886   122317360 :                 if (bp)
     887   122317350 :                         xfs_trans_brelse(args->trans, bp);
     888             : 
     889   122386928 :                 return error;
     890             :         }
     891             : 
     892     3103680 :         state = xfs_da_state_alloc(args);
     893     3103738 :         error = xfs_attr_node_lookup(args, state);
     894     3103683 :         xfs_da_state_free(state);
     895     3103683 :         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   370789749 :         struct xfs_attr_intent  *new;
     906             : 
     907           0 :         new = kmem_cache_zalloc(xfs_attr_intent_cache, GFP_NOFS | __GFP_NOFAIL);
     908   370759814 :         new->xattri_op_flags = op_flags;
     909   370759814 :         new->xattri_da_args = args;
     910             : 
     911   370759814 :         *attr = new;
     912   370759814 :         return 0;
     913             : }
     914             : 
     915             : /* Sets an attribute for an inode as a deferred operation */
     916             : int
     917   191410611 : xfs_attr_defer_add(
     918             :         struct xfs_da_args      *args)
     919             : {
     920   191410611 :         struct xfs_attr_intent  *new;
     921   191410611 :         int                     op_flag = XFS_ATTRI_OP_FLAGS_SET;
     922   191410611 :         int                     error = 0;
     923             : 
     924   191410611 :         if (args->op_flags & XFS_DA_OP_NVLOOKUP)
     925   110915589 :                 op_flag = XFS_ATTRI_OP_FLAGS_NVSET;
     926             : 
     927   191410611 :         error = xfs_attr_intent_init(args, op_flag, &new);
     928   191386845 :         if (error)
     929             :                 return error;
     930             : 
     931   191386845 :         new->xattri_dela_state = xfs_attr_init_add_state(args);
     932   191329919 :         xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
     933   191278528 :         trace_xfs_attr_defer_add(new->xattri_dela_state, args->dp);
     934             : 
     935   191232295 :         return 0;
     936             : }
     937             : 
     938             : /* Sets an attribute for an inode as a deferred operation */
     939             : int
     940    82889706 : xfs_attr_defer_replace(
     941             :         struct xfs_da_args      *args)
     942             : {
     943    82889706 :         struct xfs_attr_intent  *new;
     944    82889706 :         int                     op_flag = XFS_ATTRI_OP_FLAGS_REPLACE;
     945    82889706 :         int                     error = 0;
     946             : 
     947    82889706 :         if (args->op_flags & XFS_DA_OP_NVLOOKUP)
     948    57239884 :                 op_flag = XFS_ATTRI_OP_FLAGS_NVREPLACE;
     949             : 
     950    82889706 :         error = xfs_attr_intent_init(args, op_flag, &new);
     951    82888470 :         if (error)
     952             :                 return error;
     953             : 
     954    82888470 :         new->xattri_dela_state = xfs_attr_init_replace_state(args);
     955    82886928 :         xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
     956    82884525 :         trace_xfs_attr_defer_replace(new->xattri_dela_state, args->dp);
     957             : 
     958    82882816 :         return 0;
     959             : }
     960             : 
     961             : /* Removes an attribute for an inode as a deferred operation */
     962             : int
     963    96489432 : xfs_attr_defer_remove(
     964             :         struct xfs_da_args      *args)
     965             : {
     966             : 
     967    96489432 :         struct xfs_attr_intent  *new;
     968    96489432 :         int                     op_flag = XFS_ATTRI_OP_FLAGS_REMOVE;
     969    96489432 :         int                     error;
     970             : 
     971    96489432 :         if (args->op_flags & XFS_DA_OP_NVLOOKUP)
     972    61102376 :                 op_flag = XFS_ATTRI_OP_FLAGS_NVREMOVE;
     973             : 
     974    96489432 :         error  = xfs_attr_intent_init(args, op_flag, &new);
     975    96484499 :         if (error)
     976             :                 return error;
     977             : 
     978    96484499 :         new->xattri_dela_state = xfs_attr_init_remove_state(args);
     979    96471272 :         xfs_defer_add(args->trans, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list);
     980    96474428 :         trace_xfs_attr_defer_remove(new->xattri_dela_state, args->dp);
     981             : 
     982    96470474 :         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   190064256 : xfs_attr_set(
     991             :         struct xfs_da_args      *args)
     992             : {
     993   190064256 :         struct xfs_inode        *dp = args->dp;
     994   190064256 :         struct xfs_mount        *mp = dp->i_mount;
     995   190064256 :         struct xfs_trans_res    tres;
     996   190064256 :         bool                    rsvd = (args->attr_filter & (XFS_ATTR_ROOT |
     997             :                                                              XFS_ATTR_PARENT));
     998   190064256 :         bool                    is_remove = args->op_flags & XFS_DA_OP_REMOVE;
     999   190064256 :         int                     error, local;
    1000   190064256 :         int                     rmt_blks = 0;
    1001   190064256 :         unsigned int            total;
    1002             : 
    1003   380128512 :         if (xfs_is_shutdown(dp->i_mount))
    1004             :                 return -EIO;
    1005             : 
    1006   190063265 :         error = xfs_qm_dqattach(dp);
    1007   189980282 :         if (error)
    1008             :                 return error;
    1009             : 
    1010   189980231 :         args->geo = mp->m_attr_geo;
    1011   189980231 :         args->whichfork = XFS_ATTR_FORK;
    1012   189980231 :         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   190010103 :         args->op_flags &= (XFS_DA_OP_LOGGED | XFS_DA_OP_NVLOOKUP);
    1021   190010103 :         args->op_flags |= XFS_DA_OP_OKNOENT;
    1022             : 
    1023   190010103 :         if (!is_remove) {
    1024   126715087 :                 XFS_STATS_INC(mp, xs_attr_set);
    1025   126732958 :                 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   126718206 :                 if (xfs_inode_has_attr_fork(dp) == 0) {
    1032     4494514 :                         int sf_size = sizeof(struct xfs_attr_sf_hdr) +
    1033     4494514 :                                 xfs_attr_sf_entsize_byname(args->namelen,
    1034     4494514 :                                                 args->valuelen);
    1035             : 
    1036     4494514 :                         error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
    1037     4494814 :                         if (error)
    1038             :                                 return error;
    1039             :                 }
    1040             : 
    1041   126718193 :                 if (!local)
    1042        3258 :                         rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
    1043             :         } else {
    1044    63295016 :                 XFS_STATS_INC(mp, xs_attr_remove);
    1045    63308895 :                 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   190018653 :         xfs_init_attr_trans(args, &tres, &total);
    1053   189932705 :         error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
    1054   190194470 :         if (error)
    1055             :                 return error;
    1056             : 
    1057   190075981 :         if (!is_remove || xfs_inode_hasattr(dp)) {
    1058   189074025 :                 error = xfs_iext_count_may_overflow(dp, XFS_ATTR_FORK,
    1059   189074025 :                                 XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
    1060   188675189 :                 if (error == -EFBIG)
    1061          22 :                         error = xfs_iext_count_upgrade(args->trans, dp,
    1062          22 :                                         XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
    1063   188675189 :                 if (error)
    1064          22 :                         goto out_trans_cancel;
    1065             :         }
    1066             : 
    1067   189677123 :         error = xfs_attr_lookup(args);
    1068   189924470 :         switch (error) {
    1069    61263011 :         case -EEXIST:
    1070             :                 /* if no value, we are performing a remove operation */
    1071    61263011 :                 if (is_remove) {
    1072    35391108 :                         error = xfs_attr_defer_remove(args);
    1073    35391108 :                         break;
    1074             :                 }
    1075             :                 /* Pure create fails if the attr already exists */
    1076    25871903 :                 if (args->attr_flags & XATTR_CREATE)
    1077      222183 :                         goto out_trans_cancel;
    1078             : 
    1079    25649720 :                 error = xfs_attr_defer_replace(args);
    1080    25649720 :                 break;
    1081   128661429 :         case -ENOATTR:
    1082             :                 /* Can't remove what isn't there. */
    1083   128661429 :                 if (is_remove)
    1084    27841557 :                         goto out_trans_cancel;
    1085             : 
    1086             :                 /* Pure replace fails if no existing attr to replace. */
    1087   100819872 :                 if (args->attr_flags & XATTR_REPLACE)
    1088    15861638 :                         goto out_trans_cancel;
    1089             : 
    1090    84958234 :                 error = xfs_attr_defer_add(args);
    1091    84958234 :                 break;
    1092          30 :         default:
    1093          30 :                 goto out_trans_cancel;
    1094             :         }
    1095   145946410 :         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   145946410 :         if (xfs_has_wsync(mp))
    1103           0 :                 xfs_trans_set_sync(args->trans);
    1104             : 
    1105   145946410 :         if (!(args->op_flags & XFS_DA_OP_NOTIME))
    1106   145870694 :                 xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
    1107             : 
    1108             :         /*
    1109             :          * Commit the last in the sequence of transactions.
    1110             :          */
    1111   145690662 :         xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
    1112   145906807 :         error = xfs_trans_commit(args->trans);
    1113   190017145 : out_unlock:
    1114   190017145 :         xfs_iunlock(dp, XFS_ILOCK_EXCL);
    1115   190017145 :         return error;
    1116             : 
    1117    43925430 : out_trans_cancel:
    1118    43925430 :         if (args->trans)
    1119    43995839 :                 xfs_trans_cancel(args->trans);
    1120    44029217 :         goto out_unlock;
    1121             : }
    1122             : 
    1123             : /*========================================================================
    1124             :  * External routines when attribute list is inside the inode
    1125             :  *========================================================================*/
    1126             : 
    1127     4271893 : int xfs_attr_sf_totsize(struct xfs_inode *dp)
    1128             : {
    1129   203984509 :         struct xfs_attr_shortform *sf;
    1130             : 
    1131   203984509 :         sf = (struct xfs_attr_shortform *)dp->i_af.if_u1.if_data;
    1132   203984509 :         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   199849504 : xfs_attr_shortform_addname(
    1141             :         struct xfs_da_args      *args)
    1142             : {
    1143   199849504 :         int                     newsize, forkoff;
    1144   199849504 :         int                     error;
    1145             : 
    1146   199849504 :         trace_xfs_attr_sf_addname(args);
    1147             : 
    1148   199826911 :         error = xfs_attr_shortform_lookup(args);
    1149   199721903 :         switch (error) {
    1150   192423331 :         case -ENOATTR:
    1151   192423331 :                 if (args->op_flags & XFS_DA_OP_REPLACE)
    1152             :                         return error;
    1153             :                 break;
    1154     7298572 :         case -EEXIST:
    1155     7298572 :                 if (!(args->op_flags & XFS_DA_OP_REPLACE))
    1156             :                         return error;
    1157             : 
    1158     7298572 :                 error = xfs_attr_sf_removename(args);
    1159     7300199 :                 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     7300199 :                 args->op_flags &= ~XFS_DA_OP_REPLACE;
    1169     7300199 :                 break;
    1170             :         case 0:
    1171             :                 break;
    1172             :         default:
    1173             :                 return error;
    1174             :         }
    1175             : 
    1176   199723530 :         if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
    1177   199723530 :             args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
    1178             :                 return -ENOSPC;
    1179             : 
    1180   199712616 :         newsize = xfs_attr_sf_totsize(args->dp);
    1181   199712616 :         newsize += xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
    1182             : 
    1183   199712616 :         forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
    1184   199672515 :         if (!forkoff)
    1185             :                 return -ENOSPC;
    1186             : 
    1187   195003360 :         xfs_attr_shortform_add(args, forkoff);
    1188   195003360 :         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    17918706 :         args->blkno2 = args->blkno;
    1202    17918706 :         args->index2 = args->index;
    1203    17918706 :         args->rmtblkno2 = args->rmtblkno;
    1204    17918706 :         args->rmtblkcnt2 = args->rmtblkcnt;
    1205    17918706 :         args->rmtvaluelen2 = args->rmtvaluelen;
    1206    17918706 :         args->rmtblkno = 0;
    1207    17918706 :         args->rmtblkcnt = 0;
    1208    17918706 :         args->rmtvaluelen = 0;
    1209    17918706 : }
    1210             : 
    1211             : /* Set stored info about a remote block */
    1212             : static void
    1213    17914451 : xfs_attr_restore_rmt_blk(
    1214             :         struct xfs_da_args      *args)
    1215             : {
    1216    17914451 :         args->blkno = args->blkno2;
    1217    17914451 :         args->index = args->index2;
    1218    17914451 :         args->rmtblkno = args->rmtblkno2;
    1219    17914451 :         args->rmtblkcnt = args->rmtblkcnt2;
    1220    17914451 :         args->rmtvaluelen = args->rmtvaluelen2;
    1221    17914451 : }
    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    77010041 : xfs_attr_leaf_try_add(
    1235             :         struct xfs_da_args      *args)
    1236             : {
    1237    77010041 :         struct xfs_buf          *bp;
    1238    77010041 :         int                     error;
    1239             : 
    1240    77010041 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
    1241    77061878 :         if (error)
    1242             :                 return error;
    1243             : 
    1244             :         /*
    1245             :          * Look up the xattr name to set the insertion point for the new xattr.
    1246             :          */
    1247    77063682 :         error = xfs_attr3_leaf_lookup_int(bp, args);
    1248    77073075 :         switch (error) {
    1249    59510436 :         case -ENOATTR:
    1250    59510436 :                 if (args->op_flags & XFS_DA_OP_REPLACE)
    1251           0 :                         goto out_brelse;
    1252             :                 break;
    1253    17562639 :         case -EEXIST:
    1254    17562639 :                 if (!(args->op_flags & XFS_DA_OP_REPLACE))
    1255           0 :                         goto out_brelse;
    1256             : 
    1257    17562639 :                 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    17560598 :                 xfs_attr_save_rmt_blk(args);
    1264             :                 break;
    1265             :         case 0:
    1266             :                 break;
    1267           0 :         default:
    1268           0 :                 goto out_brelse;
    1269             :         }
    1270             : 
    1271    77071034 :         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   169698003 : xfs_attr_leaf_hasname(
    1283             :         struct xfs_da_args      *args,
    1284             :         struct xfs_buf          **bp)
    1285             : {
    1286   169698003 :         int                     error = 0;
    1287             : 
    1288   169698003 :         error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, bp);
    1289   169737446 :         if (error)
    1290             :                 return error;
    1291             : 
    1292   169746093 :         error = xfs_attr3_leaf_lookup_int(*bp, args);
    1293   169728473 :         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    30344123 : xfs_attr_leaf_removename(
    1307             :         struct xfs_da_args      *args)
    1308             : {
    1309    30344123 :         struct xfs_inode        *dp;
    1310    30344123 :         struct xfs_buf          *bp;
    1311    30344123 :         int                     error, forkoff;
    1312             : 
    1313    30344123 :         trace_xfs_attr_leaf_removename(args);
    1314             : 
    1315             :         /*
    1316             :          * Remove the attribute.
    1317             :          */
    1318    30333735 :         dp = args->dp;
    1319             : 
    1320    30333735 :         error = xfs_attr_leaf_hasname(args, &bp);
    1321    30367152 :         if (error == -ENOATTR) {
    1322          33 :                 xfs_trans_brelse(args->trans, bp);
    1323          33 :                 if (args->op_flags & XFS_DA_OP_RECOVERY)
    1324             :                         return 0;
    1325           0 :                 return error;
    1326    30367119 :         } else if (error != -EEXIST)
    1327             :                 return error;
    1328             : 
    1329    30365096 :         xfs_attr3_leaf_remove(bp, args);
    1330             : 
    1331             :         /*
    1332             :          * If the result is small enough, shrink it all into the inode.
    1333             :          */
    1334    30359079 :         forkoff = xfs_attr_shortform_allfit(bp, dp);
    1335    30359468 :         if (forkoff)
    1336     2059103 :                 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    17112156 : xfs_attr_leaf_get(xfs_da_args_t *args)
    1352             : {
    1353    17112156 :         struct xfs_buf *bp;
    1354    17112156 :         int error;
    1355             : 
    1356    17112156 :         trace_xfs_attr_leaf_get(args);
    1357             : 
    1358    17108916 :         error = xfs_attr_leaf_hasname(args, &bp);
    1359             : 
    1360    17112045 :         if (error == -ENOATTR)  {
    1361     6022573 :                 xfs_trans_brelse(args->trans, bp);
    1362     6022573 :                 return error;
    1363    11089472 :         } else if (error != -EEXIST)
    1364             :                 return error;
    1365             : 
    1366             : 
    1367    11087803 :         error = xfs_attr3_leaf_getvalue(bp, args);
    1368    11078450 :         xfs_trans_brelse(args->trans, bp);
    1369    11078450 :         return error;
    1370             : }
    1371             : 
    1372             : /* Return EEXIST if attr is found, or ENOATTR if not. */
    1373             : STATIC int
    1374     6636820 : xfs_attr_node_lookup(
    1375             :         struct xfs_da_args      *args,
    1376             :         struct xfs_da_state     *state)
    1377             : {
    1378     6636820 :         int                     retval, error;
    1379             : 
    1380             :         /*
    1381             :          * Search to see if name exists, and get back a pointer to it.
    1382             :          */
    1383     6636820 :         error = xfs_da3_node_lookup_int(state, &retval);
    1384     6636939 :         if (error)
    1385             :                 return error;
    1386             : 
    1387     6636919 :         return retval;
    1388             : }
    1389             : 
    1390             : /*========================================================================
    1391             :  * External routines when attribute list size > geo->blksize
    1392             :  *========================================================================*/
    1393             : 
    1394             : STATIC int
    1395     2160654 : xfs_attr_node_addname_find_attr(
    1396             :          struct xfs_attr_intent *attr)
    1397             : {
    1398     2160654 :         struct xfs_da_args      *args = attr->xattri_da_args;
    1399     2160654 :         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     2160654 :         xfs_attr_item_init_da_state(attr);
    1406     2160724 :         error = xfs_attr_node_lookup(args, attr->xattri_da_state);
    1407     2160786 :         switch (error) {
    1408     1802677 :         case -ENOATTR:
    1409     1802677 :                 if (args->op_flags & XFS_DA_OP_REPLACE)
    1410           0 :                         goto error;
    1411             :                 break;
    1412      358109 :         case -EEXIST:
    1413      358109 :                 if (!(args->op_flags & XFS_DA_OP_REPLACE))
    1414           0 :                         goto error;
    1415             : 
    1416             : 
    1417      358109 :                 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      358108 :                 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     2160743 : xfs_attr_node_try_addname(
    1449             :         struct xfs_attr_intent          *attr)
    1450             : {
    1451     2160743 :         struct xfs_da_state             *state = attr->xattri_da_state;
    1452     2160743 :         struct xfs_da_state_blk         *blk;
    1453     2160743 :         int                             error;
    1454             : 
    1455     2160743 :         trace_xfs_attr_node_addname(state->args);
    1456             : 
    1457     2160731 :         blk = &state->path.blk[state->path.active-1];
    1458     2160730 :         ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
    1459             : 
    1460     2160730 :         error = xfs_attr3_leaf_add(blk->bp, state->args);
    1461     2160732 :         if (error == -ENOSPC) {
    1462      143329 :                 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      143329 :                 error = xfs_da3_split(state);
    1478      143329 :                 if (error)
    1479          11 :                         goto out;
    1480             :         } else {
    1481             :                 /*
    1482             :                  * Addition succeeded, update Btree hashvals.
    1483             :                  */
    1484     2017403 :                 xfs_da3_fixhashpath(state, &state->path);
    1485             :         }
    1486             : 
    1487     2160739 : out:
    1488     2160739 :         xfs_da_state_free(state);
    1489     2160736 :         attr->xattri_da_state = NULL;
    1490     2160736 :         return error;
    1491             : }
    1492             : 
    1493             : static int
    1494     1047063 : xfs_attr_node_removename(
    1495             :         struct xfs_da_args      *args,
    1496             :         struct xfs_da_state     *state)
    1497             : {
    1498     1047063 :         struct xfs_da_state_blk *blk;
    1499     1047063 :         int                     retval;
    1500             : 
    1501             :         /*
    1502             :          * Remove the name and update the hashvals in the tree.
    1503             :          */
    1504     1047063 :         blk = &state->path.blk[state->path.active-1];
    1505     1047063 :         ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
    1506     1047063 :         retval = xfs_attr3_leaf_remove(blk->bp, args);
    1507     1047062 :         xfs_da3_fixhashpath(state, &state->path);
    1508             : 
    1509     1047063 :         return retval;
    1510             : }
    1511             : 
    1512             : static int
    1513     1047064 : xfs_attr_node_remove_attr(
    1514             :         struct xfs_attr_intent          *attr)
    1515             : {
    1516     1047064 :         struct xfs_da_args              *args = attr->xattri_da_args;
    1517     1047064 :         struct xfs_da_state             *state = xfs_da_state_alloc(args);
    1518     1047071 :         int                             retval = 0;
    1519     1047071 :         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     1047071 :         args->attr_filter |= XFS_ATTR_INCOMPLETE;
    1527     1047071 :         error = xfs_da3_node_lookup_int(state, &retval);
    1528     1047069 :         if (error)
    1529           0 :                 goto out;
    1530             : 
    1531     1047069 :         error = xfs_attr_node_removename(args, state);
    1532             : 
    1533             :         /*
    1534             :          * Check to see if the tree needs to be collapsed.
    1535             :          */
    1536     1047051 :         if (retval && (state->path.active > 1)) {
    1537     1044672 :                 error = xfs_da3_join(state);
    1538     1044668 :                 if (error)
    1539          10 :                         goto out;
    1540             :         }
    1541     1047037 :         retval = error = 0;
    1542             : 
    1543     1047047 : out:
    1544     1047047 :         xfs_da_state_free(state);
    1545     1047063 :         if (error)
    1546             :                 return error;
    1547     1047053 :         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      683471 : xfs_attr_node_get(
    1561             :         struct xfs_da_args      *args)
    1562             : {
    1563      683471 :         struct xfs_da_state     *state;
    1564      683471 :         struct xfs_da_state_blk *blk;
    1565      683471 :         int                     i;
    1566      683471 :         int                     error;
    1567             : 
    1568      683471 :         trace_xfs_attr_node_get(args);
    1569             : 
    1570             :         /*
    1571             :          * Search to see if name exists, and get back a pointer to it.
    1572             :          */
    1573      683471 :         state = xfs_da_state_alloc(args);
    1574      683479 :         error = xfs_attr_node_lookup(args, state);
    1575      683479 :         if (error != -EEXIST)
    1576      122081 :                 goto out_release;
    1577             : 
    1578             :         /*
    1579             :          * Get the value, local or "remote"
    1580             :          */
    1581      561398 :         blk = &state->path.blk[state->path.active - 1];
    1582      561397 :         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      683477 : out_release:
    1588     2052904 :         for (i = 0; i < state->path.active; i++) {
    1589     1369423 :                 xfs_trans_brelse(args->trans, state->path.blk[i].bp);
    1590     1369427 :                 state->path.blk[i].bp = NULL;
    1591             :         }
    1592             : 
    1593      683481 :         xfs_da_state_free(state);
    1594      683479 :         return error;
    1595             : }
    1596             : 
    1597             : /* Returns true if the attribute entry name is valid. */
    1598             : bool
    1599  6330383073 : xfs_attr_namecheck(
    1600             :         struct xfs_mount        *mp,
    1601             :         const void              *name,
    1602             :         size_t                  length,
    1603             :         unsigned int            flags)
    1604             : {
    1605  6330383073 :         if (flags & XFS_ATTR_PARENT)
    1606  1004676309 :                 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  5325706764 :         if (length >= MAXNAMELEN)
    1613             :                 return false;
    1614             : 
    1615             :         /* There shouldn't be any nulls here */
    1616 10651413528 :         return !memchr(name, 0, length);
    1617             : }
    1618             : 
    1619             : int __init
    1620          50 : xfs_attr_intent_init_cache(void)
    1621             : {
    1622          50 :         xfs_attr_intent_cache = kmem_cache_create("xfs_attr_intent",
    1623             :                         sizeof(struct xfs_attr_intent),
    1624             :                         0, 0, NULL);
    1625             : 
    1626          50 :         return xfs_attr_intent_cache != NULL ? 0 : -ENOMEM;
    1627             : }
    1628             : 
    1629             : void
    1630          49 : xfs_attr_intent_destroy_cache(void)
    1631             : {
    1632          49 :         kmem_cache_destroy(xfs_attr_intent_cache);
    1633          49 :         xfs_attr_intent_cache = NULL;
    1634          49 : }

Generated by: LCOV version 1.14