LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_attr.h (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-achx @ Mon Jul 31 20:08:12 PDT 2023 Lines: 20 20 100.0 %
Date: 2023-07-31 20:08:12 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0 */
       2             : /*
       3             :  * Copyright (c) 2000,2002-2003,2005 Silicon Graphics, Inc.
       4             :  * All Rights Reserved.
       5             :  */
       6             : #ifndef __XFS_ATTR_H__
       7             : #define __XFS_ATTR_H__
       8             : 
       9             : struct xfs_inode;
      10             : struct xfs_da_args;
      11             : struct xfs_attr_list_context;
      12             : 
      13             : /*
      14             :  * Large attribute lists are structured around Btrees where all the data
      15             :  * elements are in the leaf nodes.  Attribute names are hashed into an int,
      16             :  * then that int is used as the index into the Btree.  Since the hashval
      17             :  * of an attribute name may not be unique, we may have duplicate keys.
      18             :  * The internal links in the Btree are logical block offsets into the file.
      19             :  *
      20             :  * Small attribute lists use a different format and are packed as tightly
      21             :  * as possible so as to fit into the literal area of the inode.
      22             :  */
      23             : 
      24             : /*
      25             :  * The maximum size (into the kernel or returned from the kernel) of an
      26             :  * attribute value or the buffer used for an attr_list() call.  Larger
      27             :  * sizes will result in an ERANGE return code.
      28             :  */
      29             : #define ATTR_MAX_VALUELEN       (64*1024)       /* max length of a value */
      30             : 
      31             : /*
      32             :  * Kernel-internal version of the attrlist cursor.
      33             :  */
      34             : struct xfs_attrlist_cursor_kern {
      35             :         __u32   hashval;        /* hash value of next entry to add */
      36             :         __u32   blkno;          /* block containing entry (suggestion) */
      37             :         __u32   offset;         /* offset in list of equal-hashvals */
      38             :         __u16   pad1;           /* padding to match user-level */
      39             :         __u8    pad2;           /* padding to match user-level */
      40             :         __u8    initted;        /* T/F: cursor has been initialized */
      41             : };
      42             : 
      43             : 
      44             : /*========================================================================
      45             :  * Structure used to pass context around among the routines.
      46             :  *========================================================================*/
      47             : 
      48             : 
      49             : /* void; state communicated via *context */
      50             : typedef void (*put_listent_func_t)(struct xfs_attr_list_context *context,
      51             :                 int flags, unsigned char *name, int namelen, void *value,
      52             :                 int valuelen);
      53             : 
      54             : struct xfs_attr_list_context {
      55             :         struct xfs_trans        *tp;
      56             :         struct xfs_inode        *dp;            /* inode */
      57             :         struct xfs_attrlist_cursor_kern cursor; /* position in list */
      58             :         void                    *buffer;        /* output buffer */
      59             : 
      60             :         /*
      61             :          * Abort attribute list iteration if non-zero.  Can be used to pass
      62             :          * error values to the xfs_attr_list caller.
      63             :          */
      64             :         int                     seen_enough;
      65             :         bool                    allow_incomplete;
      66             : 
      67             :         ssize_t                 count;          /* num used entries */
      68             :         int                     dupcnt;         /* count dup hashvals seen */
      69             :         int                     bufsize;        /* total buffer size */
      70             :         int                     firstu;         /* first used byte in buffer */
      71             :         unsigned int            attr_filter;    /* XFS_ATTR_{ROOT,SECURE} */
      72             :         int                     resynch;        /* T/F: resynch with cursor */
      73             :         put_listent_func_t      put_listent;    /* list output fmt function */
      74             :         int                     index;          /* index into output buffer */
      75             : };
      76             : 
      77             : 
      78             : /*
      79             :  * ========================================================================
      80             :  * Structure used to pass context around among the delayed routines.
      81             :  * ========================================================================
      82             :  */
      83             : 
      84             : /*
      85             :  * Below is a state machine diagram for attr remove operations. The  XFS_DAS_*
      86             :  * states indicate places where the function would return -EAGAIN, and then
      87             :  * immediately resume from after being called by the calling function. States
      88             :  * marked as a "subroutine state" indicate that they belong to a subroutine, and
      89             :  * so the calling function needs to pass them back to that subroutine to allow
      90             :  * it to finish where it left off. But they otherwise do not have a role in the
      91             :  * calling function other than just passing through.
      92             :  *
      93             :  * xfs_attr_remove_iter()
      94             :  *              │
      95             :  *              v
      96             :  *        have attr to remove? ──n──> done
      97             :  *              │
      98             :  *              y
      99             :  *              │
     100             :  *              v
     101             :  *        are we short form? ──y──> xfs_attr_shortform_remove ──> done
     102             :  *              │
     103             :  *              n
     104             :  *              │
     105             :  *              V
     106             :  *        are we leaf form? ──y──> xfs_attr_leaf_removename ──> done
     107             :  *              │
     108             :  *              n
     109             :  *              │
     110             :  *              V
     111             :  *   ┌── need to setup state?
     112             :  *   │          │
     113             :  *   n          y
     114             :  *   │          │
     115             :  *   │          v
     116             :  *   │ find attr and get state
     117             :  *   │ attr has remote blks? ──n─┐
     118             :  *   │          │                v
     119             :  *   │          │         find and invalidate
     120             :  *   │          y         the remote blocks.
     121             :  *   │          │         mark attr incomplete
     122             :  *   │          ├────────────────┘
     123             :  *   └──────────┤
     124             :  *              │
     125             :  *              v
     126             :  *   Have remote blks to remove? ───y─────┐
     127             :  *              │        ^          remove the blks
     128             :  *              │        │                │
     129             :  *              │        │                v
     130             :  *              │  XFS_DAS_RMTBLK <─n── done?
     131             :  *              │  re-enter with          │
     132             :  *              │  one less blk to        y
     133             :  *              │      remove             │
     134             :  *              │                         V
     135             :  *              │                  refill the state
     136             :  *              n                         │
     137             :  *              │                         v
     138             :  *              │                   XFS_DAS_RM_NAME
     139             :  *              │                         │
     140             :  *              ├─────────────────────────┘
     141             :  *              │
     142             :  *              v
     143             :  *       remove leaf and
     144             :  *       update hash with
     145             :  *   xfs_attr_node_remove_cleanup
     146             :  *              │
     147             :  *              v
     148             :  *           need to
     149             :  *        shrink tree? ─n─┐
     150             :  *              │         │
     151             :  *              y         │
     152             :  *              │         │
     153             :  *              v         │
     154             :  *          join leaf     │
     155             :  *              │         │
     156             :  *              v         │
     157             :  *      XFS_DAS_RM_SHRINK │
     158             :  *              │         │
     159             :  *              v         │
     160             :  *       do the shrink    │
     161             :  *              │         │
     162             :  *              v         │
     163             :  *          free state <──┘
     164             :  *              │
     165             :  *              v
     166             :  *            done
     167             :  *
     168             :  *
     169             :  * Below is a state machine diagram for attr set operations.
     170             :  *
     171             :  * It seems the challenge with understanding this system comes from trying to
     172             :  * absorb the state machine all at once, when really one should only be looking
     173             :  * at it with in the context of a single function. Once a state sensitive
     174             :  * function is called, the idea is that it "takes ownership" of the
     175             :  * state machine. It isn't concerned with the states that may have belonged to
     176             :  * it's calling parent. Only the states relevant to itself or any other
     177             :  * subroutines there in. Once a calling function hands off the state machine to
     178             :  * a subroutine, it needs to respect the simple rule that it doesn't "own" the
     179             :  * state machine anymore, and it's the responsibility of that calling function
     180             :  * to propagate the -EAGAIN back up the call stack. Upon reentry, it is
     181             :  * committed to re-calling that subroutine until it returns something other than
     182             :  * -EAGAIN. Once that subroutine signals completion (by returning anything other
     183             :  * than -EAGAIN), the calling function can resume using the state machine.
     184             :  *
     185             :  *  xfs_attr_set_iter()
     186             :  *              │
     187             :  *              v
     188             :  *   ┌─y─ has an attr fork?
     189             :  *   │          |
     190             :  *   │          n
     191             :  *   │          |
     192             :  *   │          V
     193             :  *   │       add a fork
     194             :  *   │          │
     195             :  *   └──────────┤
     196             :  *              │
     197             :  *              V
     198             :  *   ┌─── is shortform?
     199             :  *   │          │
     200             :  *   │          y
     201             :  *   │          │
     202             :  *   │          V
     203             :  *   │   xfs_attr_set_fmt
     204             :  *   │          |
     205             :  *   │          V
     206             :  *   │ xfs_attr_try_sf_addname
     207             :  *   │          │
     208             :  *   │          V
     209             :  *   │      had enough ──y──> done
     210             :  *   │        space?
     211             :  *   n          │
     212             :  *   │          n
     213             :  *   │          │
     214             :  *   │          V
     215             :  *   │   transform to leaf
     216             :  *   │          │
     217             :  *   │          V
     218             :  *   │   hold the leaf buffer
     219             :  *   │          │
     220             :  *   │          V
     221             :  *   │     return -EAGAIN
     222             :  *   │      Re-enter in
     223             :  *   │       leaf form
     224             :  *   │
     225             :  *   └─> release leaf buffer
     226             :  *          if needed
     227             :  *              │
     228             :  *              V
     229             :  *   ┌───n── fork has
     230             :  *   │      only 1 blk?
     231             :  *   │          │
     232             :  *   │          y
     233             :  *   │          │
     234             :  *   │          v
     235             :  *   │ xfs_attr_leaf_try_add()
     236             :  *   │          │
     237             :  *   │          v
     238             :  *   │      had enough ──────────────y─────────────┐
     239             :  *   │        space?                               │
     240             :  *   │          │                                  │
     241             :  *   │          n                                  │
     242             :  *   │          │                                  │
     243             :  *   │          v                                  │
     244             :  *   │    return -EAGAIN                           │
     245             :  *   │      re-enter in                            │
     246             :  *   │        node form                            │
     247             :  *   │          │                                  │
     248             :  *   └──────────┤                                  │
     249             :  *              │                                  │
     250             :  *              V                                  │
     251             :  * xfs_attr_node_addname_find_attr                 │
     252             :  *        determines if this                       │
     253             :  *       is create or rename                       │
     254             :  *     find space to store attr                    │
     255             :  *              │                                  │
     256             :  *              v                                  │
     257             :  *     xfs_attr_node_addname                       │
     258             :  *              │                                  │
     259             :  *              v                                  │
     260             :  *   fits in a node leaf? ────n─────┐              │
     261             :  *              │     ^             v              │
     262             :  *              │     │       single leaf node?    │
     263             :  *              │     │         │            │     │
     264             :  *              y     │         y            n     │
     265             :  *              │     │         │            │     │
     266             :  *              v     │         v            v     │
     267             :  *            update  │    grow the leaf  split if │
     268             :  *           hashvals └── return -EAGAIN   needed  │
     269             :  *              │         retry leaf add     │     │
     270             :  *              │           on reentry       │     │
     271             :  *              ├────────────────────────────┘     │
     272             :  *              │                                  │
     273             :  *              v                                  │
     274             :  *         need to alloc                           │
     275             :  *   ┌─y── or flip flag?                           │
     276             :  *   │          │                                  │
     277             :  *   │          n                                  │
     278             :  *   │          │                                  │
     279             :  *   │          v                                  │
     280             :  *   │         done                                │
     281             :  *   │                                             │
     282             :  *   │                                             │
     283             :  *   │         XFS_DAS_FOUND_LBLK <────────────────┘
     284             :  *   │                  │
     285             :  *   │                  V
     286             :  *   │        xfs_attr_leaf_addname()
     287             :  *   │                  │
     288             :  *   │                  v
     289             :  *   │      ┌──first time through?
     290             :  *   │      │          │
     291             :  *   │      │          y
     292             :  *   │      │          │
     293             :  *   │      n          v
     294             :  *   │      │    if we have rmt blks
     295             :  *   │      │    find space for them
     296             :  *   │      │          │
     297             :  *   │      └──────────┤
     298             :  *   │                 │
     299             :  *   │                 v
     300             :  *   │            still have
     301             :  *   │      ┌─n─ blks to alloc? <──┐
     302             :  *   │      │          │           │
     303             :  *   │      │          y           │
     304             :  *   │      │          │           │
     305             :  *   │      │          v           │
     306             :  *   │      │     alloc one blk    │
     307             :  *   │      │     return -EAGAIN ──┘
     308             :  *   │      │    re-enter with one
     309             :  *   │      │    less blk to alloc
     310             :  *   │      │
     311             :  *   │      │
     312             :  *   │      └───> set the rmt
     313             :  *   │               value
     314             :  *   │                 │
     315             :  *   │                 v
     316             :  *   │               was this
     317             :  *   │              a rename? ──n─┐
     318             :  *   │                 │          │
     319             :  *   │                 y          │
     320             :  *   │                 │          │
     321             :  *   │                 v          │
     322             :  *   │           flip incomplete  │
     323             :  *   │               flag         │
     324             :  *   │                 │          │
     325             :  *   │                 v          │
     326             :  *   │         XFS_DAS_FLIP_LFLAG │
     327             :  *   │                 │          │
     328             :  *   │                 v          │
     329             :  *   │          need to remove    │
     330             :  *   │              old bks? ──n──┤
     331             :  *   │                 │          │
     332             :  *   │                 y          │
     333             :  *   │                 │          │
     334             :  *   │                 V          │
     335             :  *   │               remove       │
     336             :  *   │        ┌───> old blks      │
     337             :  *   │        │        │          │
     338             :  *   │ XFS_DAS_RM_LBLK │          │
     339             :  *   │        ^        │          │
     340             :  *   │        │        v          │
     341             :  *   │        └──y── more to      │
     342             :  *   │              remove?       │
     343             :  *   │                 │          │
     344             :  *   │                 n          │
     345             :  *   │                 │          │
     346             :  *   │                 v          │
     347             :  *   │          XFS_DAS_RD_LEAF   │
     348             :  *   │                 │          │
     349             :  *   │                 v          │
     350             :  *   │            remove leaf     │
     351             :  *   │                 │          │
     352             :  *   │                 v          │
     353             :  *   │            shrink to sf    │
     354             :  *   │             if needed      │
     355             :  *   │                 │          │
     356             :  *   │                 v          │
     357             :  *   │                done <──────┘
     358             :  *   │
     359             :  *   └──────> XFS_DAS_FOUND_NBLK
     360             :  *                     │
     361             :  *                     v
     362             :  *       ┌─────n──  need to
     363             :  *       │        alloc blks?
     364             :  *       │             │
     365             :  *       │             y
     366             :  *       │             │
     367             :  *       │             v
     368             :  *       │        find space
     369             :  *       │             │
     370             :  *       │             v
     371             :  *       │  ┌─>XFS_DAS_ALLOC_NODE
     372             :  *       │  │          │
     373             :  *       │  │          v
     374             :  *       │  │      alloc blk
     375             :  *       │  │          │
     376             :  *       │  │          v
     377             :  *       │  └──y── need to alloc
     378             :  *       │         more blocks?
     379             :  *       │             │
     380             :  *       │             n
     381             :  *       │             │
     382             :  *       │             v
     383             :  *       │      set the rmt value
     384             :  *       │             │
     385             :  *       │             v
     386             :  *       │          was this
     387             :  *       └────────> a rename? ──n─┐
     388             :  *                     │          │
     389             :  *                     y          │
     390             :  *                     │          │
     391             :  *                     v          │
     392             :  *               flip incomplete  │
     393             :  *                   flag         │
     394             :  *                     │          │
     395             :  *                     v          │
     396             :  *             XFS_DAS_FLIP_NFLAG │
     397             :  *                     │          │
     398             :  *                     v          │
     399             :  *                 need to        │
     400             :  *               remove blks? ─n──┤
     401             :  *                     │          │
     402             :  *                     y          │
     403             :  *                     │          │
     404             :  *                     v          │
     405             :  *                   remove       │
     406             :  *        ┌────────> old blks     │
     407             :  *        │            │          │
     408             :  *  XFS_DAS_RM_NBLK    │          │
     409             :  *        ^            │          │
     410             :  *        │            v          │
     411             :  *        └──────y── more to      │
     412             :  *                   remove       │
     413             :  *                     │          │
     414             :  *                     n          │
     415             :  *                     │          │
     416             :  *                     v          │
     417             :  *              XFS_DAS_CLR_FLAG  │
     418             :  *                     │          │
     419             :  *                     v          │
     420             :  *                clear flags     │
     421             :  *                     │          │
     422             :  *                     ├──────────┘
     423             :  *                     │
     424             :  *                     v
     425             :  *                   done
     426             :  */
     427             : 
     428             : /*
     429             :  * Enum values for xfs_attr_intent.xattri_da_state
     430             :  *
     431             :  * These values are used by delayed attribute operations to keep track  of where
     432             :  * they were before they returned -EAGAIN.  A return code of -EAGAIN signals the
     433             :  * calling function to roll the transaction, and then call the subroutine to
     434             :  * finish the operation.  The enum is then used by the subroutine to jump back
     435             :  * to where it was and resume executing where it left off.
     436             :  */
     437             : enum xfs_delattr_state {
     438             :         XFS_DAS_UNINIT          = 0,    /* No state has been set yet */
     439             : 
     440             :         /*
     441             :          * Initial sequence states. The replace setup code relies on the
     442             :          * ADD and REMOVE states for a specific format to be sequential so
     443             :          * that we can transform the initial operation to be performed
     444             :          * according to the xfs_has_larp() state easily.
     445             :          */
     446             :         XFS_DAS_SF_ADD,                 /* Initial sf add state */
     447             :         XFS_DAS_SF_REMOVE,              /* Initial sf replace/remove state */
     448             : 
     449             :         XFS_DAS_LEAF_ADD,               /* Initial leaf add state */
     450             :         XFS_DAS_LEAF_REMOVE,            /* Initial leaf replace/remove state */
     451             : 
     452             :         XFS_DAS_NODE_ADD,               /* Initial node add state */
     453             :         XFS_DAS_NODE_REMOVE,            /* Initial node replace/remove state */
     454             : 
     455             :         /* Leaf state set/replace/remove sequence */
     456             :         XFS_DAS_LEAF_SET_RMT,           /* set a remote xattr from a leaf */
     457             :         XFS_DAS_LEAF_ALLOC_RMT,         /* We are allocating remote blocks */
     458             :         XFS_DAS_LEAF_REPLACE,           /* Perform replace ops on a leaf */
     459             :         XFS_DAS_LEAF_REMOVE_OLD,        /* Start removing old attr from leaf */
     460             :         XFS_DAS_LEAF_REMOVE_RMT,        /* A rename is removing remote blocks */
     461             :         XFS_DAS_LEAF_REMOVE_ATTR,       /* Remove the old attr from a leaf */
     462             : 
     463             :         /* Node state sequence, must match leaf state above */
     464             :         XFS_DAS_NODE_SET_RMT,           /* set a remote xattr from a node */
     465             :         XFS_DAS_NODE_ALLOC_RMT,         /* We are allocating remote blocks */
     466             :         XFS_DAS_NODE_REPLACE,           /* Perform replace ops on a node */
     467             :         XFS_DAS_NODE_REMOVE_OLD,        /* Start removing old attr from node */
     468             :         XFS_DAS_NODE_REMOVE_RMT,        /* A rename is removing remote blocks */
     469             :         XFS_DAS_NODE_REMOVE_ATTR,       /* Remove the old attr from a node */
     470             : 
     471             :         XFS_DAS_DONE,                   /* finished operation */
     472             : };
     473             : 
     474             : #define XFS_DAS_STRINGS \
     475             :         { XFS_DAS_UNINIT,               "XFS_DAS_UNINIT" }, \
     476             :         { XFS_DAS_SF_ADD,               "XFS_DAS_SF_ADD" }, \
     477             :         { XFS_DAS_SF_REMOVE,            "XFS_DAS_SF_REMOVE" }, \
     478             :         { XFS_DAS_LEAF_ADD,             "XFS_DAS_LEAF_ADD" }, \
     479             :         { XFS_DAS_LEAF_REMOVE,          "XFS_DAS_LEAF_REMOVE" }, \
     480             :         { XFS_DAS_NODE_ADD,             "XFS_DAS_NODE_ADD" }, \
     481             :         { XFS_DAS_NODE_REMOVE,          "XFS_DAS_NODE_REMOVE" }, \
     482             :         { XFS_DAS_LEAF_SET_RMT,         "XFS_DAS_LEAF_SET_RMT" }, \
     483             :         { XFS_DAS_LEAF_ALLOC_RMT,       "XFS_DAS_LEAF_ALLOC_RMT" }, \
     484             :         { XFS_DAS_LEAF_REPLACE,         "XFS_DAS_LEAF_REPLACE" }, \
     485             :         { XFS_DAS_LEAF_REMOVE_OLD,      "XFS_DAS_LEAF_REMOVE_OLD" }, \
     486             :         { XFS_DAS_LEAF_REMOVE_RMT,      "XFS_DAS_LEAF_REMOVE_RMT" }, \
     487             :         { XFS_DAS_LEAF_REMOVE_ATTR,     "XFS_DAS_LEAF_REMOVE_ATTR" }, \
     488             :         { XFS_DAS_NODE_SET_RMT,         "XFS_DAS_NODE_SET_RMT" }, \
     489             :         { XFS_DAS_NODE_ALLOC_RMT,       "XFS_DAS_NODE_ALLOC_RMT" },  \
     490             :         { XFS_DAS_NODE_REPLACE,         "XFS_DAS_NODE_REPLACE" },  \
     491             :         { XFS_DAS_NODE_REMOVE_OLD,      "XFS_DAS_NODE_REMOVE_OLD" }, \
     492             :         { XFS_DAS_NODE_REMOVE_RMT,      "XFS_DAS_NODE_REMOVE_RMT" }, \
     493             :         { XFS_DAS_NODE_REMOVE_ATTR,     "XFS_DAS_NODE_REMOVE_ATTR" }, \
     494             :         { XFS_DAS_DONE,                 "XFS_DAS_DONE" }
     495             : 
     496             : struct xfs_attri_log_nameval;
     497             : 
     498             : /*
     499             :  * Context used for keeping track of delayed attribute operations
     500             :  */
     501             : struct xfs_attr_intent {
     502             :         /*
     503             :          * used to log this item to an intent containing a list of attrs to
     504             :          * commit later
     505             :          */
     506             :         struct list_head                xattri_list;
     507             : 
     508             :         /* Used in xfs_attr_node_removename to roll through removing blocks */
     509             :         struct xfs_da_state             *xattri_da_state;
     510             : 
     511             :         struct xfs_da_args              *xattri_da_args;
     512             : 
     513             :         /*
     514             :          * Shared buffer containing the attr name, new name, and value so that
     515             :          * the logging code can share large memory buffers between log items.
     516             :          */
     517             :         struct xfs_attri_log_nameval    *xattri_nameval;
     518             : 
     519             :         /* Used to keep track of current state of delayed operation */
     520             :         enum xfs_delattr_state          xattri_dela_state;
     521             : 
     522             :         /*
     523             :          * Attr operation being performed - XFS_ATTRI_OP_FLAGS_*
     524             :          */
     525             :         unsigned int                    xattri_op_flags;
     526             : 
     527             :         /* Used in xfs_attr_rmtval_set_blk to roll through allocating blocks */
     528             :         xfs_dablk_t                     xattri_lblkno;
     529             :         int                             xattri_blkcnt;
     530             :         struct xfs_bmbt_irec            xattri_map;
     531             : };
     532             : 
     533             : static inline unsigned int
     534             : xfs_attr_intent_op(const struct xfs_attr_intent *attr)
     535             : {
     536    75582725 :         return attr->xattri_op_flags & XFS_ATTRI_OP_FLAGS_TYPE_MASK;
     537             : }
     538             : 
     539             : /*========================================================================
     540             :  * Function prototypes for the kernel.
     541             :  *========================================================================*/
     542             : 
     543             : /*
     544             :  * Overall external interface routines.
     545             :  */
     546             : int xfs_attr_inactive(struct xfs_inode *dp);
     547             : int xfs_attr_list_ilocked(struct xfs_attr_list_context *);
     548             : int xfs_attr_list(struct xfs_attr_list_context *);
     549             : int xfs_inode_hasattr(struct xfs_inode *ip);
     550             : bool xfs_attr_is_leaf(struct xfs_inode *ip);
     551             : int xfs_attr_get_ilocked(struct xfs_da_args *args);
     552             : int xfs_attr_get(struct xfs_da_args *args);
     553             : int xfs_attr_defer_add(struct xfs_da_args *args);
     554             : int xfs_attr_defer_remove(struct xfs_da_args *args);
     555             : int xfs_attr_defer_replace(struct xfs_da_args *args);
     556             : int xfs_attr_set(struct xfs_da_args *args);
     557             : int xfs_attr_set_iter(struct xfs_attr_intent *attr);
     558             : int xfs_attr_remove_iter(struct xfs_attr_intent *attr);
     559             : bool xfs_attr_namecheck(struct xfs_mount *mp, const void *name, size_t length,
     560             :                 unsigned int flags);
     561             : int xfs_attr_calc_size(struct xfs_da_args *args, int *local);
     562             : void xfs_init_attr_trans(struct xfs_da_args *args, struct xfs_trans_res *tres,
     563             :                          unsigned int *total);
     564             : int xfs_attr_intent_init(struct xfs_da_args *args, unsigned int op_flags,
     565             :                          struct xfs_attr_intent  **attr);
     566             : /*
     567             :  * Check to see if the attr should be upgraded from non-existent or shortform to
     568             :  * single-leaf-block attribute list.
     569             :  */
     570             : static inline bool
     571             : xfs_attr_is_shortform(
     572             :         struct xfs_inode    *ip)
     573             : {
     574   249265405 :         return ip->i_af.if_format == XFS_DINODE_FMT_LOCAL ||
     575   248966425 :                (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
     576   248966425 :                 ip->i_af.if_nextents == 0);
     577             : }
     578             : 
     579             : static inline enum xfs_delattr_state
     580   388606300 : xfs_attr_init_add_state(struct xfs_da_args *args)
     581             : {
     582             :         /*
     583             :          * When called from the completion of a attr remove to determine the
     584             :          * next state, the attribute fork may be null. This can occur only occur
     585             :          * on a pure remove, but we grab the next state before we check if a
     586             :          * replace operation is being performed. If we are called from any other
     587             :          * context, i_af is guaranteed to exist. Hence if the attr fork is
     588             :          * null, we were called from a pure remove operation and so we are done.
     589             :          */
     590   388606300 :         if (!xfs_inode_has_attr_fork(args->dp))
     591             :                 return XFS_DAS_DONE;
     592             : 
     593   388579726 :         args->op_flags |= XFS_DA_OP_ADDNAME;
     594   606797779 :         if (xfs_attr_is_shortform(args->dp))
     595             :                 return XFS_DAS_SF_ADD;
     596   119462945 :         if (xfs_attr_is_leaf(args->dp))
     597   116365844 :                 return XFS_DAS_LEAF_ADD;
     598             :         return XFS_DAS_NODE_ADD;
     599             : }
     600             : 
     601             : static inline enum xfs_delattr_state
     602   154151990 : xfs_attr_init_remove_state(struct xfs_da_args *args)
     603             : {
     604   154151990 :         args->op_flags |= XFS_DA_OP_REMOVE;
     605   185199342 :         if (xfs_attr_is_shortform(args->dp))
     606             :                 return XFS_DAS_SF_REMOVE;
     607    31039906 :         if (xfs_attr_is_leaf(args->dp))
     608    30360028 :                 return XFS_DAS_LEAF_REMOVE;
     609             :         return XFS_DAS_NODE_REMOVE;
     610             : }
     611             : 
     612             : /*
     613             :  * If we are logging the attributes, then we have to start with removal of the
     614             :  * old attribute so that there is always consistent state that we can recover
     615             :  * from if the system goes down part way through. We always log the new attr
     616             :  * value, so even when we remove the attr first we still have the information in
     617             :  * the log to finish the replace operation atomically.
     618             :  */
     619             : static inline enum xfs_delattr_state
     620    82886461 : xfs_attr_init_replace_state(struct xfs_da_args *args)
     621             : {
     622    82886461 :         args->op_flags |= XFS_DA_OP_ADDNAME | XFS_DA_OP_REPLACE;
     623    82886461 :         if (args->op_flags & XFS_DA_OP_LOGGED)
     624    57676813 :                 return xfs_attr_init_remove_state(args);
     625    25209648 :         return xfs_attr_init_add_state(args);
     626             : }
     627             : 
     628             : extern struct kmem_cache *xfs_attr_intent_cache;
     629             : int __init xfs_attr_intent_init_cache(void);
     630             : void xfs_attr_intent_destroy_cache(void);
     631             : 
     632             : int xfs_attr_sf_totsize(struct xfs_inode *dp);
     633             : 
     634             : #endif  /* __XFS_ATTR_H__ */

Generated by: LCOV version 1.14