Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : /*
3 : : * fs/f2fs/xattr.c
4 : : *
5 : : * Copyright (c) 2012 Samsung Electronics Co., Ltd.
6 : : * http://www.samsung.com/
7 : : *
8 : : * Portions of this code from linux/fs/ext2/xattr.c
9 : : *
10 : : * Copyright (C) 2001-2003 Andreas Gruenbacher <agruen@suse.de>
11 : : *
12 : : * Fix by Harrison Xing <harrison@mountainviewdata.com>.
13 : : * Extended attributes for symlinks and special files added per
14 : : * suggestion of Luka Renko <luka.renko@hermes.si>.
15 : : * xattr consolidation Copyright (c) 2004 James Morris <jmorris@redhat.com>,
16 : : * Red Hat Inc.
17 : : */
18 : : #include <linux/rwsem.h>
19 : : #include <linux/f2fs_fs.h>
20 : : #include <linux/security.h>
21 : : #include <linux/posix_acl_xattr.h>
22 : : #include "f2fs.h"
23 : : #include "xattr.h"
24 : : #include "segment.h"
25 : :
26 : 0 : static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
27 : : struct dentry *unused, struct inode *inode,
28 : : const char *name, void *buffer, size_t size)
29 : : {
30 : 0 : struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
31 : :
32 [ # # # ]: 0 : switch (handler->flags) {
33 : : case F2FS_XATTR_INDEX_USER:
34 [ # # ]: 0 : if (!test_opt(sbi, XATTR_USER))
35 : : return -EOPNOTSUPP;
36 : : break;
37 : : case F2FS_XATTR_INDEX_TRUSTED:
38 : : case F2FS_XATTR_INDEX_SECURITY:
39 : : break;
40 : : default:
41 : : return -EINVAL;
42 : : }
43 : 0 : return f2fs_getxattr(inode, handler->flags, name,
44 : : buffer, size, NULL);
45 : : }
46 : :
47 : 0 : static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
48 : : struct dentry *unused, struct inode *inode,
49 : : const char *name, const void *value,
50 : : size_t size, int flags)
51 : : {
52 : 0 : struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
53 : :
54 [ # # # ]: 0 : switch (handler->flags) {
55 : : case F2FS_XATTR_INDEX_USER:
56 [ # # ]: 0 : if (!test_opt(sbi, XATTR_USER))
57 : : return -EOPNOTSUPP;
58 : : break;
59 : : case F2FS_XATTR_INDEX_TRUSTED:
60 : : case F2FS_XATTR_INDEX_SECURITY:
61 : : break;
62 : : default:
63 : : return -EINVAL;
64 : : }
65 : 0 : return f2fs_setxattr(inode, handler->flags, name,
66 : : value, size, NULL, flags);
67 : : }
68 : :
69 : 0 : static bool f2fs_xattr_user_list(struct dentry *dentry)
70 : : {
71 : 0 : struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
72 : :
73 : 0 : return test_opt(sbi, XATTR_USER);
74 : : }
75 : :
76 : 0 : static bool f2fs_xattr_trusted_list(struct dentry *dentry)
77 : : {
78 : 0 : return capable(CAP_SYS_ADMIN);
79 : : }
80 : :
81 : 0 : static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
82 : : struct dentry *unused, struct inode *inode,
83 : : const char *name, void *buffer, size_t size)
84 : : {
85 [ # # ]: 0 : if (buffer)
86 : 0 : *((char *)buffer) = F2FS_I(inode)->i_advise;
87 : 0 : return sizeof(char);
88 : : }
89 : :
90 : 0 : static int f2fs_xattr_advise_set(const struct xattr_handler *handler,
91 : : struct dentry *unused, struct inode *inode,
92 : : const char *name, const void *value,
93 : : size_t size, int flags)
94 : : {
95 : 0 : unsigned char old_advise = F2FS_I(inode)->i_advise;
96 : : unsigned char new_advise;
97 : :
98 [ # # ]: 0 : if (!inode_owner_or_capable(inode))
99 : : return -EPERM;
100 [ # # ]: 0 : if (value == NULL)
101 : : return -EINVAL;
102 : :
103 : 0 : new_advise = *(char *)value;
104 [ # # ]: 0 : if (new_advise & ~FADVISE_MODIFIABLE_BITS)
105 : : return -EINVAL;
106 : :
107 : 0 : new_advise = new_advise & FADVISE_MODIFIABLE_BITS;
108 : 0 : new_advise |= old_advise & ~FADVISE_MODIFIABLE_BITS;
109 : :
110 : 0 : F2FS_I(inode)->i_advise = new_advise;
111 : 0 : f2fs_mark_inode_dirty_sync(inode, true);
112 : 0 : return 0;
113 : : }
114 : :
115 : : #ifdef CONFIG_F2FS_FS_SECURITY
116 : : static int f2fs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
117 : : void *page)
118 : : {
119 : : const struct xattr *xattr;
120 : : int err = 0;
121 : :
122 : : for (xattr = xattr_array; xattr->name != NULL; xattr++) {
123 : : err = f2fs_setxattr(inode, F2FS_XATTR_INDEX_SECURITY,
124 : : xattr->name, xattr->value,
125 : : xattr->value_len, (struct page *)page, 0);
126 : : if (err < 0)
127 : : break;
128 : : }
129 : : return err;
130 : : }
131 : :
132 : : int f2fs_init_security(struct inode *inode, struct inode *dir,
133 : : const struct qstr *qstr, struct page *ipage)
134 : : {
135 : : return security_inode_init_security(inode, dir, qstr,
136 : : &f2fs_initxattrs, ipage);
137 : : }
138 : : #endif
139 : :
140 : : const struct xattr_handler f2fs_xattr_user_handler = {
141 : : .prefix = XATTR_USER_PREFIX,
142 : : .flags = F2FS_XATTR_INDEX_USER,
143 : : .list = f2fs_xattr_user_list,
144 : : .get = f2fs_xattr_generic_get,
145 : : .set = f2fs_xattr_generic_set,
146 : : };
147 : :
148 : : const struct xattr_handler f2fs_xattr_trusted_handler = {
149 : : .prefix = XATTR_TRUSTED_PREFIX,
150 : : .flags = F2FS_XATTR_INDEX_TRUSTED,
151 : : .list = f2fs_xattr_trusted_list,
152 : : .get = f2fs_xattr_generic_get,
153 : : .set = f2fs_xattr_generic_set,
154 : : };
155 : :
156 : : const struct xattr_handler f2fs_xattr_advise_handler = {
157 : : .name = F2FS_SYSTEM_ADVISE_NAME,
158 : : .flags = F2FS_XATTR_INDEX_ADVISE,
159 : : .get = f2fs_xattr_advise_get,
160 : : .set = f2fs_xattr_advise_set,
161 : : };
162 : :
163 : : const struct xattr_handler f2fs_xattr_security_handler = {
164 : : .prefix = XATTR_SECURITY_PREFIX,
165 : : .flags = F2FS_XATTR_INDEX_SECURITY,
166 : : .get = f2fs_xattr_generic_get,
167 : : .set = f2fs_xattr_generic_set,
168 : : };
169 : :
170 : : static const struct xattr_handler *f2fs_xattr_handler_map[] = {
171 : : [F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler,
172 : : #ifdef CONFIG_F2FS_FS_POSIX_ACL
173 : : [F2FS_XATTR_INDEX_POSIX_ACL_ACCESS] = &posix_acl_access_xattr_handler,
174 : : [F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &posix_acl_default_xattr_handler,
175 : : #endif
176 : : [F2FS_XATTR_INDEX_TRUSTED] = &f2fs_xattr_trusted_handler,
177 : : #ifdef CONFIG_F2FS_FS_SECURITY
178 : : [F2FS_XATTR_INDEX_SECURITY] = &f2fs_xattr_security_handler,
179 : : #endif
180 : : [F2FS_XATTR_INDEX_ADVISE] = &f2fs_xattr_advise_handler,
181 : : };
182 : :
183 : : const struct xattr_handler *f2fs_xattr_handlers[] = {
184 : : &f2fs_xattr_user_handler,
185 : : #ifdef CONFIG_F2FS_FS_POSIX_ACL
186 : : &posix_acl_access_xattr_handler,
187 : : &posix_acl_default_xattr_handler,
188 : : #endif
189 : : &f2fs_xattr_trusted_handler,
190 : : #ifdef CONFIG_F2FS_FS_SECURITY
191 : : &f2fs_xattr_security_handler,
192 : : #endif
193 : : &f2fs_xattr_advise_handler,
194 : : NULL,
195 : : };
196 : :
197 : : static inline const struct xattr_handler *f2fs_xattr_handler(int index)
198 : : {
199 : : const struct xattr_handler *handler = NULL;
200 : :
201 [ # # ]: 0 : if (index > 0 && index < ARRAY_SIZE(f2fs_xattr_handler_map))
202 : 0 : handler = f2fs_xattr_handler_map[index];
203 : : return handler;
204 : : }
205 : :
206 : 0 : static struct f2fs_xattr_entry *__find_xattr(void *base_addr,
207 : : void *last_base_addr, int index,
208 : : size_t len, const char *name)
209 : : {
210 : : struct f2fs_xattr_entry *entry;
211 : :
212 [ # # ]: 0 : list_for_each_xattr(entry, base_addr) {
213 [ # # # # ]: 0 : if ((void *)(entry) + sizeof(__u32) > last_base_addr ||
214 : 0 : (void *)XATTR_NEXT_ENTRY(entry) > last_base_addr)
215 : : return NULL;
216 : :
217 [ # # ]: 0 : if (entry->e_name_index != index)
218 : 0 : continue;
219 [ # # ]: 0 : if (entry->e_name_len != len)
220 : 0 : continue;
221 [ # # ]: 0 : if (!memcmp(entry->e_name, name, len))
222 : : break;
223 : : }
224 : 0 : return entry;
225 : : }
226 : :
227 : 0 : static struct f2fs_xattr_entry *__find_inline_xattr(struct inode *inode,
228 : : void *base_addr, void **last_addr, int index,
229 : : size_t len, const char *name)
230 : : {
231 : : struct f2fs_xattr_entry *entry;
232 : 0 : unsigned int inline_size = inline_xattr_size(inode);
233 : 0 : void *max_addr = base_addr + inline_size;
234 : :
235 [ # # ]: 0 : list_for_each_xattr(entry, base_addr) {
236 [ # # # # ]: 0 : if ((void *)entry + sizeof(__u32) > max_addr ||
237 : 0 : (void *)XATTR_NEXT_ENTRY(entry) > max_addr) {
238 : 0 : *last_addr = entry;
239 : 0 : return NULL;
240 : : }
241 [ # # ]: 0 : if (entry->e_name_index != index)
242 : 0 : continue;
243 [ # # ]: 0 : if (entry->e_name_len != len)
244 : 0 : continue;
245 [ # # ]: 0 : if (!memcmp(entry->e_name, name, len))
246 : : break;
247 : : }
248 : :
249 : : /* inline xattr header or entry across max inline xattr size */
250 [ # # # # ]: 0 : if (IS_XATTR_LAST_ENTRY(entry) &&
251 : 0 : (void *)entry + sizeof(__u32) > max_addr) {
252 : 0 : *last_addr = entry;
253 : 0 : return NULL;
254 : : }
255 : 0 : return entry;
256 : : }
257 : :
258 : 0 : static int read_inline_xattr(struct inode *inode, struct page *ipage,
259 : : void *txattr_addr)
260 : : {
261 : : struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
262 : 0 : unsigned int inline_size = inline_xattr_size(inode);
263 : : struct page *page = NULL;
264 : : void *inline_addr;
265 : :
266 [ # # ]: 0 : if (ipage) {
267 : : inline_addr = inline_xattr_addr(inode, ipage);
268 : : } else {
269 : 0 : page = f2fs_get_node_page(sbi, inode->i_ino);
270 [ # # ]: 0 : if (IS_ERR(page))
271 : 0 : return PTR_ERR(page);
272 : :
273 : : inline_addr = inline_xattr_addr(inode, page);
274 : : }
275 : 0 : memcpy(txattr_addr, inline_addr, inline_size);
276 : 0 : f2fs_put_page(page, 1);
277 : :
278 : 0 : return 0;
279 : : }
280 : :
281 : 0 : static int read_xattr_block(struct inode *inode, void *txattr_addr)
282 : : {
283 : : struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
284 : 0 : nid_t xnid = F2FS_I(inode)->i_xattr_nid;
285 : 0 : unsigned int inline_size = inline_xattr_size(inode);
286 : : struct page *xpage;
287 : : void *xattr_addr;
288 : :
289 : : /* The inode already has an extended attribute block. */
290 : 0 : xpage = f2fs_get_node_page(sbi, xnid);
291 [ # # ]: 0 : if (IS_ERR(xpage))
292 : 0 : return PTR_ERR(xpage);
293 : :
294 : : xattr_addr = page_address(xpage);
295 : 0 : memcpy(txattr_addr + inline_size, xattr_addr, VALID_XATTR_BLOCK_SIZE);
296 : 0 : f2fs_put_page(xpage, 1);
297 : :
298 : 0 : return 0;
299 : : }
300 : :
301 : 0 : static int lookup_all_xattrs(struct inode *inode, struct page *ipage,
302 : : unsigned int index, unsigned int len,
303 : : const char *name, struct f2fs_xattr_entry **xe,
304 : : void **base_addr, int *base_size)
305 : : {
306 : : void *cur_addr, *txattr_addr, *last_txattr_addr;
307 : 0 : void *last_addr = NULL;
308 : 0 : nid_t xnid = F2FS_I(inode)->i_xattr_nid;
309 : 0 : unsigned int inline_size = inline_xattr_size(inode);
310 : : int err = 0;
311 : :
312 [ # # ]: 0 : if (!xnid && !inline_size)
313 : : return -ENODATA;
314 : :
315 [ # # ]: 0 : *base_size = XATTR_SIZE(xnid, inode) + XATTR_PADDING_SIZE;
316 : : txattr_addr = f2fs_kzalloc(F2FS_I_SB(inode), *base_size, GFP_NOFS);
317 [ # # ]: 0 : if (!txattr_addr)
318 : : return -ENOMEM;
319 : :
320 [ # # ]: 0 : last_txattr_addr = (void *)txattr_addr + XATTR_SIZE(xnid, inode);
321 : :
322 : : /* read from inline xattr */
323 [ # # ]: 0 : if (inline_size) {
324 : 0 : err = read_inline_xattr(inode, ipage, txattr_addr);
325 [ # # ]: 0 : if (err)
326 : : goto out;
327 : :
328 : 0 : *xe = __find_inline_xattr(inode, txattr_addr, &last_addr,
329 : : index, len, name);
330 [ # # ]: 0 : if (*xe) {
331 : 0 : *base_size = inline_size;
332 : 0 : goto check;
333 : : }
334 : : }
335 : :
336 : : /* read from xattr node block */
337 [ # # ]: 0 : if (xnid) {
338 : 0 : err = read_xattr_block(inode, txattr_addr);
339 [ # # ]: 0 : if (err)
340 : : goto out;
341 : : }
342 : :
343 [ # # ]: 0 : if (last_addr)
344 : 0 : cur_addr = XATTR_HDR(last_addr) - 1;
345 : : else
346 : : cur_addr = txattr_addr;
347 : :
348 : 0 : *xe = __find_xattr(cur_addr, last_txattr_addr, index, len, name);
349 [ # # ]: 0 : if (!*xe) {
350 : 0 : f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr",
351 : : inode->i_ino);
352 : : set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK);
353 : : err = -EFSCORRUPTED;
354 : 0 : goto out;
355 : : }
356 : : check:
357 [ # # ]: 0 : if (IS_XATTR_LAST_ENTRY(*xe)) {
358 : : err = -ENODATA;
359 : : goto out;
360 : : }
361 : :
362 : 0 : *base_addr = txattr_addr;
363 : 0 : return 0;
364 : : out:
365 : 0 : kvfree(txattr_addr);
366 : 0 : return err;
367 : : }
368 : :
369 : 0 : static int read_all_xattrs(struct inode *inode, struct page *ipage,
370 : : void **base_addr)
371 : : {
372 : : struct f2fs_xattr_header *header;
373 : 0 : nid_t xnid = F2FS_I(inode)->i_xattr_nid;
374 : : unsigned int size = VALID_XATTR_BLOCK_SIZE;
375 : 0 : unsigned int inline_size = inline_xattr_size(inode);
376 : : void *txattr_addr;
377 : : int err;
378 : :
379 : 0 : txattr_addr = f2fs_kzalloc(F2FS_I_SB(inode),
380 : : inline_size + size + XATTR_PADDING_SIZE, GFP_NOFS);
381 [ # # ]: 0 : if (!txattr_addr)
382 : : return -ENOMEM;
383 : :
384 : : /* read from inline xattr */
385 [ # # ]: 0 : if (inline_size) {
386 : 0 : err = read_inline_xattr(inode, ipage, txattr_addr);
387 [ # # ]: 0 : if (err)
388 : : goto fail;
389 : : }
390 : :
391 : : /* read from xattr node block */
392 [ # # ]: 0 : if (xnid) {
393 : 0 : err = read_xattr_block(inode, txattr_addr);
394 [ # # ]: 0 : if (err)
395 : : goto fail;
396 : : }
397 : :
398 : : header = XATTR_HDR(txattr_addr);
399 : :
400 : : /* never been allocated xattrs */
401 [ # # ]: 0 : if (le32_to_cpu(header->h_magic) != F2FS_XATTR_MAGIC) {
402 : 0 : header->h_magic = cpu_to_le32(F2FS_XATTR_MAGIC);
403 : 0 : header->h_refcount = cpu_to_le32(1);
404 : : }
405 : 0 : *base_addr = txattr_addr;
406 : 0 : return 0;
407 : : fail:
408 : 0 : kvfree(txattr_addr);
409 : 0 : return err;
410 : : }
411 : :
412 : 0 : static inline int write_all_xattrs(struct inode *inode, __u32 hsize,
413 : : void *txattr_addr, struct page *ipage)
414 : : {
415 : : struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
416 : 0 : size_t inline_size = inline_xattr_size(inode);
417 : : struct page *in_page = NULL;
418 : : void *xattr_addr;
419 : : void *inline_addr = NULL;
420 : : struct page *xpage;
421 : 0 : nid_t new_nid = 0;
422 : : int err = 0;
423 : :
424 [ # # # # ]: 0 : if (hsize > inline_size && !F2FS_I(inode)->i_xattr_nid)
425 [ # # ]: 0 : if (!f2fs_alloc_nid(sbi, &new_nid))
426 : : return -ENOSPC;
427 : :
428 : : /* write to inline xattr */
429 [ # # ]: 0 : if (inline_size) {
430 [ # # ]: 0 : if (ipage) {
431 : : inline_addr = inline_xattr_addr(inode, ipage);
432 : : } else {
433 : 0 : in_page = f2fs_get_node_page(sbi, inode->i_ino);
434 [ # # ]: 0 : if (IS_ERR(in_page)) {
435 : 0 : f2fs_alloc_nid_failed(sbi, new_nid);
436 : 0 : return PTR_ERR(in_page);
437 : : }
438 : : inline_addr = inline_xattr_addr(inode, in_page);
439 : : }
440 : :
441 [ # # ]: 0 : f2fs_wait_on_page_writeback(ipage ? ipage : in_page,
442 : : NODE, true, true);
443 : : /* no need to use xattr node block */
444 [ # # ]: 0 : if (hsize <= inline_size) {
445 : 0 : err = f2fs_truncate_xattr_node(inode);
446 : 0 : f2fs_alloc_nid_failed(sbi, new_nid);
447 [ # # ]: 0 : if (err) {
448 : 0 : f2fs_put_page(in_page, 1);
449 : 0 : return err;
450 : : }
451 : 0 : memcpy(inline_addr, txattr_addr, inline_size);
452 [ # # ]: 0 : set_page_dirty(ipage ? ipage : in_page);
453 : 0 : goto in_page_out;
454 : : }
455 : : }
456 : :
457 : : /* write to xattr node block */
458 [ # # ]: 0 : if (F2FS_I(inode)->i_xattr_nid) {
459 : 0 : xpage = f2fs_get_node_page(sbi, F2FS_I(inode)->i_xattr_nid);
460 [ # # ]: 0 : if (IS_ERR(xpage)) {
461 : : err = PTR_ERR(xpage);
462 : 0 : f2fs_alloc_nid_failed(sbi, new_nid);
463 : 0 : goto in_page_out;
464 : : }
465 [ # # ]: 0 : f2fs_bug_on(sbi, new_nid);
466 : 0 : f2fs_wait_on_page_writeback(xpage, NODE, true, true);
467 : : } else {
468 : : struct dnode_of_data dn;
469 : 0 : set_new_dnode(&dn, inode, NULL, NULL, new_nid);
470 : 0 : xpage = f2fs_new_node_page(&dn, XATTR_NODE_OFFSET);
471 [ # # ]: 0 : if (IS_ERR(xpage)) {
472 : : err = PTR_ERR(xpage);
473 : 0 : f2fs_alloc_nid_failed(sbi, new_nid);
474 : 0 : goto in_page_out;
475 : : }
476 : 0 : f2fs_alloc_nid_done(sbi, new_nid);
477 : : }
478 : : xattr_addr = page_address(xpage);
479 : :
480 [ # # ]: 0 : if (inline_size)
481 : 0 : memcpy(inline_addr, txattr_addr, inline_size);
482 : 0 : memcpy(xattr_addr, txattr_addr + inline_size, VALID_XATTR_BLOCK_SIZE);
483 : :
484 [ # # ]: 0 : if (inline_size)
485 [ # # ]: 0 : set_page_dirty(ipage ? ipage : in_page);
486 : 0 : set_page_dirty(xpage);
487 : :
488 : 0 : f2fs_put_page(xpage, 1);
489 : : in_page_out:
490 : 0 : f2fs_put_page(in_page, 1);
491 : 0 : return err;
492 : : }
493 : :
494 : 0 : int f2fs_getxattr(struct inode *inode, int index, const char *name,
495 : : void *buffer, size_t buffer_size, struct page *ipage)
496 : : {
497 : 0 : struct f2fs_xattr_entry *entry = NULL;
498 : : int error = 0;
499 : : unsigned int size, len;
500 : 0 : void *base_addr = NULL;
501 : : int base_size;
502 : :
503 [ # # ]: 0 : if (name == NULL)
504 : : return -EINVAL;
505 : :
506 : 0 : len = strlen(name);
507 [ # # ]: 0 : if (len > F2FS_NAME_LEN)
508 : : return -ERANGE;
509 : :
510 : 0 : down_read(&F2FS_I(inode)->i_xattr_sem);
511 : 0 : error = lookup_all_xattrs(inode, ipage, index, len, name,
512 : : &entry, &base_addr, &base_size);
513 : 0 : up_read(&F2FS_I(inode)->i_xattr_sem);
514 [ # # ]: 0 : if (error)
515 : : return error;
516 : :
517 : 0 : size = le16_to_cpu(entry->e_value_size);
518 : :
519 [ # # ]: 0 : if (buffer && size > buffer_size) {
520 : : error = -ERANGE;
521 : : goto out;
522 : : }
523 : :
524 [ # # ]: 0 : if (buffer) {
525 : 0 : char *pval = entry->e_name + entry->e_name_len;
526 : :
527 [ # # ]: 0 : if (base_size - (pval - (char *)base_addr) < size) {
528 : : error = -ERANGE;
529 : : goto out;
530 : : }
531 : 0 : memcpy(buffer, pval, size);
532 : : }
533 : 0 : error = size;
534 : : out:
535 : 0 : kvfree(base_addr);
536 : 0 : return error;
537 : : }
538 : :
539 : 0 : ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
540 : : {
541 : : struct inode *inode = d_inode(dentry);
542 : 0 : nid_t xnid = F2FS_I(inode)->i_xattr_nid;
543 : : struct f2fs_xattr_entry *entry;
544 : : void *base_addr, *last_base_addr;
545 : : int error = 0;
546 : : size_t rest = buffer_size;
547 : :
548 : 0 : down_read(&F2FS_I(inode)->i_xattr_sem);
549 : 0 : error = read_all_xattrs(inode, NULL, &base_addr);
550 : 0 : up_read(&F2FS_I(inode)->i_xattr_sem);
551 [ # # ]: 0 : if (error)
552 : : return error;
553 : :
554 [ # # ]: 0 : last_base_addr = (void *)base_addr + XATTR_SIZE(xnid, inode);
555 : :
556 [ # # ]: 0 : list_for_each_xattr(entry, base_addr) {
557 : : const struct xattr_handler *handler =
558 : 0 : f2fs_xattr_handler(entry->e_name_index);
559 : : const char *prefix;
560 : : size_t prefix_len;
561 : : size_t size;
562 : :
563 [ # # # # ]: 0 : if ((void *)(entry) + sizeof(__u32) > last_base_addr ||
564 : 0 : (void *)XATTR_NEXT_ENTRY(entry) > last_base_addr) {
565 : 0 : f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr",
566 : : inode->i_ino);
567 : : set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK);
568 : : error = -EFSCORRUPTED;
569 : 0 : goto cleanup;
570 : : }
571 : :
572 [ # # # # : 0 : if (!handler || (handler->list && !handler->list(dentry)))
# # ]
573 : 0 : continue;
574 : :
575 : : prefix = xattr_prefix(handler);
576 : 0 : prefix_len = strlen(prefix);
577 : 0 : size = prefix_len + entry->e_name_len + 1;
578 [ # # ]: 0 : if (buffer) {
579 [ # # ]: 0 : if (size > rest) {
580 : : error = -ERANGE;
581 : : goto cleanup;
582 : : }
583 : 0 : memcpy(buffer, prefix, prefix_len);
584 : 0 : buffer += prefix_len;
585 : 0 : memcpy(buffer, entry->e_name, entry->e_name_len);
586 : 0 : buffer += entry->e_name_len;
587 : 0 : *buffer++ = 0;
588 : : }
589 : 0 : rest -= size;
590 : : }
591 : 0 : error = buffer_size - rest;
592 : : cleanup:
593 : 0 : kvfree(base_addr);
594 : 0 : return error;
595 : : }
596 : :
597 : : static bool f2fs_xattr_value_same(struct f2fs_xattr_entry *entry,
598 : : const void *value, size_t size)
599 : : {
600 : 0 : void *pval = entry->e_name + entry->e_name_len;
601 : :
602 [ # # # # ]: 0 : return (le16_to_cpu(entry->e_value_size) == size) &&
603 : 0 : !memcmp(pval, value, size);
604 : : }
605 : :
606 : 0 : static int __f2fs_setxattr(struct inode *inode, int index,
607 : : const char *name, const void *value, size_t size,
608 : : struct page *ipage, int flags)
609 : : {
610 : : struct f2fs_xattr_entry *here, *last;
611 : : void *base_addr, *last_base_addr;
612 : 0 : nid_t xnid = F2FS_I(inode)->i_xattr_nid;
613 : : int found, newsize;
614 : : size_t len;
615 : : __u32 new_hsize;
616 : : int error = 0;
617 : :
618 [ # # ]: 0 : if (name == NULL)
619 : : return -EINVAL;
620 : :
621 [ # # ]: 0 : if (value == NULL)
622 : : size = 0;
623 : :
624 : 0 : len = strlen(name);
625 : :
626 [ # # ]: 0 : if (len > F2FS_NAME_LEN)
627 : : return -ERANGE;
628 : :
629 [ # # ]: 0 : if (size > MAX_VALUE_LEN(inode))
630 : : return -E2BIG;
631 : :
632 : 0 : error = read_all_xattrs(inode, ipage, &base_addr);
633 [ # # ]: 0 : if (error)
634 : : return error;
635 : :
636 [ # # ]: 0 : last_base_addr = (void *)base_addr + XATTR_SIZE(xnid, inode);
637 : :
638 : : /* find entry with wanted name. */
639 : 0 : here = __find_xattr(base_addr, last_base_addr, index, len, name);
640 [ # # ]: 0 : if (!here) {
641 : 0 : f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr",
642 : : inode->i_ino);
643 : : set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK);
644 : : error = -EFSCORRUPTED;
645 : 0 : goto exit;
646 : : }
647 : :
648 : 0 : found = IS_XATTR_LAST_ENTRY(here) ? 0 : 1;
649 : :
650 [ # # ]: 0 : if (found) {
651 [ # # ]: 0 : if ((flags & XATTR_CREATE)) {
652 : : error = -EEXIST;
653 : : goto exit;
654 : : }
655 : :
656 [ # # # # ]: 0 : if (value && f2fs_xattr_value_same(here, value, size))
657 : : goto exit;
658 [ # # ]: 0 : } else if ((flags & XATTR_REPLACE)) {
659 : : error = -ENODATA;
660 : : goto exit;
661 : : }
662 : :
663 : : last = here;
664 [ # # ]: 0 : while (!IS_XATTR_LAST_ENTRY(last))
665 : 0 : last = XATTR_NEXT_ENTRY(last);
666 : :
667 : 0 : newsize = XATTR_ALIGN(sizeof(struct f2fs_xattr_entry) + len + size);
668 : :
669 : : /* 1. Check space */
670 [ # # ]: 0 : if (value) {
671 : : int free;
672 : : /*
673 : : * If value is NULL, it is remove operation.
674 : : * In case of update operation, we calculate free.
675 : : */
676 : 0 : free = MIN_OFFSET(inode) - ((char *)last - (char *)base_addr);
677 [ # # ]: 0 : if (found)
678 : 0 : free = free + ENTRY_SIZE(here);
679 : :
680 [ # # ]: 0 : if (unlikely(free < newsize)) {
681 : : error = -E2BIG;
682 : : goto exit;
683 : : }
684 : : }
685 : :
686 : : /* 2. Remove old entry */
687 [ # # ]: 0 : if (found) {
688 : : /*
689 : : * If entry is found, remove old entry.
690 : : * If not found, remove operation is not needed.
691 : : */
692 : 0 : struct f2fs_xattr_entry *next = XATTR_NEXT_ENTRY(here);
693 : 0 : int oldsize = ENTRY_SIZE(here);
694 : :
695 : 0 : memmove(here, next, (char *)last - (char *)next);
696 : 0 : last = (struct f2fs_xattr_entry *)((char *)last - oldsize);
697 : 0 : memset(last, 0, oldsize);
698 : : }
699 : :
700 : 0 : new_hsize = (char *)last - (char *)base_addr;
701 : :
702 : : /* 3. Write new entry */
703 [ # # ]: 0 : if (value) {
704 : : char *pval;
705 : : /*
706 : : * Before we come here, old entry is removed.
707 : : * We just write new entry.
708 : : */
709 : 0 : last->e_name_index = index;
710 : 0 : last->e_name_len = len;
711 : 0 : memcpy(last->e_name, name, len);
712 : 0 : pval = last->e_name + len;
713 : 0 : memcpy(pval, value, size);
714 : 0 : last->e_value_size = cpu_to_le16(size);
715 : 0 : new_hsize += newsize;
716 : : }
717 : :
718 : 0 : error = write_all_xattrs(inode, new_hsize, base_addr, ipage);
719 [ # # ]: 0 : if (error)
720 : : goto exit;
721 : :
722 [ # # ]: 0 : if (is_inode_flag_set(inode, FI_ACL_MODE)) {
723 : 0 : inode->i_mode = F2FS_I(inode)->i_acl_mode;
724 : 0 : inode->i_ctime = current_time(inode);
725 : 0 : clear_inode_flag(inode, FI_ACL_MODE);
726 : : }
727 [ # # # # ]: 0 : if (index == F2FS_XATTR_INDEX_ENCRYPTION &&
728 : 0 : !strcmp(name, F2FS_XATTR_NAME_ENCRYPTION_CONTEXT))
729 : 0 : f2fs_set_encrypted_inode(inode);
730 : 0 : f2fs_mark_inode_dirty_sync(inode, true);
731 [ # # # # ]: 0 : if (!error && S_ISDIR(inode->i_mode))
732 : : set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_CP);
733 : : exit:
734 : 0 : kvfree(base_addr);
735 : 0 : return error;
736 : : }
737 : :
738 : 0 : int f2fs_setxattr(struct inode *inode, int index, const char *name,
739 : : const void *value, size_t size,
740 : : struct page *ipage, int flags)
741 : : {
742 : : struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
743 : : int err;
744 : :
745 [ # # ]: 0 : if (unlikely(f2fs_cp_error(sbi)))
746 : : return -EIO;
747 [ # # ]: 0 : if (!f2fs_is_checkpoint_ready(sbi))
748 : : return -ENOSPC;
749 : :
750 : 0 : err = dquot_initialize(inode);
751 [ # # ]: 0 : if (err)
752 : : return err;
753 : :
754 : : /* this case is only from f2fs_init_inode_metadata */
755 [ # # ]: 0 : if (ipage)
756 : 0 : return __f2fs_setxattr(inode, index, name, value,
757 : : size, ipage, flags);
758 : 0 : f2fs_balance_fs(sbi, true);
759 : :
760 : : f2fs_lock_op(sbi);
761 : : /* protect xattr_ver */
762 : 0 : down_write(&F2FS_I(inode)->i_sem);
763 : 0 : down_write(&F2FS_I(inode)->i_xattr_sem);
764 : 0 : err = __f2fs_setxattr(inode, index, name, value, size, ipage, flags);
765 : 0 : up_write(&F2FS_I(inode)->i_xattr_sem);
766 : 0 : up_write(&F2FS_I(inode)->i_sem);
767 : : f2fs_unlock_op(sbi);
768 : :
769 : : f2fs_update_time(sbi, REQ_TIME);
770 : 0 : return err;
771 : : }
|