xref: /linux/fs/xfs/libxfs/xfs_attr.h (revision bbeb1219eeeeab7ef302fdaedee71b08e413a04c)
1508578f2SNishad Kamdar /* SPDX-License-Identifier: GPL-2.0 */
2e2421f0bSAllison Henderson /*
3e2421f0bSAllison Henderson  * Copyright (c) 2000,2002-2003,2005 Silicon Graphics, Inc.
4e2421f0bSAllison Henderson  * All Rights Reserved.
5e2421f0bSAllison Henderson  */
6e2421f0bSAllison Henderson #ifndef __XFS_ATTR_H__
7e2421f0bSAllison Henderson #define	__XFS_ATTR_H__
8e2421f0bSAllison Henderson 
9e2421f0bSAllison Henderson struct xfs_inode;
10e2421f0bSAllison Henderson struct xfs_da_args;
11e2421f0bSAllison Henderson struct xfs_attr_list_context;
12e2421f0bSAllison Henderson 
13e2421f0bSAllison Henderson /*
14e2421f0bSAllison Henderson  * Large attribute lists are structured around Btrees where all the data
15e2421f0bSAllison Henderson  * elements are in the leaf nodes.  Attribute names are hashed into an int,
16e2421f0bSAllison Henderson  * then that int is used as the index into the Btree.  Since the hashval
17e2421f0bSAllison Henderson  * of an attribute name may not be unique, we may have duplicate keys.
18e2421f0bSAllison Henderson  * The internal links in the Btree are logical block offsets into the file.
19e2421f0bSAllison Henderson  *
20e2421f0bSAllison Henderson  * Small attribute lists use a different format and are packed as tightly
21e2421f0bSAllison Henderson  * as possible so as to fit into the literal area of the inode.
22e2421f0bSAllison Henderson  */
23e2421f0bSAllison Henderson 
24e2421f0bSAllison Henderson /*
25e2421f0bSAllison Henderson  * The maximum size (into the kernel or returned from the kernel) of an
26e2421f0bSAllison Henderson  * attribute value or the buffer used for an attr_list() call.  Larger
27e2421f0bSAllison Henderson  * sizes will result in an ERANGE return code.
28e2421f0bSAllison Henderson  */
29e2421f0bSAllison Henderson #define	ATTR_MAX_VALUELEN	(64*1024)	/* max length of a value */
30e2421f0bSAllison Henderson 
31e2421f0bSAllison Henderson /*
32e2421f0bSAllison Henderson  * Kernel-internal version of the attrlist cursor.
33e2421f0bSAllison Henderson  */
34e3a19cdeSChristoph Hellwig struct xfs_attrlist_cursor_kern {
35e2421f0bSAllison Henderson 	__u32	hashval;	/* hash value of next entry to add */
36e2421f0bSAllison Henderson 	__u32	blkno;		/* block containing entry (suggestion) */
37e2421f0bSAllison Henderson 	__u32	offset;		/* offset in list of equal-hashvals */
38e2421f0bSAllison Henderson 	__u16	pad1;		/* padding to match user-level */
39e2421f0bSAllison Henderson 	__u8	pad2;		/* padding to match user-level */
40e2421f0bSAllison Henderson 	__u8	initted;	/* T/F: cursor has been initialized */
41e3a19cdeSChristoph Hellwig };
42e2421f0bSAllison Henderson 
43e2421f0bSAllison Henderson 
44e2421f0bSAllison Henderson /*========================================================================
45e2421f0bSAllison Henderson  * Structure used to pass context around among the routines.
46e2421f0bSAllison Henderson  *========================================================================*/
47e2421f0bSAllison Henderson 
48e2421f0bSAllison Henderson 
49e2421f0bSAllison Henderson /* void; state communicated via *context */
508f4b980eSAllison Henderson typedef void (*put_listent_func_t)(struct xfs_attr_list_context *context,
518f4b980eSAllison Henderson 		int flags, unsigned char *name, int namelen, void *value,
528f4b980eSAllison Henderson 		int valuelen);
53e2421f0bSAllison Henderson 
54a9c8c69bSChristoph Hellwig struct xfs_attr_list_context {
55e2421f0bSAllison Henderson 	struct xfs_trans	*tp;
56e2421f0bSAllison Henderson 	struct xfs_inode	*dp;		/* inode */
57e3a19cdeSChristoph Hellwig 	struct xfs_attrlist_cursor_kern cursor;	/* position in list */
58a9c8c69bSChristoph Hellwig 	void			*buffer;	/* output buffer */
592c3b83d7SDarrick J. Wong 
602c3b83d7SDarrick J. Wong 	/*
612c3b83d7SDarrick J. Wong 	 * Abort attribute list iteration if non-zero.  Can be used to pass
622c3b83d7SDarrick J. Wong 	 * error values to the xfs_attr_list caller.
632c3b83d7SDarrick J. Wong 	 */
642c3b83d7SDarrick J. Wong 	int			seen_enough;
655e813574SChristoph Hellwig 	bool			allow_incomplete;
662c3b83d7SDarrick J. Wong 
67e2421f0bSAllison Henderson 	ssize_t			count;		/* num used entries */
68e2421f0bSAllison Henderson 	int			dupcnt;		/* count dup hashvals seen */
69e2421f0bSAllison Henderson 	int			bufsize;	/* total buffer size */
70e2421f0bSAllison Henderson 	int			firstu;		/* first used byte in buffer */
71d5f0f49aSChristoph Hellwig 	unsigned int		attr_filter;	/* XFS_ATTR_{ROOT,SECURE} */
72e2421f0bSAllison Henderson 	int			resynch;	/* T/F: resynch with cursor */
73e2421f0bSAllison Henderson 	put_listent_func_t	put_listent;	/* list output fmt function */
74e2421f0bSAllison Henderson 	int			index;		/* index into output buffer */
75a9c8c69bSChristoph Hellwig };
76e2421f0bSAllison Henderson 
77e2421f0bSAllison Henderson 
782b74b03cSAllison Henderson /*
792b74b03cSAllison Henderson  * ========================================================================
802b74b03cSAllison Henderson  * Structure used to pass context around among the delayed routines.
812b74b03cSAllison Henderson  * ========================================================================
822b74b03cSAllison Henderson  */
832b74b03cSAllison Henderson 
842b74b03cSAllison Henderson /*
852b74b03cSAllison Henderson  * Below is a state machine diagram for attr remove operations. The  XFS_DAS_*
862b74b03cSAllison Henderson  * states indicate places where the function would return -EAGAIN, and then
872b74b03cSAllison Henderson  * immediately resume from after being called by the calling function. States
882b74b03cSAllison Henderson  * marked as a "subroutine state" indicate that they belong to a subroutine, and
892b74b03cSAllison Henderson  * so the calling function needs to pass them back to that subroutine to allow
902b74b03cSAllison Henderson  * it to finish where it left off. But they otherwise do not have a role in the
912b74b03cSAllison Henderson  * calling function other than just passing through.
922b74b03cSAllison Henderson  *
932b74b03cSAllison Henderson  * xfs_attr_remove_iter()
942b74b03cSAllison Henderson  *              │
952b74b03cSAllison Henderson  *              v
962b74b03cSAllison Henderson  *        have attr to remove? ──n──> done
972b74b03cSAllison Henderson  *              │
982b74b03cSAllison Henderson  *              y
992b74b03cSAllison Henderson  *              │
1002b74b03cSAllison Henderson  *              v
1012b74b03cSAllison Henderson  *        are we short form? ──y──> xfs_attr_shortform_remove ──> done
1022b74b03cSAllison Henderson  *              │
1032b74b03cSAllison Henderson  *              n
1042b74b03cSAllison Henderson  *              │
1052b74b03cSAllison Henderson  *              V
1062b74b03cSAllison Henderson  *        are we leaf form? ──y──> xfs_attr_leaf_removename ──> done
1072b74b03cSAllison Henderson  *              │
1082b74b03cSAllison Henderson  *              n
1092b74b03cSAllison Henderson  *              │
1102b74b03cSAllison Henderson  *              V
1112b74b03cSAllison Henderson  *   ┌── need to setup state?
1122b74b03cSAllison Henderson  *   │          │
1132b74b03cSAllison Henderson  *   n          y
1142b74b03cSAllison Henderson  *   │          │
1152b74b03cSAllison Henderson  *   │          v
1162b74b03cSAllison Henderson  *   │ find attr and get state
1172b74b03cSAllison Henderson  *   │ attr has remote blks? ──n─┐
1182b74b03cSAllison Henderson  *   │          │                v
1192b74b03cSAllison Henderson  *   │          │         find and invalidate
1202b74b03cSAllison Henderson  *   │          y         the remote blocks.
1212b74b03cSAllison Henderson  *   │          │         mark attr incomplete
1222b74b03cSAllison Henderson  *   │          ├────────────────┘
1232b74b03cSAllison Henderson  *   └──────────┤
1242b74b03cSAllison Henderson  *              │
1252b74b03cSAllison Henderson  *              v
1262b74b03cSAllison Henderson  *   Have remote blks to remove? ───y─────┐
1272b74b03cSAllison Henderson  *              │        ^          remove the blks
1282b74b03cSAllison Henderson  *              │        │                │
1292b74b03cSAllison Henderson  *              │        │                v
1302b74b03cSAllison Henderson  *              │  XFS_DAS_RMTBLK <─n── done?
1312b74b03cSAllison Henderson  *              │  re-enter with          │
1322b74b03cSAllison Henderson  *              │  one less blk to        y
1332b74b03cSAllison Henderson  *              │      remove             │
1342b74b03cSAllison Henderson  *              │                         V
1352b74b03cSAllison Henderson  *              │                  refill the state
1362b74b03cSAllison Henderson  *              n                         │
1372b74b03cSAllison Henderson  *              │                         v
1382b74b03cSAllison Henderson  *              │                   XFS_DAS_RM_NAME
1392b74b03cSAllison Henderson  *              │                         │
1402b74b03cSAllison Henderson  *              ├─────────────────────────┘
1412b74b03cSAllison Henderson  *              │
1422b74b03cSAllison Henderson  *              v
1432b74b03cSAllison Henderson  *       remove leaf and
1442b74b03cSAllison Henderson  *       update hash with
1452b74b03cSAllison Henderson  *   xfs_attr_node_remove_cleanup
1462b74b03cSAllison Henderson  *              │
1472b74b03cSAllison Henderson  *              v
1482b74b03cSAllison Henderson  *           need to
1492b74b03cSAllison Henderson  *        shrink tree? ─n─┐
1502b74b03cSAllison Henderson  *              │         │
1512b74b03cSAllison Henderson  *              y         │
1522b74b03cSAllison Henderson  *              │         │
1532b74b03cSAllison Henderson  *              v         │
1542b74b03cSAllison Henderson  *          join leaf     │
1552b74b03cSAllison Henderson  *              │         │
1562b74b03cSAllison Henderson  *              v         │
1572b74b03cSAllison Henderson  *      XFS_DAS_RM_SHRINK │
1582b74b03cSAllison Henderson  *              │         │
1592b74b03cSAllison Henderson  *              v         │
1602b74b03cSAllison Henderson  *       do the shrink    │
1612b74b03cSAllison Henderson  *              │         │
1622b74b03cSAllison Henderson  *              v         │
1632b74b03cSAllison Henderson  *          free state <──┘
1642b74b03cSAllison Henderson  *              │
1652b74b03cSAllison Henderson  *              v
1662b74b03cSAllison Henderson  *            done
1672b74b03cSAllison Henderson  *
1688f502a40SAllison Henderson  *
1698f502a40SAllison Henderson  * Below is a state machine diagram for attr set operations.
1708f502a40SAllison Henderson  *
1718f502a40SAllison Henderson  * It seems the challenge with understanding this system comes from trying to
1728f502a40SAllison Henderson  * absorb the state machine all at once, when really one should only be looking
1738f502a40SAllison Henderson  * at it with in the context of a single function. Once a state sensitive
1748f502a40SAllison Henderson  * function is called, the idea is that it "takes ownership" of the
1758f502a40SAllison Henderson  * state machine. It isn't concerned with the states that may have belonged to
1768f502a40SAllison Henderson  * it's calling parent. Only the states relevant to itself or any other
1778f502a40SAllison Henderson  * subroutines there in. Once a calling function hands off the state machine to
1788f502a40SAllison Henderson  * a subroutine, it needs to respect the simple rule that it doesn't "own" the
1798f502a40SAllison Henderson  * state machine anymore, and it's the responsibility of that calling function
1808f502a40SAllison Henderson  * to propagate the -EAGAIN back up the call stack. Upon reentry, it is
1818f502a40SAllison Henderson  * committed to re-calling that subroutine until it returns something other than
1828f502a40SAllison Henderson  * -EAGAIN. Once that subroutine signals completion (by returning anything other
1838f502a40SAllison Henderson  * than -EAGAIN), the calling function can resume using the state machine.
1848f502a40SAllison Henderson  *
1858f502a40SAllison Henderson  *  xfs_attr_set_iter()
1868f502a40SAllison Henderson  *              │
1878f502a40SAllison Henderson  *              v
1888f502a40SAllison Henderson  *   ┌─y─ has an attr fork?
1898f502a40SAllison Henderson  *   │          |
1908f502a40SAllison Henderson  *   │          n
1918f502a40SAllison Henderson  *   │          |
1928f502a40SAllison Henderson  *   │          V
1938f502a40SAllison Henderson  *   │       add a fork
1948f502a40SAllison Henderson  *   │          │
1958f502a40SAllison Henderson  *   └──────────┤
1968f502a40SAllison Henderson  *              │
1978f502a40SAllison Henderson  *              V
1988f502a40SAllison Henderson  *   ┌─── is shortform?
1998f502a40SAllison Henderson  *   │          │
2008f502a40SAllison Henderson  *   │          y
2018f502a40SAllison Henderson  *   │          │
2028f502a40SAllison Henderson  *   │          V
2038f502a40SAllison Henderson  *   │   xfs_attr_set_fmt
2048f502a40SAllison Henderson  *   │          |
2058f502a40SAllison Henderson  *   │          V
2068f502a40SAllison Henderson  *   │ xfs_attr_try_sf_addname
2078f502a40SAllison Henderson  *   │          │
2088f502a40SAllison Henderson  *   │          V
2098f502a40SAllison Henderson  *   │      had enough ──y──> done
2108f502a40SAllison Henderson  *   │        space?
2118f502a40SAllison Henderson  *   n          │
2128f502a40SAllison Henderson  *   │          n
2138f502a40SAllison Henderson  *   │          │
2148f502a40SAllison Henderson  *   │          V
2158f502a40SAllison Henderson  *   │   transform to leaf
2168f502a40SAllison Henderson  *   │          │
2178f502a40SAllison Henderson  *   │          V
2188f502a40SAllison Henderson  *   │   hold the leaf buffer
2198f502a40SAllison Henderson  *   │          │
2208f502a40SAllison Henderson  *   │          V
2218f502a40SAllison Henderson  *   │     return -EAGAIN
2228f502a40SAllison Henderson  *   │      Re-enter in
2238f502a40SAllison Henderson  *   │       leaf form
2248f502a40SAllison Henderson  *   │
2258f502a40SAllison Henderson  *   └─> release leaf buffer
2268f502a40SAllison Henderson  *          if needed
2278f502a40SAllison Henderson  *              │
2288f502a40SAllison Henderson  *              V
2298f502a40SAllison Henderson  *   ┌───n── fork has
2308f502a40SAllison Henderson  *   │      only 1 blk?
2318f502a40SAllison Henderson  *   │          │
2328f502a40SAllison Henderson  *   │          y
2338f502a40SAllison Henderson  *   │          │
2348f502a40SAllison Henderson  *   │          v
2358f502a40SAllison Henderson  *   │ xfs_attr_leaf_try_add()
2368f502a40SAllison Henderson  *   │          │
2378f502a40SAllison Henderson  *   │          v
2388f502a40SAllison Henderson  *   │      had enough ──────────────y─────────────┐
2398f502a40SAllison Henderson  *   │        space?                               │
2408f502a40SAllison Henderson  *   │          │                                  │
2418f502a40SAllison Henderson  *   │          n                                  │
2428f502a40SAllison Henderson  *   │          │                                  │
2438f502a40SAllison Henderson  *   │          v                                  │
2448f502a40SAllison Henderson  *   │    return -EAGAIN                           │
2458f502a40SAllison Henderson  *   │      re-enter in                            │
2468f502a40SAllison Henderson  *   │        node form                            │
2478f502a40SAllison Henderson  *   │          │                                  │
2488f502a40SAllison Henderson  *   └──────────┤                                  │
2498f502a40SAllison Henderson  *              │                                  │
2508f502a40SAllison Henderson  *              V                                  │
2518f502a40SAllison Henderson  * xfs_attr_node_addname_find_attr                 │
2528f502a40SAllison Henderson  *        determines if this                       │
2538f502a40SAllison Henderson  *       is create or rename                       │
2548f502a40SAllison Henderson  *     find space to store attr                    │
2558f502a40SAllison Henderson  *              │                                  │
2568f502a40SAllison Henderson  *              v                                  │
2578f502a40SAllison Henderson  *     xfs_attr_node_addname                       │
2588f502a40SAllison Henderson  *              │                                  │
2598f502a40SAllison Henderson  *              v                                  │
2608f502a40SAllison Henderson  *   fits in a node leaf? ────n─────┐              │
2618f502a40SAllison Henderson  *              │     ^             v              │
2628f502a40SAllison Henderson  *              │     │       single leaf node?    │
2638f502a40SAllison Henderson  *              │     │         │            │     │
2648f502a40SAllison Henderson  *              y     │         y            n     │
2658f502a40SAllison Henderson  *              │     │         │            │     │
2668f502a40SAllison Henderson  *              v     │         v            v     │
2678f502a40SAllison Henderson  *            update  │    grow the leaf  split if │
2688f502a40SAllison Henderson  *           hashvals └── return -EAGAIN   needed  │
2698f502a40SAllison Henderson  *              │         retry leaf add     │     │
2708f502a40SAllison Henderson  *              │           on reentry       │     │
2718f502a40SAllison Henderson  *              ├────────────────────────────┘     │
2728f502a40SAllison Henderson  *              │                                  │
2738f502a40SAllison Henderson  *              v                                  │
2748f502a40SAllison Henderson  *         need to alloc                           │
2758f502a40SAllison Henderson  *   ┌─y── or flip flag?                           │
2768f502a40SAllison Henderson  *   │          │                                  │
2778f502a40SAllison Henderson  *   │          n                                  │
2788f502a40SAllison Henderson  *   │          │                                  │
2798f502a40SAllison Henderson  *   │          v                                  │
2808f502a40SAllison Henderson  *   │         done                                │
2818f502a40SAllison Henderson  *   │                                             │
2828f502a40SAllison Henderson  *   │                                             │
2838f502a40SAllison Henderson  *   │         XFS_DAS_FOUND_LBLK <────────────────┘
2848f502a40SAllison Henderson  *   │                  │
2858f502a40SAllison Henderson  *   │                  V
2868f502a40SAllison Henderson  *   │        xfs_attr_leaf_addname()
2878f502a40SAllison Henderson  *   │                  │
2888f502a40SAllison Henderson  *   │                  v
2898f502a40SAllison Henderson  *   │      ┌──first time through?
2908f502a40SAllison Henderson  *   │      │          │
2918f502a40SAllison Henderson  *   │      │          y
2928f502a40SAllison Henderson  *   │      │          │
2938f502a40SAllison Henderson  *   │      n          v
2948f502a40SAllison Henderson  *   │      │    if we have rmt blks
2958f502a40SAllison Henderson  *   │      │    find space for them
2968f502a40SAllison Henderson  *   │      │          │
2978f502a40SAllison Henderson  *   │      └──────────┤
2988f502a40SAllison Henderson  *   │                 │
2998f502a40SAllison Henderson  *   │                 v
3008f502a40SAllison Henderson  *   │            still have
3018f502a40SAllison Henderson  *   │      ┌─n─ blks to alloc? <──┐
3028f502a40SAllison Henderson  *   │      │          │           │
3038f502a40SAllison Henderson  *   │      │          y           │
3048f502a40SAllison Henderson  *   │      │          │           │
3058f502a40SAllison Henderson  *   │      │          v           │
3068f502a40SAllison Henderson  *   │      │     alloc one blk    │
3078f502a40SAllison Henderson  *   │      │     return -EAGAIN ──┘
3088f502a40SAllison Henderson  *   │      │    re-enter with one
3098f502a40SAllison Henderson  *   │      │    less blk to alloc
3108f502a40SAllison Henderson  *   │      │
3118f502a40SAllison Henderson  *   │      │
3128f502a40SAllison Henderson  *   │      └───> set the rmt
3138f502a40SAllison Henderson  *   │               value
3148f502a40SAllison Henderson  *   │                 │
3158f502a40SAllison Henderson  *   │                 v
3168f502a40SAllison Henderson  *   │               was this
3178f502a40SAllison Henderson  *   │              a rename? ──n─┐
3188f502a40SAllison Henderson  *   │                 │          │
3198f502a40SAllison Henderson  *   │                 y          │
3208f502a40SAllison Henderson  *   │                 │          │
3218f502a40SAllison Henderson  *   │                 v          │
3228f502a40SAllison Henderson  *   │           flip incomplete  │
3238f502a40SAllison Henderson  *   │               flag         │
3248f502a40SAllison Henderson  *   │                 │          │
3258f502a40SAllison Henderson  *   │                 v          │
3268f502a40SAllison Henderson  *   │         XFS_DAS_FLIP_LFLAG │
3278f502a40SAllison Henderson  *   │                 │          │
3288f502a40SAllison Henderson  *   │                 v          │
3298f502a40SAllison Henderson  *   │          need to remove    │
3308f502a40SAllison Henderson  *   │              old bks? ──n──┤
3318f502a40SAllison Henderson  *   │                 │          │
3328f502a40SAllison Henderson  *   │                 y          │
3338f502a40SAllison Henderson  *   │                 │          │
3348f502a40SAllison Henderson  *   │                 V          │
3358f502a40SAllison Henderson  *   │               remove       │
3368f502a40SAllison Henderson  *   │        ┌───> old blks      │
3378f502a40SAllison Henderson  *   │        │        │          │
3388f502a40SAllison Henderson  *   │ XFS_DAS_RM_LBLK │          │
3398f502a40SAllison Henderson  *   │        ^        │          │
3408f502a40SAllison Henderson  *   │        │        v          │
3418f502a40SAllison Henderson  *   │        └──y── more to      │
3428f502a40SAllison Henderson  *   │              remove?       │
3438f502a40SAllison Henderson  *   │                 │          │
3448f502a40SAllison Henderson  *   │                 n          │
3458f502a40SAllison Henderson  *   │                 │          │
3468f502a40SAllison Henderson  *   │                 v          │
3478f502a40SAllison Henderson  *   │          XFS_DAS_RD_LEAF   │
3488f502a40SAllison Henderson  *   │                 │          │
3498f502a40SAllison Henderson  *   │                 v          │
3508f502a40SAllison Henderson  *   │            remove leaf     │
3518f502a40SAllison Henderson  *   │                 │          │
3528f502a40SAllison Henderson  *   │                 v          │
3538f502a40SAllison Henderson  *   │            shrink to sf    │
3548f502a40SAllison Henderson  *   │             if needed      │
3558f502a40SAllison Henderson  *   │                 │          │
3568f502a40SAllison Henderson  *   │                 v          │
3578f502a40SAllison Henderson  *   │                done <──────┘
3588f502a40SAllison Henderson  *   │
3598f502a40SAllison Henderson  *   └──────> XFS_DAS_FOUND_NBLK
3608f502a40SAllison Henderson  *                     │
3618f502a40SAllison Henderson  *                     v
3628f502a40SAllison Henderson  *       ┌─────n──  need to
3638f502a40SAllison Henderson  *       │        alloc blks?
3648f502a40SAllison Henderson  *       │             │
3658f502a40SAllison Henderson  *       │             y
3668f502a40SAllison Henderson  *       │             │
3678f502a40SAllison Henderson  *       │             v
3688f502a40SAllison Henderson  *       │        find space
3698f502a40SAllison Henderson  *       │             │
3708f502a40SAllison Henderson  *       │             v
3718f502a40SAllison Henderson  *       │  ┌─>XFS_DAS_ALLOC_NODE
3728f502a40SAllison Henderson  *       │  │          │
3738f502a40SAllison Henderson  *       │  │          v
3748f502a40SAllison Henderson  *       │  │      alloc blk
3758f502a40SAllison Henderson  *       │  │          │
3768f502a40SAllison Henderson  *       │  │          v
3778f502a40SAllison Henderson  *       │  └──y── need to alloc
3788f502a40SAllison Henderson  *       │         more blocks?
3798f502a40SAllison Henderson  *       │             │
3808f502a40SAllison Henderson  *       │             n
3818f502a40SAllison Henderson  *       │             │
3828f502a40SAllison Henderson  *       │             v
3838f502a40SAllison Henderson  *       │      set the rmt value
3848f502a40SAllison Henderson  *       │             │
3858f502a40SAllison Henderson  *       │             v
3868f502a40SAllison Henderson  *       │          was this
3878f502a40SAllison Henderson  *       └────────> a rename? ──n─┐
3888f502a40SAllison Henderson  *                     │          │
3898f502a40SAllison Henderson  *                     y          │
3908f502a40SAllison Henderson  *                     │          │
3918f502a40SAllison Henderson  *                     v          │
3928f502a40SAllison Henderson  *               flip incomplete  │
3938f502a40SAllison Henderson  *                   flag         │
3948f502a40SAllison Henderson  *                     │          │
3958f502a40SAllison Henderson  *                     v          │
3968f502a40SAllison Henderson  *             XFS_DAS_FLIP_NFLAG │
3978f502a40SAllison Henderson  *                     │          │
3988f502a40SAllison Henderson  *                     v          │
3998f502a40SAllison Henderson  *                 need to        │
4008f502a40SAllison Henderson  *               remove blks? ─n──┤
4018f502a40SAllison Henderson  *                     │          │
4028f502a40SAllison Henderson  *                     y          │
4038f502a40SAllison Henderson  *                     │          │
4048f502a40SAllison Henderson  *                     v          │
4058f502a40SAllison Henderson  *                   remove       │
4068f502a40SAllison Henderson  *        ┌────────> old blks     │
4078f502a40SAllison Henderson  *        │            │          │
4088f502a40SAllison Henderson  *  XFS_DAS_RM_NBLK    │          │
4098f502a40SAllison Henderson  *        ^            │          │
4108f502a40SAllison Henderson  *        │            v          │
4118f502a40SAllison Henderson  *        └──────y── more to      │
4128f502a40SAllison Henderson  *                   remove       │
4138f502a40SAllison Henderson  *                     │          │
4148f502a40SAllison Henderson  *                     n          │
4158f502a40SAllison Henderson  *                     │          │
4168f502a40SAllison Henderson  *                     v          │
4178f502a40SAllison Henderson  *              XFS_DAS_CLR_FLAG  │
4188f502a40SAllison Henderson  *                     │          │
4198f502a40SAllison Henderson  *                     v          │
4208f502a40SAllison Henderson  *                clear flags     │
4218f502a40SAllison Henderson  *                     │          │
4228f502a40SAllison Henderson  *                     ├──────────┘
4238f502a40SAllison Henderson  *                     │
4248f502a40SAllison Henderson  *                     v
4258f502a40SAllison Henderson  *                   done
4262b74b03cSAllison Henderson  */
4272b74b03cSAllison Henderson 
4282b74b03cSAllison Henderson /*
429e3c5de22SDarrick J. Wong  * Enum values for xfs_attr_intent.xattri_da_state
4302b74b03cSAllison Henderson  *
4312b74b03cSAllison Henderson  * These values are used by delayed attribute operations to keep track  of where
4322b74b03cSAllison Henderson  * they were before they returned -EAGAIN.  A return code of -EAGAIN signals the
4332b74b03cSAllison Henderson  * calling function to roll the transaction, and then call the subroutine to
4342b74b03cSAllison Henderson  * finish the operation.  The enum is then used by the subroutine to jump back
4352b74b03cSAllison Henderson  * to where it was and resume executing where it left off.
4362b74b03cSAllison Henderson  */
4372b74b03cSAllison Henderson enum xfs_delattr_state {
4382b74b03cSAllison Henderson 	XFS_DAS_UNINIT		= 0,	/* No state has been set yet */
439251b29c8SDave Chinner 
440fdaf1bb3SDave Chinner 	/*
441fdaf1bb3SDave Chinner 	 * Initial sequence states. The replace setup code relies on the
442fdaf1bb3SDave Chinner 	 * ADD and REMOVE states for a specific format to be sequential so
443fdaf1bb3SDave Chinner 	 * that we can transform the initial operation to be performed
444fdaf1bb3SDave Chinner 	 * according to the xfs_has_larp() state easily.
445fdaf1bb3SDave Chinner 	 */
446fdaf1bb3SDave Chinner 	XFS_DAS_SF_ADD,			/* Initial sf add state */
447fdaf1bb3SDave Chinner 	XFS_DAS_SF_REMOVE,		/* Initial sf replace/remove state */
448e5d5596aSDave Chinner 
449fdaf1bb3SDave Chinner 	XFS_DAS_LEAF_ADD,		/* Initial leaf add state */
450fdaf1bb3SDave Chinner 	XFS_DAS_LEAF_REMOVE,		/* Initial leaf replace/remove state */
451fdaf1bb3SDave Chinner 
452fdaf1bb3SDave Chinner 	XFS_DAS_NODE_ADD,		/* Initial node add state */
453fdaf1bb3SDave Chinner 	XFS_DAS_NODE_REMOVE,		/* Initial node replace/remove state */
454fdaf1bb3SDave Chinner 
455fdaf1bb3SDave Chinner 	/* Leaf state set/replace/remove sequence */
4567d035336SDave Chinner 	XFS_DAS_LEAF_SET_RMT,		/* set a remote xattr from a leaf */
4572157d169SDave Chinner 	XFS_DAS_LEAF_ALLOC_RMT,		/* We are allocating remote blocks */
4587d035336SDave Chinner 	XFS_DAS_LEAF_REPLACE,		/* Perform replace ops on a leaf */
459411b434aSDave Chinner 	XFS_DAS_LEAF_REMOVE_OLD,	/* Start removing old attr from leaf */
4602e7ef218SDave Chinner 	XFS_DAS_LEAF_REMOVE_RMT,	/* A rename is removing remote blocks */
461b11fa61bSDave Chinner 	XFS_DAS_LEAF_REMOVE_ATTR,	/* Remove the old attr from a leaf */
462251b29c8SDave Chinner 
463fdaf1bb3SDave Chinner 	/* Node state sequence, must match leaf state above */
4647d035336SDave Chinner 	XFS_DAS_NODE_SET_RMT,		/* set a remote xattr from a node */
465251b29c8SDave Chinner 	XFS_DAS_NODE_ALLOC_RMT,		/* We are allocating remote blocks */
4667d035336SDave Chinner 	XFS_DAS_NODE_REPLACE,		/* Perform replace ops on a node */
467411b434aSDave Chinner 	XFS_DAS_NODE_REMOVE_OLD,	/* Start removing old attr from node */
4682e7ef218SDave Chinner 	XFS_DAS_NODE_REMOVE_RMT,	/* A rename is removing remote blocks */
469b11fa61bSDave Chinner 	XFS_DAS_NODE_REMOVE_ATTR,	/* Remove the old attr from a node */
470251b29c8SDave Chinner 
471e0c41089SDave Chinner 	XFS_DAS_DONE,			/* finished operation */
4722b74b03cSAllison Henderson };
4732b74b03cSAllison Henderson 
474e0c41089SDave Chinner #define XFS_DAS_STRINGS	\
475e0c41089SDave Chinner 	{ XFS_DAS_UNINIT,		"XFS_DAS_UNINIT" }, \
476e0c41089SDave Chinner 	{ XFS_DAS_SF_ADD,		"XFS_DAS_SF_ADD" }, \
477fdaf1bb3SDave Chinner 	{ XFS_DAS_SF_REMOVE,		"XFS_DAS_SF_REMOVE" }, \
478e0c41089SDave Chinner 	{ XFS_DAS_LEAF_ADD,		"XFS_DAS_LEAF_ADD" }, \
479fdaf1bb3SDave Chinner 	{ XFS_DAS_LEAF_REMOVE,		"XFS_DAS_LEAF_REMOVE" }, \
480e0c41089SDave Chinner 	{ XFS_DAS_NODE_ADD,		"XFS_DAS_NODE_ADD" }, \
481fdaf1bb3SDave Chinner 	{ XFS_DAS_NODE_REMOVE,		"XFS_DAS_NODE_REMOVE" }, \
4827d035336SDave Chinner 	{ XFS_DAS_LEAF_SET_RMT,		"XFS_DAS_LEAF_SET_RMT" }, \
4832157d169SDave Chinner 	{ XFS_DAS_LEAF_ALLOC_RMT,	"XFS_DAS_LEAF_ALLOC_RMT" }, \
4847d035336SDave Chinner 	{ XFS_DAS_LEAF_REPLACE,		"XFS_DAS_LEAF_REPLACE" }, \
485411b434aSDave Chinner 	{ XFS_DAS_LEAF_REMOVE_OLD,	"XFS_DAS_LEAF_REMOVE_OLD" }, \
4862e7ef218SDave Chinner 	{ XFS_DAS_LEAF_REMOVE_RMT,	"XFS_DAS_LEAF_REMOVE_RMT" }, \
487b11fa61bSDave Chinner 	{ XFS_DAS_LEAF_REMOVE_ATTR,	"XFS_DAS_LEAF_REMOVE_ATTR" }, \
4887d035336SDave Chinner 	{ XFS_DAS_NODE_SET_RMT,		"XFS_DAS_NODE_SET_RMT" }, \
4897d035336SDave Chinner 	{ XFS_DAS_NODE_ALLOC_RMT,	"XFS_DAS_NODE_ALLOC_RMT" },  \
4907d035336SDave Chinner 	{ XFS_DAS_NODE_REPLACE,		"XFS_DAS_NODE_REPLACE" },  \
491411b434aSDave Chinner 	{ XFS_DAS_NODE_REMOVE_OLD,	"XFS_DAS_NODE_REMOVE_OLD" }, \
4922e7ef218SDave Chinner 	{ XFS_DAS_NODE_REMOVE_RMT,	"XFS_DAS_NODE_REMOVE_RMT" }, \
493b11fa61bSDave Chinner 	{ XFS_DAS_NODE_REMOVE_ATTR,	"XFS_DAS_NODE_REMOVE_ATTR" }, \
494e0c41089SDave Chinner 	{ XFS_DAS_DONE,			"XFS_DAS_DONE" }
495e0c41089SDave Chinner 
4964183e4f2SDarrick J. Wong struct xfs_attri_log_nameval;
4974183e4f2SDarrick J. Wong 
4982b74b03cSAllison Henderson /*
4992b74b03cSAllison Henderson  * Context used for keeping track of delayed attribute operations
5002b74b03cSAllison Henderson  */
501e3c5de22SDarrick J. Wong struct xfs_attr_intent {
502500a512cSDarrick J. Wong 	/*
503500a512cSDarrick J. Wong 	 * used to log this item to an intent containing a list of attrs to
504500a512cSDarrick J. Wong 	 * commit later
505500a512cSDarrick J. Wong 	 */
506500a512cSDarrick J. Wong 	struct list_head		xattri_list;
507500a512cSDarrick J. Wong 
508500a512cSDarrick J. Wong 	/* Used in xfs_attr_node_removename to roll through removing blocks */
509500a512cSDarrick J. Wong 	struct xfs_da_state		*xattri_da_state;
510500a512cSDarrick J. Wong 
511d68c51e9SAllison Henderson 	struct xfs_da_args		*xattri_da_args;
5122b74b03cSAllison Henderson 
513fd920008SAllison Henderson 	/*
5145773f7f8SDarrick J. Wong 	 * Shared buffer containing the attr name, new name, and value so that
5155773f7f8SDarrick J. Wong 	 * the logging code can share large memory buffers between log items.
5164183e4f2SDarrick J. Wong 	 */
5174183e4f2SDarrick J. Wong 	struct xfs_attri_log_nameval	*xattri_nameval;
5184183e4f2SDarrick J. Wong 
5192b74b03cSAllison Henderson 	/* Used to keep track of current state of delayed operation */
520d68c51e9SAllison Henderson 	enum xfs_delattr_state		xattri_dela_state;
521fd920008SAllison Henderson 
522fd920008SAllison Henderson 	/*
523b53d212bSDarrick J. Wong 	 * Attr operation being performed - XFS_ATTRI_OP_FLAGS_*
524fd920008SAllison Henderson 	 */
525fd920008SAllison Henderson 	unsigned int			xattri_op_flags;
526fd920008SAllison Henderson 
527500a512cSDarrick J. Wong 	/* Used in xfs_attr_rmtval_set_blk to roll through allocating blocks */
528500a512cSDarrick J. Wong 	xfs_dablk_t			xattri_lblkno;
529500a512cSDarrick J. Wong 	int				xattri_blkcnt;
530500a512cSDarrick J. Wong 	struct xfs_bmbt_irec		xattri_map;
531fd920008SAllison Henderson };
532fd920008SAllison Henderson 
5332a2c05d0SDarrick J. Wong static inline unsigned int
xfs_attr_intent_op(const struct xfs_attr_intent * attr)5342a2c05d0SDarrick J. Wong xfs_attr_intent_op(const struct xfs_attr_intent *attr)
5352a2c05d0SDarrick J. Wong {
5362a2c05d0SDarrick J. Wong 	return attr->xattri_op_flags & XFS_ATTRI_OP_FLAGS_TYPE_MASK;
5372a2c05d0SDarrick J. Wong }
538fd920008SAllison Henderson 
539e2421f0bSAllison Henderson /*========================================================================
540e2421f0bSAllison Henderson  * Function prototypes for the kernel.
541e2421f0bSAllison Henderson  *========================================================================*/
542e2421f0bSAllison Henderson 
543e2421f0bSAllison Henderson /*
544e2421f0bSAllison Henderson  * Overall external interface routines.
545e2421f0bSAllison Henderson  */
546e2421f0bSAllison Henderson int xfs_attr_inactive(struct xfs_inode *dp);
54717e1dd83SChristoph Hellwig int xfs_attr_list_ilocked(struct xfs_attr_list_context *);
54817e1dd83SChristoph Hellwig int xfs_attr_list(struct xfs_attr_list_context *);
549e2421f0bSAllison Henderson int xfs_inode_hasattr(struct xfs_inode *ip);
5502ac131dfSChristoph Hellwig bool xfs_attr_is_leaf(struct xfs_inode *ip);
551c36f533fSChristoph Hellwig int xfs_attr_get_ilocked(struct xfs_da_args *args);
552e5171d7eSChristoph Hellwig int xfs_attr_get(struct xfs_da_args *args);
55354275d84SDarrick J. Wong 
55454275d84SDarrick J. Wong enum xfs_attr_update {
555c27411d4SDarrick J. Wong 	XFS_ATTRUPDATE_REMOVE,	/* remove attr */
556c27411d4SDarrick J. Wong 	XFS_ATTRUPDATE_UPSERT,	/* set value, replace any existing attr */
55754275d84SDarrick J. Wong 	XFS_ATTRUPDATE_CREATE,	/* set value, fail if attr already exists */
55854275d84SDarrick J. Wong 	XFS_ATTRUPDATE_REPLACE,	/* set value, fail if attr does not exist */
55954275d84SDarrick J. Wong };
56054275d84SDarrick J. Wong 
561bf61c36aSDarrick J. Wong int xfs_attr_set(struct xfs_da_args *args, enum xfs_attr_update op, bool rsvd);
562e3c5de22SDarrick J. Wong int xfs_attr_set_iter(struct xfs_attr_intent *attr);
563e3c5de22SDarrick J. Wong int xfs_attr_remove_iter(struct xfs_attr_intent *attr);
564ea0b3e81SDarrick J. Wong bool xfs_attr_check_namespace(unsigned int attr_flags);
565ea0b3e81SDarrick J. Wong bool xfs_attr_namecheck(unsigned int attr_flags, const void *name,
566ea0b3e81SDarrick J. Wong 		size_t length);
567fd920008SAllison Henderson int xfs_attr_calc_size(struct xfs_da_args *args, int *local);
568*97835e68SDarrick J. Wong struct xfs_trans_res xfs_attr_set_resv(const struct xfs_da_args *args);
569fd920008SAllison Henderson 
570e0c41089SDave Chinner /*
571e0c41089SDave Chinner  * Check to see if the attr should be upgraded from non-existent or shortform to
572e0c41089SDave Chinner  * single-leaf-block attribute list.
573e0c41089SDave Chinner  */
574e0c41089SDave Chinner static inline bool
xfs_attr_is_shortform(struct xfs_inode * ip)575e0c41089SDave Chinner xfs_attr_is_shortform(
576e0c41089SDave Chinner 	struct xfs_inode    *ip)
577e0c41089SDave Chinner {
5782ed5b09bSDarrick J. Wong 	return ip->i_af.if_format == XFS_DINODE_FMT_LOCAL ||
5792ed5b09bSDarrick J. Wong 	       (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
5802ed5b09bSDarrick J. Wong 		ip->i_af.if_nextents == 0);
581e0c41089SDave Chinner }
582e0c41089SDave Chinner 
583e0c41089SDave Chinner static inline enum xfs_delattr_state
xfs_attr_init_add_state(struct xfs_da_args * args)584e0c41089SDave Chinner xfs_attr_init_add_state(struct xfs_da_args *args)
585e0c41089SDave Chinner {
586e0c41089SDave Chinner 	/*
587e0c41089SDave Chinner 	 * When called from the completion of a attr remove to determine the
588e0c41089SDave Chinner 	 * next state, the attribute fork may be null. This can occur only occur
589e0c41089SDave Chinner 	 * on a pure remove, but we grab the next state before we check if a
590e0c41089SDave Chinner 	 * replace operation is being performed. If we are called from any other
5912ed5b09bSDarrick J. Wong 	 * context, i_af is guaranteed to exist. Hence if the attr fork is
592e0c41089SDave Chinner 	 * null, we were called from a pure remove operation and so we are done.
593e0c41089SDave Chinner 	 */
594932b42c6SDarrick J. Wong 	if (!xfs_inode_has_attr_fork(args->dp))
595e0c41089SDave Chinner 		return XFS_DAS_DONE;
596e7f358deSDave Chinner 
597e7f358deSDave Chinner 	args->op_flags |= XFS_DA_OP_ADDNAME;
598e0c41089SDave Chinner 	if (xfs_attr_is_shortform(args->dp))
599e0c41089SDave Chinner 		return XFS_DAS_SF_ADD;
600e0c41089SDave Chinner 	if (xfs_attr_is_leaf(args->dp))
601e0c41089SDave Chinner 		return XFS_DAS_LEAF_ADD;
602e0c41089SDave Chinner 	return XFS_DAS_NODE_ADD;
603e0c41089SDave Chinner }
604e0c41089SDave Chinner 
605e0c41089SDave Chinner static inline enum xfs_delattr_state
xfs_attr_init_remove_state(struct xfs_da_args * args)6064b9879b1SDave Chinner xfs_attr_init_remove_state(struct xfs_da_args *args)
6074b9879b1SDave Chinner {
6084b9879b1SDave Chinner 	if (xfs_attr_is_shortform(args->dp))
6094b9879b1SDave Chinner 		return XFS_DAS_SF_REMOVE;
6104b9879b1SDave Chinner 	if (xfs_attr_is_leaf(args->dp))
6114b9879b1SDave Chinner 		return XFS_DAS_LEAF_REMOVE;
6124b9879b1SDave Chinner 	return XFS_DAS_NODE_REMOVE;
6134b9879b1SDave Chinner }
6144b9879b1SDave Chinner 
615fdaf1bb3SDave Chinner /*
616fdaf1bb3SDave Chinner  * If we are logging the attributes, then we have to start with removal of the
617fdaf1bb3SDave Chinner  * old attribute so that there is always consistent state that we can recover
618fdaf1bb3SDave Chinner  * from if the system goes down part way through. We always log the new attr
619fdaf1bb3SDave Chinner  * value, so even when we remove the attr first we still have the information in
620fdaf1bb3SDave Chinner  * the log to finish the replace operation atomically.
621fdaf1bb3SDave Chinner  */
6224b9879b1SDave Chinner static inline enum xfs_delattr_state
xfs_attr_init_replace_state(struct xfs_da_args * args)623e0c41089SDave Chinner xfs_attr_init_replace_state(struct xfs_da_args *args)
624e0c41089SDave Chinner {
625e7f358deSDave Chinner 	args->op_flags |= XFS_DA_OP_ADDNAME | XFS_DA_OP_REPLACE;
626f4288f01SDarrick J. Wong 	if (args->op_flags & XFS_DA_OP_LOGGED)
627fdaf1bb3SDave Chinner 		return xfs_attr_init_remove_state(args);
628e0c41089SDave Chinner 	return xfs_attr_init_add_state(args);
629e0c41089SDave Chinner }
630e0c41089SDave Chinner 
631a64e0134SDarrick J. Wong xfs_dahash_t xfs_attr_hashname(const uint8_t *name, int namelen);
632a64e0134SDarrick J. Wong 
633a64e0134SDarrick J. Wong xfs_dahash_t xfs_attr_hashval(struct xfs_mount *mp, unsigned int attr_flags,
634a64e0134SDarrick J. Wong 		const uint8_t *name, int namelen, const void *value,
635a64e0134SDarrick J. Wong 		int valuelen);
636a64e0134SDarrick J. Wong 
637a64e0134SDarrick J. Wong /* Set the hash value for any extended attribute from any namespace. */
xfs_attr_sethash(struct xfs_da_args * args)638a64e0134SDarrick J. Wong static inline void xfs_attr_sethash(struct xfs_da_args *args)
639a64e0134SDarrick J. Wong {
640a64e0134SDarrick J. Wong 	args->hashval = xfs_attr_hashval(args->dp->i_mount, args->attr_filter,
641a64e0134SDarrick J. Wong 					 args->name, args->namelen,
642a64e0134SDarrick J. Wong 					 args->value, args->valuelen);
643a64e0134SDarrick J. Wong }
644a64e0134SDarrick J. Wong 
645e2c78949SDarrick J. Wong extern struct kmem_cache *xfs_attr_intent_cache;
646e2c78949SDarrick J. Wong int __init xfs_attr_intent_init_cache(void);
647e2c78949SDarrick J. Wong void xfs_attr_intent_destroy_cache(void);
648e2c78949SDarrick J. Wong 
649e47dcf11SDarrick J. Wong int xfs_attr_sf_totsize(struct xfs_inode *dp);
650a26dc213SDarrick J. Wong int xfs_attr_add_fork(struct xfs_inode *ip, int size, int rsvd);
651e47dcf11SDarrick J. Wong 
652e2421f0bSAllison Henderson #endif	/* __XFS_ATTR_H__ */
653