]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - fs/xattr.c
fs: block_page_mkwrite should wait for writeback to finish
[mirror_ubuntu-jammy-kernel.git] / fs / xattr.c
CommitLineData
1da177e4
LT
1/*
2 File: fs/xattr.c
3
4 Extended attribute handling.
5
6 Copyright (C) 2001 by Andreas Gruenbacher <a.gruenbacher@computer.org>
7 Copyright (C) 2001 SGI - Silicon Graphics, Inc <linux-xfs@oss.sgi.com>
8 Copyright (c) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
9 */
10#include <linux/fs.h>
11#include <linux/slab.h>
1da177e4
LT
12#include <linux/file.h>
13#include <linux/xattr.h>
18f335af 14#include <linux/mount.h>
1da177e4
LT
15#include <linux/namei.h>
16#include <linux/security.h>
17#include <linux/syscalls.h>
18#include <linux/module.h>
0eeca283 19#include <linux/fsnotify.h>
73241ccc 20#include <linux/audit.h>
1da177e4
LT
21#include <asm/uaccess.h>
22
5be196e5 23
e0ad7b07 24/*
25 * Check permissions for extended attribute access. This is a bit complicated
26 * because different namespaces have very different rules.
27 */
28static int
29xattr_permission(struct inode *inode, const char *name, int mask)
30{
31 /*
32 * We can never set or remove an extended attribute on a read-only
33 * filesystem or on an immutable / append-only inode.
34 */
35 if (mask & MAY_WRITE) {
e0ad7b07 36 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
37 return -EPERM;
38 }
39
40 /*
41 * No restriction for security.* and system.* from the VFS. Decision
42 * on these is left to the underlying filesystem / security module.
43 */
44 if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) ||
45 !strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
46 return 0;
47
48 /*
55b23bde 49 * The trusted.* namespace can only be accessed by privileged users.
e0ad7b07 50 */
55b23bde
AG
51 if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) {
52 if (!capable(CAP_SYS_ADMIN))
53 return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
54 return 0;
55 }
e0ad7b07 56
55b23bde
AG
57 /*
58 * In the user.* namespace, only regular files and directories can have
f1f2d871 59 * extended attributes. For sticky directories, only the owner and
55b23bde 60 * privileged users can write attributes.
f1f2d871 61 */
e0ad7b07 62 if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
f1f2d871 63 if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
55b23bde 64 return (mask & MAY_WRITE) ? -EPERM : -ENODATA;
f1f2d871 65 if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) &&
2e149670 66 (mask & MAY_WRITE) && !inode_owner_or_capable(inode))
e0ad7b07 67 return -EPERM;
68 }
69
f419a2e3 70 return inode_permission(inode, mask);
e0ad7b07 71}
72
b1ab7e4b
DQ
73/**
74 * __vfs_setxattr_noperm - perform setxattr operation without performing
75 * permission checks.
76 *
77 * @dentry - object to perform setxattr on
78 * @name - xattr name to set
79 * @value - value to set @name to
80 * @size - size of @value
81 * @flags - flags to pass into filesystem operations
82 *
83 * returns the result of the internal setxattr or setsecurity operations.
84 *
85 * This function requires the caller to lock the inode's i_mutex before it
86 * is executed. It also assumes that the caller will make the appropriate
87 * permission checks.
88 */
89int __vfs_setxattr_noperm(struct dentry *dentry, const char *name,
90 const void *value, size_t size, int flags)
5be196e5
CH
91{
92 struct inode *inode = dentry->d_inode;
b1ab7e4b 93 int error = -EOPNOTSUPP;
e0ad7b07 94
5be196e5
CH
95 if (inode->i_op->setxattr) {
96 error = inode->i_op->setxattr(dentry, name, value, size, flags);
97 if (!error) {
98 fsnotify_xattr(dentry);
99 security_inode_post_setxattr(dentry, name, value,
100 size, flags);
101 }
102 } else if (!strncmp(name, XATTR_SECURITY_PREFIX,
e0ad7b07 103 XATTR_SECURITY_PREFIX_LEN)) {
104 const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
5be196e5
CH
105 error = security_inode_setsecurity(inode, suffix, value,
106 size, flags);
107 if (!error)
108 fsnotify_xattr(dentry);
109 }
b1ab7e4b
DQ
110
111 return error;
112}
113
114
115int
116vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
117 size_t size, int flags)
118{
119 struct inode *inode = dentry->d_inode;
120 int error;
121
122 error = xattr_permission(inode, name, MAY_WRITE);
123 if (error)
124 return error;
125
126 mutex_lock(&inode->i_mutex);
127 error = security_inode_setxattr(dentry, name, value, size, flags);
128 if (error)
129 goto out;
130
131 error = __vfs_setxattr_noperm(dentry, name, value, size, flags);
132
5be196e5
CH
133out:
134 mutex_unlock(&inode->i_mutex);
135 return error;
136}
137EXPORT_SYMBOL_GPL(vfs_setxattr);
138
42492594
DQ
139ssize_t
140xattr_getsecurity(struct inode *inode, const char *name, void *value,
141 size_t size)
142{
143 void *buffer = NULL;
144 ssize_t len;
145
146 if (!value || !size) {
147 len = security_inode_getsecurity(inode, name, &buffer, false);
148 goto out_noalloc;
149 }
150
151 len = security_inode_getsecurity(inode, name, &buffer, true);
152 if (len < 0)
153 return len;
154 if (size < len) {
155 len = -ERANGE;
156 goto out;
157 }
158 memcpy(value, buffer, len);
159out:
160 security_release_secctx(buffer, len);
161out_noalloc:
162 return len;
163}
164EXPORT_SYMBOL_GPL(xattr_getsecurity);
165
5be196e5 166ssize_t
8f0cfa52 167vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
5be196e5
CH
168{
169 struct inode *inode = dentry->d_inode;
170 int error;
171
e0ad7b07 172 error = xattr_permission(inode, name, MAY_READ);
173 if (error)
174 return error;
175
5be196e5
CH
176 error = security_inode_getxattr(dentry, name);
177 if (error)
178 return error;
179
5be196e5 180 if (!strncmp(name, XATTR_SECURITY_PREFIX,
e0ad7b07 181 XATTR_SECURITY_PREFIX_LEN)) {
182 const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
42492594 183 int ret = xattr_getsecurity(inode, suffix, value, size);
5be196e5
CH
184 /*
185 * Only overwrite the return value if a security module
186 * is actually active.
187 */
4bea5805
DQ
188 if (ret == -EOPNOTSUPP)
189 goto nolsm;
190 return ret;
5be196e5 191 }
4bea5805
DQ
192nolsm:
193 if (inode->i_op->getxattr)
194 error = inode->i_op->getxattr(dentry, name, value, size);
195 else
196 error = -EOPNOTSUPP;
5be196e5
CH
197
198 return error;
199}
200EXPORT_SYMBOL_GPL(vfs_getxattr);
201
659564c8
BN
202ssize_t
203vfs_listxattr(struct dentry *d, char *list, size_t size)
204{
205 ssize_t error;
206
207 error = security_inode_listxattr(d);
208 if (error)
209 return error;
210 error = -EOPNOTSUPP;
acfa4380 211 if (d->d_inode->i_op->listxattr) {
659564c8
BN
212 error = d->d_inode->i_op->listxattr(d, list, size);
213 } else {
214 error = security_inode_listsecurity(d->d_inode, list, size);
215 if (size && error > size)
216 error = -ERANGE;
217 }
218 return error;
219}
220EXPORT_SYMBOL_GPL(vfs_listxattr);
221
5be196e5 222int
8f0cfa52 223vfs_removexattr(struct dentry *dentry, const char *name)
5be196e5
CH
224{
225 struct inode *inode = dentry->d_inode;
226 int error;
227
228 if (!inode->i_op->removexattr)
229 return -EOPNOTSUPP;
230
e0ad7b07 231 error = xattr_permission(inode, name, MAY_WRITE);
232 if (error)
233 return error;
234
5be196e5
CH
235 error = security_inode_removexattr(dentry, name);
236 if (error)
237 return error;
238
239 mutex_lock(&inode->i_mutex);
240 error = inode->i_op->removexattr(dentry, name);
241 mutex_unlock(&inode->i_mutex);
242
243 if (!error)
244 fsnotify_xattr(dentry);
245 return error;
246}
247EXPORT_SYMBOL_GPL(vfs_removexattr);
248
249
1da177e4
LT
250/*
251 * Extended attribute SET operations
252 */
253static long
8f0cfa52 254setxattr(struct dentry *d, const char __user *name, const void __user *value,
1da177e4
LT
255 size_t size, int flags)
256{
257 int error;
258 void *kvalue = NULL;
259 char kname[XATTR_NAME_MAX + 1];
260
261 if (flags & ~(XATTR_CREATE|XATTR_REPLACE))
262 return -EINVAL;
263
264 error = strncpy_from_user(kname, name, sizeof(kname));
265 if (error == 0 || error == sizeof(kname))
266 error = -ERANGE;
267 if (error < 0)
268 return error;
269
270 if (size) {
271 if (size > XATTR_SIZE_MAX)
272 return -E2BIG;
3939fcde
LZ
273 kvalue = memdup_user(value, size);
274 if (IS_ERR(kvalue))
275 return PTR_ERR(kvalue);
1da177e4
LT
276 }
277
5be196e5 278 error = vfs_setxattr(d, kname, kvalue, size, flags);
f99d49ad 279 kfree(kvalue);
1da177e4
LT
280 return error;
281}
282
64fd1de3
HC
283SYSCALL_DEFINE5(setxattr, const char __user *, pathname,
284 const char __user *, name, const void __user *, value,
285 size_t, size, int, flags)
1da177e4 286{
2d8f3038 287 struct path path;
1da177e4
LT
288 int error;
289
2d8f3038 290 error = user_path(pathname, &path);
1da177e4
LT
291 if (error)
292 return error;
2d8f3038 293 error = mnt_want_write(path.mnt);
18f335af 294 if (!error) {
2d8f3038
AV
295 error = setxattr(path.dentry, name, value, size, flags);
296 mnt_drop_write(path.mnt);
18f335af 297 }
2d8f3038 298 path_put(&path);
1da177e4
LT
299 return error;
300}
301
64fd1de3
HC
302SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname,
303 const char __user *, name, const void __user *, value,
304 size_t, size, int, flags)
1da177e4 305{
2d8f3038 306 struct path path;
1da177e4
LT
307 int error;
308
2d8f3038 309 error = user_lpath(pathname, &path);
1da177e4
LT
310 if (error)
311 return error;
2d8f3038 312 error = mnt_want_write(path.mnt);
18f335af 313 if (!error) {
2d8f3038
AV
314 error = setxattr(path.dentry, name, value, size, flags);
315 mnt_drop_write(path.mnt);
18f335af 316 }
2d8f3038 317 path_put(&path);
1da177e4
LT
318 return error;
319}
320
64fd1de3
HC
321SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
322 const void __user *,value, size_t, size, int, flags)
1da177e4
LT
323{
324 struct file *f;
73241ccc 325 struct dentry *dentry;
1da177e4
LT
326 int error = -EBADF;
327
328 f = fget(fd);
329 if (!f)
330 return error;
0f7fc9e4 331 dentry = f->f_path.dentry;
5a190ae6 332 audit_inode(NULL, dentry);
96029c4e 333 error = mnt_want_write_file(f);
18f335af
DH
334 if (!error) {
335 error = setxattr(dentry, name, value, size, flags);
336 mnt_drop_write(f->f_path.mnt);
337 }
1da177e4
LT
338 fput(f);
339 return error;
340}
341
342/*
343 * Extended attribute GET operations
344 */
345static ssize_t
8f0cfa52
DH
346getxattr(struct dentry *d, const char __user *name, void __user *value,
347 size_t size)
1da177e4
LT
348{
349 ssize_t error;
350 void *kvalue = NULL;
351 char kname[XATTR_NAME_MAX + 1];
352
353 error = strncpy_from_user(kname, name, sizeof(kname));
354 if (error == 0 || error == sizeof(kname))
355 error = -ERANGE;
356 if (error < 0)
357 return error;
358
359 if (size) {
360 if (size > XATTR_SIZE_MAX)
361 size = XATTR_SIZE_MAX;
d381d8a9 362 kvalue = kzalloc(size, GFP_KERNEL);
1da177e4
LT
363 if (!kvalue)
364 return -ENOMEM;
365 }
366
5be196e5 367 error = vfs_getxattr(d, kname, kvalue, size);
f549d6c1
SS
368 if (error > 0) {
369 if (size && copy_to_user(value, kvalue, error))
370 error = -EFAULT;
371 } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) {
372 /* The file system tried to returned a value bigger
373 than XATTR_SIZE_MAX bytes. Not possible. */
374 error = -E2BIG;
1da177e4 375 }
f99d49ad 376 kfree(kvalue);
1da177e4
LT
377 return error;
378}
379
64fd1de3
HC
380SYSCALL_DEFINE4(getxattr, const char __user *, pathname,
381 const char __user *, name, void __user *, value, size_t, size)
1da177e4 382{
2d8f3038 383 struct path path;
1da177e4
LT
384 ssize_t error;
385
2d8f3038 386 error = user_path(pathname, &path);
1da177e4
LT
387 if (error)
388 return error;
2d8f3038
AV
389 error = getxattr(path.dentry, name, value, size);
390 path_put(&path);
1da177e4
LT
391 return error;
392}
393
64fd1de3
HC
394SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname,
395 const char __user *, name, void __user *, value, size_t, size)
1da177e4 396{
2d8f3038 397 struct path path;
1da177e4
LT
398 ssize_t error;
399
2d8f3038 400 error = user_lpath(pathname, &path);
1da177e4
LT
401 if (error)
402 return error;
2d8f3038
AV
403 error = getxattr(path.dentry, name, value, size);
404 path_put(&path);
1da177e4
LT
405 return error;
406}
407
64fd1de3
HC
408SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name,
409 void __user *, value, size_t, size)
1da177e4
LT
410{
411 struct file *f;
412 ssize_t error = -EBADF;
413
414 f = fget(fd);
415 if (!f)
416 return error;
5a190ae6 417 audit_inode(NULL, f->f_path.dentry);
0f7fc9e4 418 error = getxattr(f->f_path.dentry, name, value, size);
1da177e4
LT
419 fput(f);
420 return error;
421}
422
423/*
424 * Extended attribute LIST operations
425 */
426static ssize_t
427listxattr(struct dentry *d, char __user *list, size_t size)
428{
429 ssize_t error;
430 char *klist = NULL;
431
432 if (size) {
433 if (size > XATTR_LIST_MAX)
434 size = XATTR_LIST_MAX;
435 klist = kmalloc(size, GFP_KERNEL);
436 if (!klist)
437 return -ENOMEM;
438 }
439
659564c8 440 error = vfs_listxattr(d, klist, size);
f549d6c1
SS
441 if (error > 0) {
442 if (size && copy_to_user(list, klist, error))
443 error = -EFAULT;
444 } else if (error == -ERANGE && size >= XATTR_LIST_MAX) {
445 /* The file system tried to returned a list bigger
446 than XATTR_LIST_MAX bytes. Not possible. */
447 error = -E2BIG;
1da177e4 448 }
f99d49ad 449 kfree(klist);
1da177e4
LT
450 return error;
451}
452
64fd1de3
HC
453SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list,
454 size_t, size)
1da177e4 455{
2d8f3038 456 struct path path;
1da177e4
LT
457 ssize_t error;
458
2d8f3038 459 error = user_path(pathname, &path);
1da177e4
LT
460 if (error)
461 return error;
2d8f3038
AV
462 error = listxattr(path.dentry, list, size);
463 path_put(&path);
1da177e4
LT
464 return error;
465}
466
64fd1de3
HC
467SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list,
468 size_t, size)
1da177e4 469{
2d8f3038 470 struct path path;
1da177e4
LT
471 ssize_t error;
472
2d8f3038 473 error = user_lpath(pathname, &path);
1da177e4
LT
474 if (error)
475 return error;
2d8f3038
AV
476 error = listxattr(path.dentry, list, size);
477 path_put(&path);
1da177e4
LT
478 return error;
479}
480
64fd1de3 481SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size)
1da177e4
LT
482{
483 struct file *f;
484 ssize_t error = -EBADF;
485
486 f = fget(fd);
487 if (!f)
488 return error;
5a190ae6 489 audit_inode(NULL, f->f_path.dentry);
0f7fc9e4 490 error = listxattr(f->f_path.dentry, list, size);
1da177e4
LT
491 fput(f);
492 return error;
493}
494
495/*
496 * Extended attribute REMOVE operations
497 */
498static long
8f0cfa52 499removexattr(struct dentry *d, const char __user *name)
1da177e4
LT
500{
501 int error;
502 char kname[XATTR_NAME_MAX + 1];
503
504 error = strncpy_from_user(kname, name, sizeof(kname));
505 if (error == 0 || error == sizeof(kname))
506 error = -ERANGE;
507 if (error < 0)
508 return error;
509
5be196e5 510 return vfs_removexattr(d, kname);
1da177e4
LT
511}
512
64fd1de3
HC
513SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
514 const char __user *, name)
1da177e4 515{
2d8f3038 516 struct path path;
1da177e4
LT
517 int error;
518
2d8f3038 519 error = user_path(pathname, &path);
1da177e4
LT
520 if (error)
521 return error;
2d8f3038 522 error = mnt_want_write(path.mnt);
18f335af 523 if (!error) {
2d8f3038
AV
524 error = removexattr(path.dentry, name);
525 mnt_drop_write(path.mnt);
18f335af 526 }
2d8f3038 527 path_put(&path);
1da177e4
LT
528 return error;
529}
530
6a6160a7
HC
531SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname,
532 const char __user *, name)
1da177e4 533{
2d8f3038 534 struct path path;
1da177e4
LT
535 int error;
536
2d8f3038 537 error = user_lpath(pathname, &path);
1da177e4
LT
538 if (error)
539 return error;
2d8f3038 540 error = mnt_want_write(path.mnt);
18f335af 541 if (!error) {
2d8f3038
AV
542 error = removexattr(path.dentry, name);
543 mnt_drop_write(path.mnt);
18f335af 544 }
2d8f3038 545 path_put(&path);
1da177e4
LT
546 return error;
547}
548
6a6160a7 549SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
1da177e4
LT
550{
551 struct file *f;
73241ccc 552 struct dentry *dentry;
1da177e4
LT
553 int error = -EBADF;
554
555 f = fget(fd);
556 if (!f)
557 return error;
0f7fc9e4 558 dentry = f->f_path.dentry;
5a190ae6 559 audit_inode(NULL, dentry);
96029c4e 560 error = mnt_want_write_file(f);
18f335af
DH
561 if (!error) {
562 error = removexattr(dentry, name);
563 mnt_drop_write(f->f_path.mnt);
564 }
1da177e4
LT
565 fput(f);
566 return error;
567}
568
569
570static const char *
571strcmp_prefix(const char *a, const char *a_prefix)
572{
573 while (*a_prefix && *a == *a_prefix) {
574 a++;
575 a_prefix++;
576 }
577 return *a_prefix ? NULL : a;
578}
579
580/*
581 * In order to implement different sets of xattr operations for each xattr
582 * prefix with the generic xattr API, a filesystem should create a
583 * null-terminated array of struct xattr_handler (one for each prefix) and
584 * hang a pointer to it off of the s_xattr field of the superblock.
585 *
586 * The generic_fooxattr() functions will use this list to dispatch xattr
587 * operations to the correct xattr_handler.
588 */
589#define for_each_xattr_handler(handlers, handler) \
590 for ((handler) = *(handlers)++; \
591 (handler) != NULL; \
592 (handler) = *(handlers)++)
593
594/*
595 * Find the xattr_handler with the matching prefix.
596 */
bb435453
SH
597static const struct xattr_handler *
598xattr_resolve_name(const struct xattr_handler **handlers, const char **name)
1da177e4 599{
bb435453 600 const struct xattr_handler *handler;
1da177e4
LT
601
602 if (!*name)
603 return NULL;
604
605 for_each_xattr_handler(handlers, handler) {
606 const char *n = strcmp_prefix(*name, handler->prefix);
607 if (n) {
608 *name = n;
609 break;
610 }
611 }
612 return handler;
613}
614
615/*
616 * Find the handler for the prefix and dispatch its get() operation.
617 */
618ssize_t
619generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size)
620{
bb435453 621 const struct xattr_handler *handler;
1da177e4 622
431547b3 623 handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
1da177e4
LT
624 if (!handler)
625 return -EOPNOTSUPP;
431547b3 626 return handler->get(dentry, name, buffer, size, handler->flags);
1da177e4
LT
627}
628
629/*
630 * Combine the results of the list() operation from every xattr_handler in the
631 * list.
632 */
633ssize_t
634generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
635{
bb435453 636 const struct xattr_handler *handler, **handlers = dentry->d_sb->s_xattr;
1da177e4
LT
637 unsigned int size = 0;
638
639 if (!buffer) {
431547b3
CH
640 for_each_xattr_handler(handlers, handler) {
641 size += handler->list(dentry, NULL, 0, NULL, 0,
642 handler->flags);
643 }
1da177e4
LT
644 } else {
645 char *buf = buffer;
646
647 for_each_xattr_handler(handlers, handler) {
431547b3
CH
648 size = handler->list(dentry, buf, buffer_size,
649 NULL, 0, handler->flags);
1da177e4
LT
650 if (size > buffer_size)
651 return -ERANGE;
652 buf += size;
653 buffer_size -= size;
654 }
655 size = buf - buffer;
656 }
657 return size;
658}
659
660/*
661 * Find the handler for the prefix and dispatch its set() operation.
662 */
663int
664generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags)
665{
bb435453 666 const struct xattr_handler *handler;
1da177e4
LT
667
668 if (size == 0)
669 value = ""; /* empty EA, do not remove */
431547b3 670 handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
1da177e4
LT
671 if (!handler)
672 return -EOPNOTSUPP;
df7e1303 673 return handler->set(dentry, name, value, size, flags, handler->flags);
1da177e4
LT
674}
675
676/*
677 * Find the handler for the prefix and dispatch its set() operation to remove
678 * any associated extended attribute.
679 */
680int
681generic_removexattr(struct dentry *dentry, const char *name)
682{
bb435453 683 const struct xattr_handler *handler;
1da177e4 684
431547b3 685 handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
1da177e4
LT
686 if (!handler)
687 return -EOPNOTSUPP;
431547b3
CH
688 return handler->set(dentry, name, NULL, 0,
689 XATTR_REPLACE, handler->flags);
1da177e4
LT
690}
691
692EXPORT_SYMBOL(generic_getxattr);
693EXPORT_SYMBOL(generic_listxattr);
694EXPORT_SYMBOL(generic_setxattr);
695EXPORT_SYMBOL(generic_removexattr);