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