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

Generated by: LCOV version 1.14