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 31fd920008SAllison Henderson static inline bool xfs_has_larp(struct xfs_mount *mp) 32fd920008SAllison Henderson { 33535e2f75SAllison Henderson #ifdef DEBUG 34535e2f75SAllison Henderson return xfs_globals.larp; 35535e2f75SAllison Henderson #else 36fd920008SAllison Henderson return false; 37535e2f75SAllison Henderson #endif 38fd920008SAllison Henderson } 39fd920008SAllison Henderson 40e2421f0bSAllison Henderson /* 41e2421f0bSAllison Henderson * Kernel-internal version of the attrlist cursor. 42e2421f0bSAllison Henderson */ 43e3a19cdeSChristoph Hellwig struct xfs_attrlist_cursor_kern { 44e2421f0bSAllison Henderson __u32 hashval; /* hash value of next entry to add */ 45e2421f0bSAllison Henderson __u32 blkno; /* block containing entry (suggestion) */ 46e2421f0bSAllison Henderson __u32 offset; /* offset in list of equal-hashvals */ 47e2421f0bSAllison Henderson __u16 pad1; /* padding to match user-level */ 48e2421f0bSAllison Henderson __u8 pad2; /* padding to match user-level */ 49e2421f0bSAllison Henderson __u8 initted; /* T/F: cursor has been initialized */ 50e3a19cdeSChristoph Hellwig }; 51e2421f0bSAllison Henderson 52e2421f0bSAllison Henderson 53e2421f0bSAllison Henderson /*======================================================================== 54e2421f0bSAllison Henderson * Structure used to pass context around among the routines. 55e2421f0bSAllison Henderson *========================================================================*/ 56e2421f0bSAllison Henderson 57e2421f0bSAllison Henderson 58e2421f0bSAllison Henderson /* void; state communicated via *context */ 59e2421f0bSAllison Henderson typedef void (*put_listent_func_t)(struct xfs_attr_list_context *, int, 60e2421f0bSAllison Henderson unsigned char *, int, int); 61e2421f0bSAllison Henderson 62a9c8c69bSChristoph Hellwig struct xfs_attr_list_context { 63e2421f0bSAllison Henderson struct xfs_trans *tp; 64e2421f0bSAllison Henderson struct xfs_inode *dp; /* inode */ 65e3a19cdeSChristoph Hellwig struct xfs_attrlist_cursor_kern cursor; /* position in list */ 66a9c8c69bSChristoph Hellwig void *buffer; /* output buffer */ 672c3b83d7SDarrick J. Wong 682c3b83d7SDarrick J. Wong /* 692c3b83d7SDarrick J. Wong * Abort attribute list iteration if non-zero. Can be used to pass 702c3b83d7SDarrick J. Wong * error values to the xfs_attr_list caller. 712c3b83d7SDarrick J. Wong */ 722c3b83d7SDarrick J. Wong int seen_enough; 735e813574SChristoph Hellwig bool allow_incomplete; 742c3b83d7SDarrick J. Wong 75e2421f0bSAllison Henderson ssize_t count; /* num used entries */ 76e2421f0bSAllison Henderson int dupcnt; /* count dup hashvals seen */ 77e2421f0bSAllison Henderson int bufsize; /* total buffer size */ 78e2421f0bSAllison Henderson int firstu; /* first used byte in buffer */ 79d5f0f49aSChristoph Hellwig unsigned int attr_filter; /* XFS_ATTR_{ROOT,SECURE} */ 80e2421f0bSAllison Henderson int resynch; /* T/F: resynch with cursor */ 81e2421f0bSAllison Henderson put_listent_func_t put_listent; /* list output fmt function */ 82e2421f0bSAllison Henderson int index; /* index into output buffer */ 83a9c8c69bSChristoph Hellwig }; 84e2421f0bSAllison Henderson 85e2421f0bSAllison Henderson 862b74b03cSAllison Henderson /* 872b74b03cSAllison Henderson * ======================================================================== 882b74b03cSAllison Henderson * Structure used to pass context around among the delayed routines. 892b74b03cSAllison Henderson * ======================================================================== 902b74b03cSAllison Henderson */ 912b74b03cSAllison Henderson 922b74b03cSAllison Henderson /* 932b74b03cSAllison Henderson * Below is a state machine diagram for attr remove operations. The XFS_DAS_* 942b74b03cSAllison Henderson * states indicate places where the function would return -EAGAIN, and then 952b74b03cSAllison Henderson * immediately resume from after being called by the calling function. States 962b74b03cSAllison Henderson * marked as a "subroutine state" indicate that they belong to a subroutine, and 972b74b03cSAllison Henderson * so the calling function needs to pass them back to that subroutine to allow 982b74b03cSAllison Henderson * it to finish where it left off. But they otherwise do not have a role in the 992b74b03cSAllison Henderson * calling function other than just passing through. 1002b74b03cSAllison Henderson * 1012b74b03cSAllison Henderson * xfs_attr_remove_iter() 1022b74b03cSAllison Henderson * │ 1032b74b03cSAllison Henderson * v 1042b74b03cSAllison Henderson * have attr to remove? ──n──> done 1052b74b03cSAllison Henderson * │ 1062b74b03cSAllison Henderson * y 1072b74b03cSAllison Henderson * │ 1082b74b03cSAllison Henderson * v 1092b74b03cSAllison Henderson * are we short form? ──y──> xfs_attr_shortform_remove ──> done 1102b74b03cSAllison Henderson * │ 1112b74b03cSAllison Henderson * n 1122b74b03cSAllison Henderson * │ 1132b74b03cSAllison Henderson * V 1142b74b03cSAllison Henderson * are we leaf form? ──y──> xfs_attr_leaf_removename ──> done 1152b74b03cSAllison Henderson * │ 1162b74b03cSAllison Henderson * n 1172b74b03cSAllison Henderson * │ 1182b74b03cSAllison Henderson * V 1192b74b03cSAllison Henderson * ┌── need to setup state? 1202b74b03cSAllison Henderson * │ │ 1212b74b03cSAllison Henderson * n y 1222b74b03cSAllison Henderson * │ │ 1232b74b03cSAllison Henderson * │ v 1242b74b03cSAllison Henderson * │ find attr and get state 1252b74b03cSAllison Henderson * │ attr has remote blks? ──n─┐ 1262b74b03cSAllison Henderson * │ │ v 1272b74b03cSAllison Henderson * │ │ find and invalidate 1282b74b03cSAllison Henderson * │ y the remote blocks. 1292b74b03cSAllison Henderson * │ │ mark attr incomplete 1302b74b03cSAllison Henderson * │ ├────────────────┘ 1312b74b03cSAllison Henderson * └──────────┤ 1322b74b03cSAllison Henderson * │ 1332b74b03cSAllison Henderson * v 1342b74b03cSAllison Henderson * Have remote blks to remove? ───y─────┐ 1352b74b03cSAllison Henderson * │ ^ remove the blks 1362b74b03cSAllison Henderson * │ │ │ 1372b74b03cSAllison Henderson * │ │ v 1382b74b03cSAllison Henderson * │ XFS_DAS_RMTBLK <─n── done? 1392b74b03cSAllison Henderson * │ re-enter with │ 1402b74b03cSAllison Henderson * │ one less blk to y 1412b74b03cSAllison Henderson * │ remove │ 1422b74b03cSAllison Henderson * │ V 1432b74b03cSAllison Henderson * │ refill the state 1442b74b03cSAllison Henderson * n │ 1452b74b03cSAllison Henderson * │ v 1462b74b03cSAllison Henderson * │ XFS_DAS_RM_NAME 1472b74b03cSAllison Henderson * │ │ 1482b74b03cSAllison Henderson * ├─────────────────────────┘ 1492b74b03cSAllison Henderson * │ 1502b74b03cSAllison Henderson * v 1512b74b03cSAllison Henderson * remove leaf and 1522b74b03cSAllison Henderson * update hash with 1532b74b03cSAllison Henderson * xfs_attr_node_remove_cleanup 1542b74b03cSAllison Henderson * │ 1552b74b03cSAllison Henderson * v 1562b74b03cSAllison Henderson * need to 1572b74b03cSAllison Henderson * shrink tree? ─n─┐ 1582b74b03cSAllison Henderson * │ │ 1592b74b03cSAllison Henderson * y │ 1602b74b03cSAllison Henderson * │ │ 1612b74b03cSAllison Henderson * v │ 1622b74b03cSAllison Henderson * join leaf │ 1632b74b03cSAllison Henderson * │ │ 1642b74b03cSAllison Henderson * v │ 1652b74b03cSAllison Henderson * XFS_DAS_RM_SHRINK │ 1662b74b03cSAllison Henderson * │ │ 1672b74b03cSAllison Henderson * v │ 1682b74b03cSAllison Henderson * do the shrink │ 1692b74b03cSAllison Henderson * │ │ 1702b74b03cSAllison Henderson * v │ 1712b74b03cSAllison Henderson * free state <──┘ 1722b74b03cSAllison Henderson * │ 1732b74b03cSAllison Henderson * v 1742b74b03cSAllison Henderson * done 1752b74b03cSAllison Henderson * 1768f502a40SAllison Henderson * 1778f502a40SAllison Henderson * Below is a state machine diagram for attr set operations. 1788f502a40SAllison Henderson * 1798f502a40SAllison Henderson * It seems the challenge with understanding this system comes from trying to 1808f502a40SAllison Henderson * absorb the state machine all at once, when really one should only be looking 1818f502a40SAllison Henderson * at it with in the context of a single function. Once a state sensitive 1828f502a40SAllison Henderson * function is called, the idea is that it "takes ownership" of the 1838f502a40SAllison Henderson * state machine. It isn't concerned with the states that may have belonged to 1848f502a40SAllison Henderson * it's calling parent. Only the states relevant to itself or any other 1858f502a40SAllison Henderson * subroutines there in. Once a calling function hands off the state machine to 1868f502a40SAllison Henderson * a subroutine, it needs to respect the simple rule that it doesn't "own" the 1878f502a40SAllison Henderson * state machine anymore, and it's the responsibility of that calling function 1888f502a40SAllison Henderson * to propagate the -EAGAIN back up the call stack. Upon reentry, it is 1898f502a40SAllison Henderson * committed to re-calling that subroutine until it returns something other than 1908f502a40SAllison Henderson * -EAGAIN. Once that subroutine signals completion (by returning anything other 1918f502a40SAllison Henderson * than -EAGAIN), the calling function can resume using the state machine. 1928f502a40SAllison Henderson * 1938f502a40SAllison Henderson * xfs_attr_set_iter() 1948f502a40SAllison Henderson * │ 1958f502a40SAllison Henderson * v 1968f502a40SAllison Henderson * ┌─y─ has an attr fork? 1978f502a40SAllison Henderson * │ | 1988f502a40SAllison Henderson * │ n 1998f502a40SAllison Henderson * │ | 2008f502a40SAllison Henderson * │ V 2018f502a40SAllison Henderson * │ add a fork 2028f502a40SAllison Henderson * │ │ 2038f502a40SAllison Henderson * └──────────┤ 2048f502a40SAllison Henderson * │ 2058f502a40SAllison Henderson * V 2068f502a40SAllison Henderson * ┌─── is shortform? 2078f502a40SAllison Henderson * │ │ 2088f502a40SAllison Henderson * │ y 2098f502a40SAllison Henderson * │ │ 2108f502a40SAllison Henderson * │ V 2118f502a40SAllison Henderson * │ xfs_attr_set_fmt 2128f502a40SAllison Henderson * │ | 2138f502a40SAllison Henderson * │ V 2148f502a40SAllison Henderson * │ xfs_attr_try_sf_addname 2158f502a40SAllison Henderson * │ │ 2168f502a40SAllison Henderson * │ V 2178f502a40SAllison Henderson * │ had enough ──y──> done 2188f502a40SAllison Henderson * │ space? 2198f502a40SAllison Henderson * n │ 2208f502a40SAllison Henderson * │ n 2218f502a40SAllison Henderson * │ │ 2228f502a40SAllison Henderson * │ V 2238f502a40SAllison Henderson * │ transform to leaf 2248f502a40SAllison Henderson * │ │ 2258f502a40SAllison Henderson * │ V 2268f502a40SAllison Henderson * │ hold the leaf buffer 2278f502a40SAllison Henderson * │ │ 2288f502a40SAllison Henderson * │ V 2298f502a40SAllison Henderson * │ return -EAGAIN 2308f502a40SAllison Henderson * │ Re-enter in 2318f502a40SAllison Henderson * │ leaf form 2328f502a40SAllison Henderson * │ 2338f502a40SAllison Henderson * └─> release leaf buffer 2348f502a40SAllison Henderson * if needed 2358f502a40SAllison Henderson * │ 2368f502a40SAllison Henderson * V 2378f502a40SAllison Henderson * ┌───n── fork has 2388f502a40SAllison Henderson * │ only 1 blk? 2398f502a40SAllison Henderson * │ │ 2408f502a40SAllison Henderson * │ y 2418f502a40SAllison Henderson * │ │ 2428f502a40SAllison Henderson * │ v 2438f502a40SAllison Henderson * │ xfs_attr_leaf_try_add() 2448f502a40SAllison Henderson * │ │ 2458f502a40SAllison Henderson * │ v 2468f502a40SAllison Henderson * │ had enough ──────────────y─────────────┐ 2478f502a40SAllison Henderson * │ space? │ 2488f502a40SAllison Henderson * │ │ │ 2498f502a40SAllison Henderson * │ n │ 2508f502a40SAllison Henderson * │ │ │ 2518f502a40SAllison Henderson * │ v │ 2528f502a40SAllison Henderson * │ return -EAGAIN │ 2538f502a40SAllison Henderson * │ re-enter in │ 2548f502a40SAllison Henderson * │ node form │ 2558f502a40SAllison Henderson * │ │ │ 2568f502a40SAllison Henderson * └──────────┤ │ 2578f502a40SAllison Henderson * │ │ 2588f502a40SAllison Henderson * V │ 2598f502a40SAllison Henderson * xfs_attr_node_addname_find_attr │ 2608f502a40SAllison Henderson * determines if this │ 2618f502a40SAllison Henderson * is create or rename │ 2628f502a40SAllison Henderson * find space to store attr │ 2638f502a40SAllison Henderson * │ │ 2648f502a40SAllison Henderson * v │ 2658f502a40SAllison Henderson * xfs_attr_node_addname │ 2668f502a40SAllison Henderson * │ │ 2678f502a40SAllison Henderson * v │ 2688f502a40SAllison Henderson * fits in a node leaf? ────n─────┐ │ 2698f502a40SAllison Henderson * │ ^ v │ 2708f502a40SAllison Henderson * │ │ single leaf node? │ 2718f502a40SAllison Henderson * │ │ │ │ │ 2728f502a40SAllison Henderson * y │ y n │ 2738f502a40SAllison Henderson * │ │ │ │ │ 2748f502a40SAllison Henderson * v │ v v │ 2758f502a40SAllison Henderson * update │ grow the leaf split if │ 2768f502a40SAllison Henderson * hashvals └── return -EAGAIN needed │ 2778f502a40SAllison Henderson * │ retry leaf add │ │ 2788f502a40SAllison Henderson * │ on reentry │ │ 2798f502a40SAllison Henderson * ├────────────────────────────┘ │ 2808f502a40SAllison Henderson * │ │ 2818f502a40SAllison Henderson * v │ 2828f502a40SAllison Henderson * need to alloc │ 2838f502a40SAllison Henderson * ┌─y── or flip flag? │ 2848f502a40SAllison Henderson * │ │ │ 2858f502a40SAllison Henderson * │ n │ 2868f502a40SAllison Henderson * │ │ │ 2878f502a40SAllison Henderson * │ v │ 2888f502a40SAllison Henderson * │ done │ 2898f502a40SAllison Henderson * │ │ 2908f502a40SAllison Henderson * │ │ 2918f502a40SAllison Henderson * │ XFS_DAS_FOUND_LBLK <────────────────┘ 2928f502a40SAllison Henderson * │ │ 2938f502a40SAllison Henderson * │ V 2948f502a40SAllison Henderson * │ xfs_attr_leaf_addname() 2958f502a40SAllison Henderson * │ │ 2968f502a40SAllison Henderson * │ v 2978f502a40SAllison Henderson * │ ┌──first time through? 2988f502a40SAllison Henderson * │ │ │ 2998f502a40SAllison Henderson * │ │ y 3008f502a40SAllison Henderson * │ │ │ 3018f502a40SAllison Henderson * │ n v 3028f502a40SAllison Henderson * │ │ if we have rmt blks 3038f502a40SAllison Henderson * │ │ find space for them 3048f502a40SAllison Henderson * │ │ │ 3058f502a40SAllison Henderson * │ └──────────┤ 3068f502a40SAllison Henderson * │ │ 3078f502a40SAllison Henderson * │ v 3088f502a40SAllison Henderson * │ still have 3098f502a40SAllison Henderson * │ ┌─n─ blks to alloc? <──┐ 3108f502a40SAllison Henderson * │ │ │ │ 3118f502a40SAllison Henderson * │ │ y │ 3128f502a40SAllison Henderson * │ │ │ │ 3138f502a40SAllison Henderson * │ │ v │ 3148f502a40SAllison Henderson * │ │ alloc one blk │ 3158f502a40SAllison Henderson * │ │ return -EAGAIN ──┘ 3168f502a40SAllison Henderson * │ │ re-enter with one 3178f502a40SAllison Henderson * │ │ less blk to alloc 3188f502a40SAllison Henderson * │ │ 3198f502a40SAllison Henderson * │ │ 3208f502a40SAllison Henderson * │ └───> set the rmt 3218f502a40SAllison Henderson * │ value 3228f502a40SAllison Henderson * │ │ 3238f502a40SAllison Henderson * │ v 3248f502a40SAllison Henderson * │ was this 3258f502a40SAllison Henderson * │ a rename? ──n─┐ 3268f502a40SAllison Henderson * │ │ │ 3278f502a40SAllison Henderson * │ y │ 3288f502a40SAllison Henderson * │ │ │ 3298f502a40SAllison Henderson * │ v │ 3308f502a40SAllison Henderson * │ flip incomplete │ 3318f502a40SAllison Henderson * │ flag │ 3328f502a40SAllison Henderson * │ │ │ 3338f502a40SAllison Henderson * │ v │ 3348f502a40SAllison Henderson * │ XFS_DAS_FLIP_LFLAG │ 3358f502a40SAllison Henderson * │ │ │ 3368f502a40SAllison Henderson * │ v │ 3378f502a40SAllison Henderson * │ need to remove │ 3388f502a40SAllison Henderson * │ old bks? ──n──┤ 3398f502a40SAllison Henderson * │ │ │ 3408f502a40SAllison Henderson * │ y │ 3418f502a40SAllison Henderson * │ │ │ 3428f502a40SAllison Henderson * │ V │ 3438f502a40SAllison Henderson * │ remove │ 3448f502a40SAllison Henderson * │ ┌───> old blks │ 3458f502a40SAllison Henderson * │ │ │ │ 3468f502a40SAllison Henderson * │ XFS_DAS_RM_LBLK │ │ 3478f502a40SAllison Henderson * │ ^ │ │ 3488f502a40SAllison Henderson * │ │ v │ 3498f502a40SAllison Henderson * │ └──y── more to │ 3508f502a40SAllison Henderson * │ remove? │ 3518f502a40SAllison Henderson * │ │ │ 3528f502a40SAllison Henderson * │ n │ 3538f502a40SAllison Henderson * │ │ │ 3548f502a40SAllison Henderson * │ v │ 3558f502a40SAllison Henderson * │ XFS_DAS_RD_LEAF │ 3568f502a40SAllison Henderson * │ │ │ 3578f502a40SAllison Henderson * │ v │ 3588f502a40SAllison Henderson * │ remove leaf │ 3598f502a40SAllison Henderson * │ │ │ 3608f502a40SAllison Henderson * │ v │ 3618f502a40SAllison Henderson * │ shrink to sf │ 3628f502a40SAllison Henderson * │ if needed │ 3638f502a40SAllison Henderson * │ │ │ 3648f502a40SAllison Henderson * │ v │ 3658f502a40SAllison Henderson * │ done <──────┘ 3668f502a40SAllison Henderson * │ 3678f502a40SAllison Henderson * └──────> XFS_DAS_FOUND_NBLK 3688f502a40SAllison Henderson * │ 3698f502a40SAllison Henderson * v 3708f502a40SAllison Henderson * ┌─────n── need to 3718f502a40SAllison Henderson * │ alloc blks? 3728f502a40SAllison Henderson * │ │ 3738f502a40SAllison Henderson * │ y 3748f502a40SAllison Henderson * │ │ 3758f502a40SAllison Henderson * │ v 3768f502a40SAllison Henderson * │ find space 3778f502a40SAllison Henderson * │ │ 3788f502a40SAllison Henderson * │ v 3798f502a40SAllison Henderson * │ ┌─>XFS_DAS_ALLOC_NODE 3808f502a40SAllison Henderson * │ │ │ 3818f502a40SAllison Henderson * │ │ v 3828f502a40SAllison Henderson * │ │ alloc blk 3838f502a40SAllison Henderson * │ │ │ 3848f502a40SAllison Henderson * │ │ v 3858f502a40SAllison Henderson * │ └──y── need to alloc 3868f502a40SAllison Henderson * │ more blocks? 3878f502a40SAllison Henderson * │ │ 3888f502a40SAllison Henderson * │ n 3898f502a40SAllison Henderson * │ │ 3908f502a40SAllison Henderson * │ v 3918f502a40SAllison Henderson * │ set the rmt value 3928f502a40SAllison Henderson * │ │ 3938f502a40SAllison Henderson * │ v 3948f502a40SAllison Henderson * │ was this 3958f502a40SAllison Henderson * └────────> a rename? ──n─┐ 3968f502a40SAllison Henderson * │ │ 3978f502a40SAllison Henderson * y │ 3988f502a40SAllison Henderson * │ │ 3998f502a40SAllison Henderson * v │ 4008f502a40SAllison Henderson * flip incomplete │ 4018f502a40SAllison Henderson * flag │ 4028f502a40SAllison Henderson * │ │ 4038f502a40SAllison Henderson * v │ 4048f502a40SAllison Henderson * XFS_DAS_FLIP_NFLAG │ 4058f502a40SAllison Henderson * │ │ 4068f502a40SAllison Henderson * v │ 4078f502a40SAllison Henderson * need to │ 4088f502a40SAllison Henderson * remove blks? ─n──┤ 4098f502a40SAllison Henderson * │ │ 4108f502a40SAllison Henderson * y │ 4118f502a40SAllison Henderson * │ │ 4128f502a40SAllison Henderson * v │ 4138f502a40SAllison Henderson * remove │ 4148f502a40SAllison Henderson * ┌────────> old blks │ 4158f502a40SAllison Henderson * │ │ │ 4168f502a40SAllison Henderson * XFS_DAS_RM_NBLK │ │ 4178f502a40SAllison Henderson * ^ │ │ 4188f502a40SAllison Henderson * │ v │ 4198f502a40SAllison Henderson * └──────y── more to │ 4208f502a40SAllison Henderson * remove │ 4218f502a40SAllison Henderson * │ │ 4228f502a40SAllison Henderson * n │ 4238f502a40SAllison Henderson * │ │ 4248f502a40SAllison Henderson * v │ 4258f502a40SAllison Henderson * XFS_DAS_CLR_FLAG │ 4268f502a40SAllison Henderson * │ │ 4278f502a40SAllison Henderson * v │ 4288f502a40SAllison Henderson * clear flags │ 4298f502a40SAllison Henderson * │ │ 4308f502a40SAllison Henderson * ├──────────┘ 4318f502a40SAllison Henderson * │ 4328f502a40SAllison Henderson * v 4338f502a40SAllison Henderson * done 4342b74b03cSAllison Henderson */ 4352b74b03cSAllison Henderson 4362b74b03cSAllison Henderson /* 437d68c51e9SAllison Henderson * Enum values for xfs_attr_item.xattri_da_state 4382b74b03cSAllison Henderson * 4392b74b03cSAllison Henderson * These values are used by delayed attribute operations to keep track of where 4402b74b03cSAllison Henderson * they were before they returned -EAGAIN. A return code of -EAGAIN signals the 4412b74b03cSAllison Henderson * calling function to roll the transaction, and then call the subroutine to 4422b74b03cSAllison Henderson * finish the operation. The enum is then used by the subroutine to jump back 4432b74b03cSAllison Henderson * to where it was and resume executing where it left off. 4442b74b03cSAllison Henderson */ 4452b74b03cSAllison Henderson enum xfs_delattr_state { 4462b74b03cSAllison Henderson XFS_DAS_UNINIT = 0, /* No state has been set yet */ 447251b29c8SDave Chinner 448fdaf1bb3SDave Chinner /* 449fdaf1bb3SDave Chinner * Initial sequence states. The replace setup code relies on the 450fdaf1bb3SDave Chinner * ADD and REMOVE states for a specific format to be sequential so 451fdaf1bb3SDave Chinner * that we can transform the initial operation to be performed 452fdaf1bb3SDave Chinner * according to the xfs_has_larp() state easily. 453fdaf1bb3SDave Chinner */ 454fdaf1bb3SDave Chinner XFS_DAS_SF_ADD, /* Initial sf add state */ 455fdaf1bb3SDave Chinner XFS_DAS_SF_REMOVE, /* Initial sf replace/remove state */ 456e5d5596aSDave Chinner 457fdaf1bb3SDave Chinner XFS_DAS_LEAF_ADD, /* Initial leaf add state */ 458fdaf1bb3SDave Chinner XFS_DAS_LEAF_REMOVE, /* Initial leaf replace/remove state */ 459fdaf1bb3SDave Chinner 460fdaf1bb3SDave Chinner XFS_DAS_NODE_ADD, /* Initial node add state */ 461fdaf1bb3SDave Chinner XFS_DAS_NODE_REMOVE, /* Initial node replace/remove state */ 462fdaf1bb3SDave Chinner 463fdaf1bb3SDave Chinner /* Leaf state set/replace/remove sequence */ 4647d035336SDave Chinner XFS_DAS_LEAF_SET_RMT, /* set a remote xattr from a leaf */ 4652157d169SDave Chinner XFS_DAS_LEAF_ALLOC_RMT, /* We are allocating remote blocks */ 4667d035336SDave Chinner XFS_DAS_LEAF_REPLACE, /* Perform replace ops on a leaf */ 467411b434aSDave Chinner XFS_DAS_LEAF_REMOVE_OLD, /* Start removing old attr from leaf */ 4682e7ef218SDave Chinner XFS_DAS_LEAF_REMOVE_RMT, /* A rename is removing remote blocks */ 469b11fa61bSDave Chinner XFS_DAS_LEAF_REMOVE_ATTR, /* Remove the old attr from a leaf */ 470251b29c8SDave Chinner 471fdaf1bb3SDave Chinner /* Node state sequence, must match leaf state above */ 4727d035336SDave Chinner XFS_DAS_NODE_SET_RMT, /* set a remote xattr from a node */ 473251b29c8SDave Chinner XFS_DAS_NODE_ALLOC_RMT, /* We are allocating remote blocks */ 4747d035336SDave Chinner XFS_DAS_NODE_REPLACE, /* Perform replace ops on a node */ 475411b434aSDave Chinner XFS_DAS_NODE_REMOVE_OLD, /* Start removing old attr from node */ 4762e7ef218SDave Chinner XFS_DAS_NODE_REMOVE_RMT, /* A rename is removing remote blocks */ 477b11fa61bSDave Chinner XFS_DAS_NODE_REMOVE_ATTR, /* Remove the old attr from a node */ 478251b29c8SDave Chinner 479e0c41089SDave Chinner XFS_DAS_DONE, /* finished operation */ 4802b74b03cSAllison Henderson }; 4812b74b03cSAllison Henderson 482e0c41089SDave Chinner #define XFS_DAS_STRINGS \ 483e0c41089SDave Chinner { XFS_DAS_UNINIT, "XFS_DAS_UNINIT" }, \ 484e0c41089SDave Chinner { XFS_DAS_SF_ADD, "XFS_DAS_SF_ADD" }, \ 485fdaf1bb3SDave Chinner { XFS_DAS_SF_REMOVE, "XFS_DAS_SF_REMOVE" }, \ 486e0c41089SDave Chinner { XFS_DAS_LEAF_ADD, "XFS_DAS_LEAF_ADD" }, \ 487fdaf1bb3SDave Chinner { XFS_DAS_LEAF_REMOVE, "XFS_DAS_LEAF_REMOVE" }, \ 488e0c41089SDave Chinner { XFS_DAS_NODE_ADD, "XFS_DAS_NODE_ADD" }, \ 489fdaf1bb3SDave Chinner { XFS_DAS_NODE_REMOVE, "XFS_DAS_NODE_REMOVE" }, \ 4907d035336SDave Chinner { XFS_DAS_LEAF_SET_RMT, "XFS_DAS_LEAF_SET_RMT" }, \ 4912157d169SDave Chinner { XFS_DAS_LEAF_ALLOC_RMT, "XFS_DAS_LEAF_ALLOC_RMT" }, \ 4927d035336SDave Chinner { XFS_DAS_LEAF_REPLACE, "XFS_DAS_LEAF_REPLACE" }, \ 493411b434aSDave Chinner { XFS_DAS_LEAF_REMOVE_OLD, "XFS_DAS_LEAF_REMOVE_OLD" }, \ 4942e7ef218SDave Chinner { XFS_DAS_LEAF_REMOVE_RMT, "XFS_DAS_LEAF_REMOVE_RMT" }, \ 495b11fa61bSDave Chinner { XFS_DAS_LEAF_REMOVE_ATTR, "XFS_DAS_LEAF_REMOVE_ATTR" }, \ 4967d035336SDave Chinner { XFS_DAS_NODE_SET_RMT, "XFS_DAS_NODE_SET_RMT" }, \ 4977d035336SDave Chinner { XFS_DAS_NODE_ALLOC_RMT, "XFS_DAS_NODE_ALLOC_RMT" }, \ 4987d035336SDave Chinner { XFS_DAS_NODE_REPLACE, "XFS_DAS_NODE_REPLACE" }, \ 499411b434aSDave Chinner { XFS_DAS_NODE_REMOVE_OLD, "XFS_DAS_NODE_REMOVE_OLD" }, \ 5002e7ef218SDave Chinner { XFS_DAS_NODE_REMOVE_RMT, "XFS_DAS_NODE_REMOVE_RMT" }, \ 501b11fa61bSDave Chinner { XFS_DAS_NODE_REMOVE_ATTR, "XFS_DAS_NODE_REMOVE_ATTR" }, \ 502e0c41089SDave Chinner { XFS_DAS_DONE, "XFS_DAS_DONE" } 503e0c41089SDave Chinner 5042b74b03cSAllison Henderson /* 505d68c51e9SAllison Henderson * Defines for xfs_attr_item.xattri_flags 5062b74b03cSAllison Henderson */ 50773159fc2SAllison Henderson #define XFS_DAC_LEAF_ADDNAME_INIT 0x01 /* xfs_attr_leaf_addname init*/ 5082b74b03cSAllison Henderson 5092b74b03cSAllison Henderson /* 5102b74b03cSAllison Henderson * Context used for keeping track of delayed attribute operations 5112b74b03cSAllison Henderson */ 512d68c51e9SAllison Henderson struct xfs_attr_item { 513d68c51e9SAllison Henderson struct xfs_da_args *xattri_da_args; 5142b74b03cSAllison Henderson 515fd920008SAllison Henderson /* 516fd920008SAllison Henderson * Used by xfs_attr_set to hold a leaf buffer across a transaction roll 517fd920008SAllison Henderson */ 518d68c51e9SAllison Henderson struct xfs_buf *xattri_leaf_bp; 519fd920008SAllison Henderson 5208f502a40SAllison Henderson /* Used in xfs_attr_rmtval_set_blk to roll through allocating blocks */ 521d68c51e9SAllison Henderson struct xfs_bmbt_irec xattri_map; 522d68c51e9SAllison Henderson xfs_dablk_t xattri_lblkno; 523d68c51e9SAllison Henderson int xattri_blkcnt; 5248f502a40SAllison Henderson 5252b74b03cSAllison Henderson /* Used in xfs_attr_node_removename to roll through removing blocks */ 526d68c51e9SAllison Henderson struct xfs_da_state *xattri_da_state; 5272b74b03cSAllison Henderson 5282b74b03cSAllison Henderson /* Used to keep track of current state of delayed operation */ 529d68c51e9SAllison Henderson unsigned int xattri_flags; 530d68c51e9SAllison Henderson enum xfs_delattr_state xattri_dela_state; 531fd920008SAllison Henderson 532fd920008SAllison Henderson /* 533b53d212bSDarrick J. Wong * Attr operation being performed - XFS_ATTRI_OP_FLAGS_* 534fd920008SAllison Henderson */ 535fd920008SAllison Henderson unsigned int xattri_op_flags; 536fd920008SAllison Henderson 537d68c51e9SAllison Henderson /* 538d68c51e9SAllison Henderson * used to log this item to an intent containing a list of attrs to 539d68c51e9SAllison Henderson * commit later 540d68c51e9SAllison Henderson */ 541fd920008SAllison Henderson struct list_head xattri_list; 542fd920008SAllison Henderson }; 543fd920008SAllison Henderson 544fd920008SAllison Henderson 545e2421f0bSAllison Henderson /*======================================================================== 546e2421f0bSAllison Henderson * Function prototypes for the kernel. 547e2421f0bSAllison Henderson *========================================================================*/ 548e2421f0bSAllison Henderson 549e2421f0bSAllison Henderson /* 550e2421f0bSAllison Henderson * Overall external interface routines. 551e2421f0bSAllison Henderson */ 552e2421f0bSAllison Henderson int xfs_attr_inactive(struct xfs_inode *dp); 55317e1dd83SChristoph Hellwig int xfs_attr_list_ilocked(struct xfs_attr_list_context *); 55417e1dd83SChristoph Hellwig int xfs_attr_list(struct xfs_attr_list_context *); 555e2421f0bSAllison Henderson int xfs_inode_hasattr(struct xfs_inode *ip); 5562ac131dfSChristoph Hellwig bool xfs_attr_is_leaf(struct xfs_inode *ip); 557c36f533fSChristoph Hellwig int xfs_attr_get_ilocked(struct xfs_da_args *args); 558e5171d7eSChristoph Hellwig int xfs_attr_get(struct xfs_da_args *args); 559a2544622SChristoph Hellwig int xfs_attr_set(struct xfs_da_args *args); 560d68c51e9SAllison Henderson int xfs_attr_set_iter(struct xfs_attr_item *attr); 561d68c51e9SAllison Henderson int xfs_attr_remove_iter(struct xfs_attr_item *attr); 56265480536SDarrick J. Wong bool xfs_attr_namecheck(const void *name, size_t length); 563fd920008SAllison Henderson int xfs_attr_calc_size(struct xfs_da_args *args, int *local); 564c3546cf5SAllison Henderson void xfs_init_attr_trans(struct xfs_da_args *args, struct xfs_trans_res *tres, 565c3546cf5SAllison Henderson unsigned int *total); 566fd920008SAllison Henderson 567fd920008SAllison Henderson extern struct kmem_cache *xfs_attri_cache; 568fd920008SAllison Henderson extern struct kmem_cache *xfs_attrd_cache; 569fd920008SAllison Henderson 570fd920008SAllison Henderson int __init xfs_attri_init_cache(void); 571fd920008SAllison Henderson void xfs_attri_destroy_cache(void); 572fd920008SAllison Henderson int __init xfs_attrd_init_cache(void); 573fd920008SAllison Henderson void xfs_attrd_destroy_cache(void); 574e2421f0bSAllison Henderson 575e0c41089SDave Chinner /* 576e0c41089SDave Chinner * Check to see if the attr should be upgraded from non-existent or shortform to 577e0c41089SDave Chinner * single-leaf-block attribute list. 578e0c41089SDave Chinner */ 579e0c41089SDave Chinner static inline bool 580e0c41089SDave Chinner xfs_attr_is_shortform( 581e0c41089SDave Chinner struct xfs_inode *ip) 582e0c41089SDave Chinner { 583e0c41089SDave Chinner return ip->i_afp->if_format == XFS_DINODE_FMT_LOCAL || 584e0c41089SDave Chinner (ip->i_afp->if_format == XFS_DINODE_FMT_EXTENTS && 585e0c41089SDave Chinner ip->i_afp->if_nextents == 0); 586e0c41089SDave Chinner } 587e0c41089SDave Chinner 588e0c41089SDave Chinner static inline enum xfs_delattr_state 589e0c41089SDave Chinner xfs_attr_init_add_state(struct xfs_da_args *args) 590e0c41089SDave Chinner { 591e0c41089SDave Chinner /* 592e0c41089SDave Chinner * When called from the completion of a attr remove to determine the 593e0c41089SDave Chinner * next state, the attribute fork may be null. This can occur only occur 594e0c41089SDave Chinner * on a pure remove, but we grab the next state before we check if a 595e0c41089SDave Chinner * replace operation is being performed. If we are called from any other 596e0c41089SDave Chinner * context, i_afp is guaranteed to exist. Hence if the attr fork is 597e0c41089SDave Chinner * null, we were called from a pure remove operation and so we are done. 598e0c41089SDave Chinner */ 599e0c41089SDave Chinner if (!args->dp->i_afp) 600e0c41089SDave Chinner return XFS_DAS_DONE; 601e7f358deSDave Chinner 602e7f358deSDave Chinner args->op_flags |= XFS_DA_OP_ADDNAME; 603e0c41089SDave Chinner if (xfs_attr_is_shortform(args->dp)) 604e0c41089SDave Chinner return XFS_DAS_SF_ADD; 605e0c41089SDave Chinner if (xfs_attr_is_leaf(args->dp)) 606e0c41089SDave Chinner return XFS_DAS_LEAF_ADD; 607e0c41089SDave Chinner return XFS_DAS_NODE_ADD; 608e0c41089SDave Chinner } 609e0c41089SDave Chinner 610e0c41089SDave Chinner static inline enum xfs_delattr_state 6114b9879b1SDave Chinner xfs_attr_init_remove_state(struct xfs_da_args *args) 6124b9879b1SDave Chinner { 613e7f358deSDave Chinner args->op_flags |= XFS_DA_OP_REMOVE; 6144b9879b1SDave Chinner if (xfs_attr_is_shortform(args->dp)) 6154b9879b1SDave Chinner return XFS_DAS_SF_REMOVE; 6164b9879b1SDave Chinner if (xfs_attr_is_leaf(args->dp)) 6174b9879b1SDave Chinner return XFS_DAS_LEAF_REMOVE; 6184b9879b1SDave Chinner return XFS_DAS_NODE_REMOVE; 6194b9879b1SDave Chinner } 6204b9879b1SDave Chinner 621fdaf1bb3SDave Chinner /* 622fdaf1bb3SDave Chinner * If we are logging the attributes, then we have to start with removal of the 623fdaf1bb3SDave Chinner * old attribute so that there is always consistent state that we can recover 624fdaf1bb3SDave Chinner * from if the system goes down part way through. We always log the new attr 625fdaf1bb3SDave Chinner * value, so even when we remove the attr first we still have the information in 626fdaf1bb3SDave Chinner * the log to finish the replace operation atomically. 627fdaf1bb3SDave Chinner */ 6284b9879b1SDave Chinner static inline enum xfs_delattr_state 629e0c41089SDave Chinner xfs_attr_init_replace_state(struct xfs_da_args *args) 630e0c41089SDave Chinner { 631e7f358deSDave Chinner args->op_flags |= XFS_DA_OP_ADDNAME | XFS_DA_OP_REPLACE; 632fdaf1bb3SDave Chinner if (xfs_has_larp(args->dp->i_mount)) 633fdaf1bb3SDave Chinner return xfs_attr_init_remove_state(args); 634e0c41089SDave Chinner return xfs_attr_init_add_state(args); 635e0c41089SDave Chinner } 636e0c41089SDave Chinner 637*e2c78949SDarrick J. Wong extern struct kmem_cache *xfs_attr_intent_cache; 638*e2c78949SDarrick J. Wong int __init xfs_attr_intent_init_cache(void); 639*e2c78949SDarrick J. Wong void xfs_attr_intent_destroy_cache(void); 640*e2c78949SDarrick J. Wong 641e2421f0bSAllison Henderson #endif /* __XFS_ATTR_H__ */ 642