1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun File: fs/ext4/xattr.h
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun On-disk format of extended attributes for the ext4 filesystem.
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <linux/xattr.h>
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun /* Magic value in attribute blocks */
13*4882a593Smuzhiyun #define EXT4_XATTR_MAGIC 0xEA020000
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun /* Maximum number of references to one attribute block */
16*4882a593Smuzhiyun #define EXT4_XATTR_REFCOUNT_MAX 1024
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun /* Name indexes */
19*4882a593Smuzhiyun #define EXT4_XATTR_INDEX_USER 1
20*4882a593Smuzhiyun #define EXT4_XATTR_INDEX_POSIX_ACL_ACCESS 2
21*4882a593Smuzhiyun #define EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT 3
22*4882a593Smuzhiyun #define EXT4_XATTR_INDEX_TRUSTED 4
23*4882a593Smuzhiyun #define EXT4_XATTR_INDEX_LUSTRE 5
24*4882a593Smuzhiyun #define EXT4_XATTR_INDEX_SECURITY 6
25*4882a593Smuzhiyun #define EXT4_XATTR_INDEX_SYSTEM 7
26*4882a593Smuzhiyun #define EXT4_XATTR_INDEX_RICHACL 8
27*4882a593Smuzhiyun #define EXT4_XATTR_INDEX_ENCRYPTION 9
28*4882a593Smuzhiyun #define EXT4_XATTR_INDEX_HURD 10 /* Reserved for Hurd */
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun struct ext4_xattr_header {
31*4882a593Smuzhiyun __le32 h_magic; /* magic number for identification */
32*4882a593Smuzhiyun __le32 h_refcount; /* reference count */
33*4882a593Smuzhiyun __le32 h_blocks; /* number of disk blocks used */
34*4882a593Smuzhiyun __le32 h_hash; /* hash value of all attributes */
35*4882a593Smuzhiyun __le32 h_checksum; /* crc32c(uuid+id+xattrblock) */
36*4882a593Smuzhiyun /* id = inum if refcount=1, blknum otherwise */
37*4882a593Smuzhiyun __u32 h_reserved[3]; /* zero right now */
38*4882a593Smuzhiyun };
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun struct ext4_xattr_ibody_header {
41*4882a593Smuzhiyun __le32 h_magic; /* magic number for identification */
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun struct ext4_xattr_entry {
45*4882a593Smuzhiyun __u8 e_name_len; /* length of name */
46*4882a593Smuzhiyun __u8 e_name_index; /* attribute name index */
47*4882a593Smuzhiyun __le16 e_value_offs; /* offset in disk block of value */
48*4882a593Smuzhiyun __le32 e_value_inum; /* inode in which the value is stored */
49*4882a593Smuzhiyun __le32 e_value_size; /* size of attribute value */
50*4882a593Smuzhiyun __le32 e_hash; /* hash value of name and value */
51*4882a593Smuzhiyun char e_name[]; /* attribute name */
52*4882a593Smuzhiyun };
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun #define EXT4_XATTR_PAD_BITS 2
55*4882a593Smuzhiyun #define EXT4_XATTR_PAD (1<<EXT4_XATTR_PAD_BITS)
56*4882a593Smuzhiyun #define EXT4_XATTR_ROUND (EXT4_XATTR_PAD-1)
57*4882a593Smuzhiyun #define EXT4_XATTR_LEN(name_len) \
58*4882a593Smuzhiyun (((name_len) + EXT4_XATTR_ROUND + \
59*4882a593Smuzhiyun sizeof(struct ext4_xattr_entry)) & ~EXT4_XATTR_ROUND)
60*4882a593Smuzhiyun #define EXT4_XATTR_NEXT(entry) \
61*4882a593Smuzhiyun ((struct ext4_xattr_entry *)( \
62*4882a593Smuzhiyun (char *)(entry) + EXT4_XATTR_LEN((entry)->e_name_len)))
63*4882a593Smuzhiyun #define EXT4_XATTR_SIZE(size) \
64*4882a593Smuzhiyun (((size) + EXT4_XATTR_ROUND) & ~EXT4_XATTR_ROUND)
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun #define IHDR(inode, raw_inode) \
67*4882a593Smuzhiyun ((struct ext4_xattr_ibody_header *) \
68*4882a593Smuzhiyun ((void *)raw_inode + \
69*4882a593Smuzhiyun EXT4_GOOD_OLD_INODE_SIZE + \
70*4882a593Smuzhiyun EXT4_I(inode)->i_extra_isize))
71*4882a593Smuzhiyun #define IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr)+1))
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun /*
74*4882a593Smuzhiyun * XATTR_SIZE_MAX is currently 64k, but for the purposes of checking
75*4882a593Smuzhiyun * for file system consistency errors, we use a somewhat bigger value.
76*4882a593Smuzhiyun * This allows XATTR_SIZE_MAX to grow in the future, but by using this
77*4882a593Smuzhiyun * instead of INT_MAX for certain consistency checks, we don't need to
78*4882a593Smuzhiyun * worry about arithmetic overflows. (Actually XATTR_SIZE_MAX is
79*4882a593Smuzhiyun * defined in include/uapi/linux/limits.h, so changing it is going
80*4882a593Smuzhiyun * not going to be trivial....)
81*4882a593Smuzhiyun */
82*4882a593Smuzhiyun #define EXT4_XATTR_SIZE_MAX (1 << 24)
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun /*
85*4882a593Smuzhiyun * The minimum size of EA value when you start storing it in an external inode
86*4882a593Smuzhiyun * size of block - size of header - size of 1 entry - 4 null bytes
87*4882a593Smuzhiyun */
88*4882a593Smuzhiyun #define EXT4_XATTR_MIN_LARGE_EA_SIZE(b) \
89*4882a593Smuzhiyun ((b) - EXT4_XATTR_LEN(3) - sizeof(struct ext4_xattr_header) - 4)
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun #define BHDR(bh) ((struct ext4_xattr_header *)((bh)->b_data))
92*4882a593Smuzhiyun #define ENTRY(ptr) ((struct ext4_xattr_entry *)(ptr))
93*4882a593Smuzhiyun #define BFIRST(bh) ENTRY(BHDR(bh)+1)
94*4882a593Smuzhiyun #define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0)
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun #define EXT4_ZERO_XATTR_VALUE ((void *)-1)
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun /*
99*4882a593Smuzhiyun * If we want to add an xattr to the inode, we should make sure that
100*4882a593Smuzhiyun * i_extra_isize is not 0 and that the inode size is not less than
101*4882a593Smuzhiyun * EXT4_GOOD_OLD_INODE_SIZE + extra_isize + pad.
102*4882a593Smuzhiyun * EXT4_GOOD_OLD_INODE_SIZE extra_isize header entry pad data
103*4882a593Smuzhiyun * |--------------------------|------------|------|---------|---|-------|
104*4882a593Smuzhiyun */
105*4882a593Smuzhiyun #define EXT4_INODE_HAS_XATTR_SPACE(inode) \
106*4882a593Smuzhiyun ((EXT4_I(inode)->i_extra_isize != 0) && \
107*4882a593Smuzhiyun (EXT4_GOOD_OLD_INODE_SIZE + EXT4_I(inode)->i_extra_isize + \
108*4882a593Smuzhiyun sizeof(struct ext4_xattr_ibody_header) + EXT4_XATTR_PAD <= \
109*4882a593Smuzhiyun EXT4_INODE_SIZE((inode)->i_sb)))
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun struct ext4_xattr_info {
112*4882a593Smuzhiyun const char *name;
113*4882a593Smuzhiyun const void *value;
114*4882a593Smuzhiyun size_t value_len;
115*4882a593Smuzhiyun int name_index;
116*4882a593Smuzhiyun int in_inode;
117*4882a593Smuzhiyun };
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun struct ext4_xattr_search {
120*4882a593Smuzhiyun struct ext4_xattr_entry *first;
121*4882a593Smuzhiyun void *base;
122*4882a593Smuzhiyun void *end;
123*4882a593Smuzhiyun struct ext4_xattr_entry *here;
124*4882a593Smuzhiyun int not_found;
125*4882a593Smuzhiyun };
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun struct ext4_xattr_ibody_find {
128*4882a593Smuzhiyun struct ext4_xattr_search s;
129*4882a593Smuzhiyun struct ext4_iloc iloc;
130*4882a593Smuzhiyun };
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun struct ext4_xattr_inode_array {
133*4882a593Smuzhiyun unsigned int count; /* # of used items in the array */
134*4882a593Smuzhiyun struct inode *inodes[];
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun extern const struct xattr_handler ext4_xattr_user_handler;
138*4882a593Smuzhiyun extern const struct xattr_handler ext4_xattr_trusted_handler;
139*4882a593Smuzhiyun extern const struct xattr_handler ext4_xattr_security_handler;
140*4882a593Smuzhiyun extern const struct xattr_handler ext4_xattr_hurd_handler;
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun #define EXT4_XATTR_NAME_ENCRYPTION_CONTEXT "c"
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun /*
145*4882a593Smuzhiyun * The EXT4_STATE_NO_EXPAND is overloaded and used for two purposes.
146*4882a593Smuzhiyun * The first is to signal that there the inline xattrs and data are
147*4882a593Smuzhiyun * taking up so much space that we might as well not keep trying to
148*4882a593Smuzhiyun * expand it. The second is that xattr_sem is taken for writing, so
149*4882a593Smuzhiyun * we shouldn't try to recurse into the inode expansion. For this
150*4882a593Smuzhiyun * second case, we need to make sure that we take save and restore the
151*4882a593Smuzhiyun * NO_EXPAND state flag appropriately.
152*4882a593Smuzhiyun */
ext4_write_lock_xattr(struct inode * inode,int * save)153*4882a593Smuzhiyun static inline void ext4_write_lock_xattr(struct inode *inode, int *save)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun down_write(&EXT4_I(inode)->xattr_sem);
156*4882a593Smuzhiyun *save = ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND);
157*4882a593Smuzhiyun ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND);
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun
ext4_write_trylock_xattr(struct inode * inode,int * save)160*4882a593Smuzhiyun static inline int ext4_write_trylock_xattr(struct inode *inode, int *save)
161*4882a593Smuzhiyun {
162*4882a593Smuzhiyun if (down_write_trylock(&EXT4_I(inode)->xattr_sem) == 0)
163*4882a593Smuzhiyun return 0;
164*4882a593Smuzhiyun *save = ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND);
165*4882a593Smuzhiyun ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND);
166*4882a593Smuzhiyun return 1;
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun
ext4_write_unlock_xattr(struct inode * inode,int * save)169*4882a593Smuzhiyun static inline void ext4_write_unlock_xattr(struct inode *inode, int *save)
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun if (*save == 0)
172*4882a593Smuzhiyun ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND);
173*4882a593Smuzhiyun up_write(&EXT4_I(inode)->xattr_sem);
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun extern ssize_t ext4_listxattr(struct dentry *, char *, size_t);
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun extern int ext4_xattr_get(struct inode *, int, const char *, void *, size_t);
179*4882a593Smuzhiyun extern int ext4_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
180*4882a593Smuzhiyun extern int ext4_xattr_set_handle(handle_t *, struct inode *, int, const char *, const void *, size_t, int);
181*4882a593Smuzhiyun extern int ext4_xattr_set_credits(struct inode *inode, size_t value_len,
182*4882a593Smuzhiyun bool is_create, int *credits);
183*4882a593Smuzhiyun extern int __ext4_xattr_set_credits(struct super_block *sb, struct inode *inode,
184*4882a593Smuzhiyun struct buffer_head *block_bh, size_t value_len,
185*4882a593Smuzhiyun bool is_create);
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun extern int ext4_xattr_delete_inode(handle_t *handle, struct inode *inode,
188*4882a593Smuzhiyun struct ext4_xattr_inode_array **array,
189*4882a593Smuzhiyun int extra_credits);
190*4882a593Smuzhiyun extern void ext4_xattr_inode_array_free(struct ext4_xattr_inode_array *array);
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun extern int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize,
193*4882a593Smuzhiyun struct ext4_inode *raw_inode, handle_t *handle);
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun extern const struct xattr_handler *ext4_xattr_handlers[];
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun extern int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
198*4882a593Smuzhiyun struct ext4_xattr_ibody_find *is);
199*4882a593Smuzhiyun extern int ext4_xattr_ibody_get(struct inode *inode, int name_index,
200*4882a593Smuzhiyun const char *name,
201*4882a593Smuzhiyun void *buffer, size_t buffer_size);
202*4882a593Smuzhiyun extern int ext4_xattr_ibody_inline_set(handle_t *handle, struct inode *inode,
203*4882a593Smuzhiyun struct ext4_xattr_info *i,
204*4882a593Smuzhiyun struct ext4_xattr_ibody_find *is);
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun extern struct mb_cache *ext4_xattr_create_cache(void);
207*4882a593Smuzhiyun extern void ext4_xattr_destroy_cache(struct mb_cache *);
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun #ifdef CONFIG_EXT4_FS_SECURITY
210*4882a593Smuzhiyun extern int ext4_init_security(handle_t *handle, struct inode *inode,
211*4882a593Smuzhiyun struct inode *dir, const struct qstr *qstr);
212*4882a593Smuzhiyun #else
ext4_init_security(handle_t * handle,struct inode * inode,struct inode * dir,const struct qstr * qstr)213*4882a593Smuzhiyun static inline int ext4_init_security(handle_t *handle, struct inode *inode,
214*4882a593Smuzhiyun struct inode *dir, const struct qstr *qstr)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun return 0;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun #endif
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun #ifdef CONFIG_LOCKDEP
221*4882a593Smuzhiyun extern void ext4_xattr_inode_set_class(struct inode *ea_inode);
222*4882a593Smuzhiyun #else
ext4_xattr_inode_set_class(struct inode * ea_inode)223*4882a593Smuzhiyun static inline void ext4_xattr_inode_set_class(struct inode *ea_inode) { }
224*4882a593Smuzhiyun #endif
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun extern int ext4_get_inode_usage(struct inode *inode, qsize_t *usage);
227