summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext2/xattr.c15
-rw-r--r--fs/ext2/xattr_security.c17
-rw-r--r--fs/ext2/xattr_trusted.c19
-rw-r--r--fs/ext2/xattr_user.c19
-rw-r--r--fs/ext4/xattr.c17
-rw-r--r--fs/ext4/xattr_security.c18
-rw-r--r--fs/ext4/xattr_trusted.c19
-rw-r--r--fs/ext4/xattr_user.c19
-rw-r--r--fs/f2fs/xattr.c82
-rw-r--r--fs/jffs2/security.c16
-rw-r--r--fs/jffs2/xattr.c26
-rw-r--r--fs/jffs2/xattr_trusted.c17
-rw-r--r--fs/jffs2/xattr_user.c16
-rw-r--r--fs/nfs/nfs4proc.c14
-rw-r--r--fs/posix_acl.c17
-rw-r--r--fs/reiserfs/xattr.c13
-rw-r--r--fs/reiserfs/xattr_security.c16
-rw-r--r--fs/reiserfs/xattr_trusted.c15
-rw-r--r--fs/reiserfs/xattr_user.c14
-rw-r--r--fs/squashfs/xattr.c35
-rw-r--r--fs/xattr.c20
-rw-r--r--include/linux/xattr.h4
22 files changed, 113 insertions, 335 deletions
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c
index fa70848afa8f..cd95d14f9cc2 100644
--- a/fs/ext2/xattr.c
+++ b/fs/ext2/xattr.c
@@ -292,16 +292,21 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_list",
292 const struct xattr_handler *handler = 292 const struct xattr_handler *handler =
293 ext2_xattr_handler(entry->e_name_index); 293 ext2_xattr_handler(entry->e_name_index);
294 294
295 if (handler) { 295 if (handler && (!handler->list || handler->list(dentry))) {
296 size_t size = handler->list(handler, dentry, buffer, 296 const char *prefix = handler->prefix ?: handler->name;
297 rest, entry->e_name, 297 size_t prefix_len = strlen(prefix);
298 entry->e_name_len); 298 size_t size = prefix_len + entry->e_name_len + 1;
299
299 if (buffer) { 300 if (buffer) {
300 if (size > rest) { 301 if (size > rest) {
301 error = -ERANGE; 302 error = -ERANGE;
302 goto cleanup; 303 goto cleanup;
303 } 304 }
304 buffer += size; 305 memcpy(buffer, prefix, prefix_len);
306 buffer += prefix_len;
307 memcpy(buffer, entry->e_name, entry->e_name_len);
308 buffer += entry->e_name_len;
309 *buffer++ = 0;
305 } 310 }
306 rest -= size; 311 rest -= size;
307 } 312 }
diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c
index 118bf231bc7f..ba97f243b050 100644
--- a/fs/ext2/xattr_security.c
+++ b/fs/ext2/xattr_security.c
@@ -7,22 +7,6 @@
7#include <linux/security.h> 7#include <linux/security.h>
8#include "xattr.h" 8#include "xattr.h"
9 9
10static size_t
11ext2_xattr_security_list(const struct xattr_handler *handler,
12 struct dentry *dentry, char *list, size_t list_size,
13 const char *name, size_t name_len)
14{
15 const int prefix_len = XATTR_SECURITY_PREFIX_LEN;
16 const size_t total_len = prefix_len + name_len + 1;
17
18 if (list && total_len <= list_size) {
19 memcpy(list, XATTR_SECURITY_PREFIX, prefix_len);
20 memcpy(list+prefix_len, name, name_len);
21 list[prefix_len + name_len] = '\0';
22 }
23 return total_len;
24}
25
26static int 10static int
27ext2_xattr_security_get(const struct xattr_handler *handler, 11ext2_xattr_security_get(const struct xattr_handler *handler,
28 struct dentry *dentry, const char *name, 12 struct dentry *dentry, const char *name,
@@ -67,7 +51,6 @@ ext2_init_security(struct inode *inode, struct inode *dir,
67 51
68const struct xattr_handler ext2_xattr_security_handler = { 52const struct xattr_handler ext2_xattr_security_handler = {
69 .prefix = XATTR_SECURITY_PREFIX, 53 .prefix = XATTR_SECURITY_PREFIX,
70 .list = ext2_xattr_security_list,
71 .get = ext2_xattr_security_get, 54 .get = ext2_xattr_security_get,
72 .set = ext2_xattr_security_set, 55 .set = ext2_xattr_security_set,
73}; 56};
diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c
index 3f8f2bc6539e..2c94d1930626 100644
--- a/fs/ext2/xattr_trusted.c
+++ b/fs/ext2/xattr_trusted.c
@@ -8,23 +8,10 @@
8#include "ext2.h" 8#include "ext2.h"
9#include "xattr.h" 9#include "xattr.h"
10 10
11static size_t 11static bool
12ext2_xattr_trusted_list(const struct xattr_handler *handler, 12ext2_xattr_trusted_list(struct dentry *dentry)
13 struct dentry *dentry, char *list, size_t list_size,
14 const char *name, size_t name_len)
15{ 13{
16 const int prefix_len = XATTR_TRUSTED_PREFIX_LEN; 14 return capable(CAP_SYS_ADMIN);
17 const size_t total_len = prefix_len + name_len + 1;
18
19 if (!capable(CAP_SYS_ADMIN))
20 return 0;
21
22 if (list && total_len <= list_size) {
23 memcpy(list, XATTR_TRUSTED_PREFIX, prefix_len);
24 memcpy(list+prefix_len, name, name_len);
25 list[prefix_len + name_len] = '\0';
26 }
27 return total_len;
28} 15}
29 16
30static int 17static int
diff --git a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c
index afd45ab1218c..72a2a96d677f 100644
--- a/fs/ext2/xattr_user.c
+++ b/fs/ext2/xattr_user.c
@@ -10,23 +10,10 @@
10#include "ext2.h" 10#include "ext2.h"
11#include "xattr.h" 11#include "xattr.h"
12 12
13static size_t 13static bool
14ext2_xattr_user_list(const struct xattr_handler *handler, 14ext2_xattr_user_list(struct dentry *dentry)
15 struct dentry *dentry, char *list, size_t list_size,
16 const char *name, size_t name_len)
17{ 15{
18 const size_t prefix_len = XATTR_USER_PREFIX_LEN; 16 return test_opt(dentry->d_sb, XATTR_USER);
19 const size_t total_len = prefix_len + name_len + 1;
20
21 if (!test_opt(dentry->d_sb, XATTR_USER))
22 return 0;
23
24 if (list && total_len <= list_size) {
25 memcpy(list, XATTR_USER_PREFIX, prefix_len);
26 memcpy(list+prefix_len, name, name_len);
27 list[prefix_len + name_len] = '\0';
28 }
29 return total_len;
30} 17}
31 18
32static int 19static int
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 6b6b3e751f8c..e9b9afdd1d96 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -404,19 +404,24 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
404 const struct xattr_handler *handler = 404 const struct xattr_handler *handler =
405 ext4_xattr_handler(entry->e_name_index); 405 ext4_xattr_handler(entry->e_name_index);
406 406
407 if (handler) { 407 if (handler && (!handler->list || handler->list(dentry))) {
408 size_t size = handler->list(handler, dentry, buffer, 408 const char *prefix = handler->prefix ?: handler->name;
409 rest, entry->e_name, 409 size_t prefix_len = strlen(prefix);
410 entry->e_name_len); 410 size_t size = prefix_len + entry->e_name_len + 1;
411
411 if (buffer) { 412 if (buffer) {
412 if (size > rest) 413 if (size > rest)
413 return -ERANGE; 414 return -ERANGE;
414 buffer += size; 415 memcpy(buffer, prefix, prefix_len);
416 buffer += prefix_len;
417 memcpy(buffer, entry->e_name, entry->e_name_len);
418 buffer += entry->e_name_len;
419 *buffer++ = 0;
415 } 420 }
416 rest -= size; 421 rest -= size;
417 } 422 }
418 } 423 }
419 return buffer_size - rest; 424 return buffer_size - rest; /* total size */
420} 425}
421 426
422static int 427static int
diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c
index 195abc4a88bb..3e81bdca071a 100644
--- a/fs/ext4/xattr_security.c
+++ b/fs/ext4/xattr_security.c
@@ -11,23 +11,6 @@
11#include "ext4.h" 11#include "ext4.h"
12#include "xattr.h" 12#include "xattr.h"
13 13
14static size_t
15ext4_xattr_security_list(const struct xattr_handler *handler,
16 struct dentry *dentry, char *list, size_t list_size,
17 const char *name, size_t name_len)
18{
19 const size_t prefix_len = sizeof(XATTR_SECURITY_PREFIX)-1;
20 const size_t total_len = prefix_len + name_len + 1;
21
22
23 if (list && total_len <= list_size) {
24 memcpy(list, XATTR_SECURITY_PREFIX, prefix_len);
25 memcpy(list+prefix_len, name, name_len);
26 list[prefix_len + name_len] = '\0';
27 }
28 return total_len;
29}
30
31static int 14static int
32ext4_xattr_security_get(const struct xattr_handler *handler, 15ext4_xattr_security_get(const struct xattr_handler *handler,
33 struct dentry *dentry, const char *name, 16 struct dentry *dentry, const char *name,
@@ -75,7 +58,6 @@ ext4_init_security(handle_t *handle, struct inode *inode, struct inode *dir,
75 58
76const struct xattr_handler ext4_xattr_security_handler = { 59const struct xattr_handler ext4_xattr_security_handler = {
77 .prefix = XATTR_SECURITY_PREFIX, 60 .prefix = XATTR_SECURITY_PREFIX,
78 .list = ext4_xattr_security_list,
79 .get = ext4_xattr_security_get, 61 .get = ext4_xattr_security_get,
80 .set = ext4_xattr_security_set, 62 .set = ext4_xattr_security_set,
81}; 63};
diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c
index 121fdf9fdc02..2a3c6f9b8cb8 100644
--- a/fs/ext4/xattr_trusted.c
+++ b/fs/ext4/xattr_trusted.c
@@ -12,23 +12,10 @@
12#include "ext4.h" 12#include "ext4.h"
13#include "xattr.h" 13#include "xattr.h"
14 14
15static size_t 15static bool
16ext4_xattr_trusted_list(const struct xattr_handler *handler, 16ext4_xattr_trusted_list(struct dentry *dentry)
17 struct dentry *dentry, char *list, size_t list_size,
18 const char *name, size_t name_len)
19{ 17{
20 const size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN; 18 return capable(CAP_SYS_ADMIN);
21 const size_t total_len = prefix_len + name_len + 1;
22
23 if (!capable(CAP_SYS_ADMIN))
24 return 0;
25
26 if (list && total_len <= list_size) {
27 memcpy(list, XATTR_TRUSTED_PREFIX, prefix_len);
28 memcpy(list+prefix_len, name, name_len);
29 list[prefix_len + name_len] = '\0';
30 }
31 return total_len;
32} 19}
33 20
34static int 21static int
diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c
index 577fc122d884..d152f431e432 100644
--- a/fs/ext4/xattr_user.c
+++ b/fs/ext4/xattr_user.c
@@ -11,23 +11,10 @@
11#include "ext4.h" 11#include "ext4.h"
12#include "xattr.h" 12#include "xattr.h"
13 13
14static size_t 14static bool
15ext4_xattr_user_list(const struct xattr_handler *handler, 15ext4_xattr_user_list(struct dentry *dentry)
16 struct dentry *dentry, char *list, size_t list_size,
17 const char *name, size_t name_len)
18{ 16{
19 const size_t prefix_len = XATTR_USER_PREFIX_LEN; 17 return test_opt(dentry->d_sb, XATTR_USER);
20 const size_t total_len = prefix_len + name_len + 1;
21
22 if (!test_opt(dentry->d_sb, XATTR_USER))
23 return 0;
24
25 if (list && total_len <= list_size) {
26 memcpy(list, XATTR_USER_PREFIX, prefix_len);
27 memcpy(list+prefix_len, name, name_len);
28 list[prefix_len + name_len] = '\0';
29 }
30 return total_len;
31} 18}
32 19
33static int 20static int
diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
index 21cfe516034f..036952a945fa 100644
--- a/fs/f2fs/xattr.c
+++ b/fs/f2fs/xattr.c
@@ -25,40 +25,6 @@
25#include "f2fs.h" 25#include "f2fs.h"
26#include "xattr.h" 26#include "xattr.h"
27 27
28static size_t f2fs_xattr_generic_list(const struct xattr_handler *handler,
29 struct dentry *dentry, char *list, size_t list_size,
30 const char *name, size_t len)
31{
32 struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
33 const char *prefix;
34 int total_len, prefix_len;
35
36 switch (handler->flags) {
37 case F2FS_XATTR_INDEX_USER:
38 if (!test_opt(sbi, XATTR_USER))
39 return -EOPNOTSUPP;
40 break;
41 case F2FS_XATTR_INDEX_TRUSTED:
42 if (!capable(CAP_SYS_ADMIN))
43 return -EPERM;
44 break;
45 case F2FS_XATTR_INDEX_SECURITY:
46 break;
47 default:
48 return -EINVAL;
49 }
50
51 prefix = xattr_prefix(handler);
52 prefix_len = strlen(prefix);
53 total_len = prefix_len + len + 1;
54 if (list && total_len <= list_size) {
55 memcpy(list, prefix, prefix_len);
56 memcpy(list + prefix_len, name, len);
57 list[prefix_len + len] = '\0';
58 }
59 return total_len;
60}
61
62static int f2fs_xattr_generic_get(const struct xattr_handler *handler, 28static int f2fs_xattr_generic_get(const struct xattr_handler *handler,
63 struct dentry *dentry, const char *name, void *buffer, 29 struct dentry *dentry, const char *name, void *buffer,
64 size_t size) 30 size_t size)
@@ -107,17 +73,16 @@ static int f2fs_xattr_generic_set(const struct xattr_handler *handler,
107 value, size, NULL, flags); 73 value, size, NULL, flags);
108} 74}
109 75
110static size_t f2fs_xattr_advise_list(const struct xattr_handler *handler, 76static bool f2fs_xattr_user_list(struct dentry *dentry)
111 struct dentry *dentry, char *list, size_t list_size,
112 const char *name, size_t len)
113{ 77{
114 const char *xname = F2FS_SYSTEM_ADVISE_NAME; 78 struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb);
115 size_t size; 79
80 return test_opt(sbi, XATTR_USER);
81}
116 82
117 size = strlen(xname) + 1; 83static bool f2fs_xattr_trusted_list(struct dentry *dentry)
118 if (list && size <= list_size) 84{
119 memcpy(list, xname, size); 85 return capable(CAP_SYS_ADMIN);
120 return size;
121} 86}
122 87
123static int f2fs_xattr_advise_get(const struct xattr_handler *handler, 88static int f2fs_xattr_advise_get(const struct xattr_handler *handler,
@@ -175,7 +140,7 @@ int f2fs_init_security(struct inode *inode, struct inode *dir,
175const struct xattr_handler f2fs_xattr_user_handler = { 140const struct xattr_handler f2fs_xattr_user_handler = {
176 .prefix = XATTR_USER_PREFIX, 141 .prefix = XATTR_USER_PREFIX,
177 .flags = F2FS_XATTR_INDEX_USER, 142 .flags = F2FS_XATTR_INDEX_USER,
178 .list = f2fs_xattr_generic_list, 143 .list = f2fs_xattr_user_list,
179 .get = f2fs_xattr_generic_get, 144 .get = f2fs_xattr_generic_get,
180 .set = f2fs_xattr_generic_set, 145 .set = f2fs_xattr_generic_set,
181}; 146};
@@ -183,7 +148,7 @@ const struct xattr_handler f2fs_xattr_user_handler = {
183const struct xattr_handler f2fs_xattr_trusted_handler = { 148const struct xattr_handler f2fs_xattr_trusted_handler = {
184 .prefix = XATTR_TRUSTED_PREFIX, 149 .prefix = XATTR_TRUSTED_PREFIX,
185 .flags = F2FS_XATTR_INDEX_TRUSTED, 150 .flags = F2FS_XATTR_INDEX_TRUSTED,
186 .list = f2fs_xattr_generic_list, 151 .list = f2fs_xattr_trusted_list,
187 .get = f2fs_xattr_generic_get, 152 .get = f2fs_xattr_generic_get,
188 .set = f2fs_xattr_generic_set, 153 .set = f2fs_xattr_generic_set,
189}; 154};
@@ -191,7 +156,6 @@ const struct xattr_handler f2fs_xattr_trusted_handler = {
191const struct xattr_handler f2fs_xattr_advise_handler = { 156const struct xattr_handler f2fs_xattr_advise_handler = {
192 .name = F2FS_SYSTEM_ADVISE_NAME, 157 .name = F2FS_SYSTEM_ADVISE_NAME,
193 .flags = F2FS_XATTR_INDEX_ADVISE, 158 .flags = F2FS_XATTR_INDEX_ADVISE,
194 .list = f2fs_xattr_advise_list,
195 .get = f2fs_xattr_advise_get, 159 .get = f2fs_xattr_advise_get,
196 .set = f2fs_xattr_advise_set, 160 .set = f2fs_xattr_advise_set,
197}; 161};
@@ -199,7 +163,6 @@ const struct xattr_handler f2fs_xattr_advise_handler = {
199const struct xattr_handler f2fs_xattr_security_handler = { 163const struct xattr_handler f2fs_xattr_security_handler = {
200 .prefix = XATTR_SECURITY_PREFIX, 164 .prefix = XATTR_SECURITY_PREFIX,
201 .flags = F2FS_XATTR_INDEX_SECURITY, 165 .flags = F2FS_XATTR_INDEX_SECURITY,
202 .list = f2fs_xattr_generic_list,
203 .get = f2fs_xattr_generic_get, 166 .get = f2fs_xattr_generic_get,
204 .set = f2fs_xattr_generic_set, 167 .set = f2fs_xattr_generic_set,
205}; 168};
@@ -447,20 +410,27 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
447 list_for_each_xattr(entry, base_addr) { 410 list_for_each_xattr(entry, base_addr) {
448 const struct xattr_handler *handler = 411 const struct xattr_handler *handler =
449 f2fs_xattr_handler(entry->e_name_index); 412 f2fs_xattr_handler(entry->e_name_index);
413 const char *prefix;
414 size_t prefix_len;
450 size_t size; 415 size_t size;
451 416
452 if (!handler) 417 if (!handler || (handler->list && !handler->list(dentry)))
453 continue; 418 continue;
454 419
455 size = handler->list(handler, dentry, buffer, rest, 420 prefix = handler->prefix ?: handler->name;
456 entry->e_name, entry->e_name_len); 421 prefix_len = strlen(prefix);
457 if (buffer && size > rest) { 422 size = prefix_len + entry->e_name_len + 1;
458 error = -ERANGE; 423 if (buffer) {
459 goto cleanup; 424 if (size > rest) {
425 error = -ERANGE;
426 goto cleanup;
427 }
428 memcpy(buffer, prefix, prefix_len);
429 buffer += prefix_len;
430 memcpy(buffer, entry->e_name, entry->e_name_len);
431 buffer += entry->e_name_len;
432 *buffer++ = 0;
460 } 433 }
461
462 if (buffer)
463 buffer += size;
464 rest -= size; 434 rest -= size;
465 } 435 }
466 error = buffer_size - rest; 436 error = buffer_size - rest;
diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c
index ea79932cd665..7a28facd7175 100644
--- a/fs/jffs2/security.c
+++ b/fs/jffs2/security.c
@@ -64,24 +64,8 @@ static int jffs2_security_setxattr(const struct xattr_handler *handler,
64 name, buffer, size, flags); 64 name, buffer, size, flags);
65} 65}
66 66
67static size_t jffs2_security_listxattr(const struct xattr_handler *handler,
68 struct dentry *dentry, char *list,
69 size_t list_size, const char *name,
70 size_t name_len)
71{
72 size_t retlen = XATTR_SECURITY_PREFIX_LEN + name_len + 1;
73
74 if (list && retlen <= list_size) {
75 strcpy(list, XATTR_SECURITY_PREFIX);
76 strcpy(list + XATTR_SECURITY_PREFIX_LEN, name);
77 }
78
79 return retlen;
80}
81
82const struct xattr_handler jffs2_security_xattr_handler = { 67const struct xattr_handler jffs2_security_xattr_handler = {
83 .prefix = XATTR_SECURITY_PREFIX, 68 .prefix = XATTR_SECURITY_PREFIX,
84 .list = jffs2_security_listxattr,
85 .set = jffs2_security_setxattr, 69 .set = jffs2_security_setxattr,
86 .get = jffs2_security_getxattr 70 .get = jffs2_security_getxattr
87}; 71};
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c
index 4c2c03663533..da3e18503c65 100644
--- a/fs/jffs2/xattr.c
+++ b/fs/jffs2/xattr.c
@@ -967,7 +967,8 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
967 struct jffs2_xattr_ref *ref, **pref; 967 struct jffs2_xattr_ref *ref, **pref;
968 struct jffs2_xattr_datum *xd; 968 struct jffs2_xattr_datum *xd;
969 const struct xattr_handler *xhandle; 969 const struct xattr_handler *xhandle;
970 ssize_t len, rc; 970 const char *prefix;
971 ssize_t prefix_len, len, rc;
971 int retry = 0; 972 int retry = 0;
972 973
973 rc = check_xattr_ref_inode(c, ic); 974 rc = check_xattr_ref_inode(c, ic);
@@ -998,18 +999,23 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
998 } 999 }
999 } 1000 }
1000 xhandle = xprefix_to_handler(xd->xprefix); 1001 xhandle = xprefix_to_handler(xd->xprefix);
1001 if (!xhandle) 1002 if (!xhandle || (xhandle->list && !xhandle->list(dentry)))
1002 continue; 1003 continue;
1004 prefix = xhandle->prefix ?: xhandle->name;
1005 prefix_len = strlen(prefix);
1006 rc = prefix_len + xd->name_len + 1;
1007
1003 if (buffer) { 1008 if (buffer) {
1004 rc = xhandle->list(xhandle, dentry, buffer + len, 1009 if (rc > size - len) {
1005 size - len, xd->xname, 1010 rc = -ERANGE;
1006 xd->name_len); 1011 goto out;
1007 } else { 1012 }
1008 rc = xhandle->list(xhandle, dentry, NULL, 0, 1013 memcpy(buffer, prefix, prefix_len);
1009 xd->xname, xd->name_len); 1014 buffer += prefix_len;
1015 memcpy(buffer, xd->xname, xd->name_len);
1016 buffer += xd->name_len;
1017 *buffer++ = 0;
1010 } 1018 }
1011 if (rc < 0)
1012 goto out;
1013 len += rc; 1019 len += rc;
1014 } 1020 }
1015 rc = len; 1021 rc = len;
diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c
index 8b55fe44c777..b2555ef07a12 100644
--- a/fs/jffs2/xattr_trusted.c
+++ b/fs/jffs2/xattr_trusted.c
@@ -32,22 +32,9 @@ static int jffs2_trusted_setxattr(const struct xattr_handler *handler,
32 name, buffer, size, flags); 32 name, buffer, size, flags);
33} 33}
34 34
35static size_t jffs2_trusted_listxattr(const struct xattr_handler *handler, 35static bool jffs2_trusted_listxattr(struct dentry *dentry)
36 struct dentry *dentry, char *list,
37 size_t list_size, const char *name,
38 size_t name_len)
39{ 36{
40 size_t retlen = XATTR_TRUSTED_PREFIX_LEN + name_len + 1; 37 return capable(CAP_SYS_ADMIN);
41
42 if (!capable(CAP_SYS_ADMIN))
43 return 0;
44
45 if (list && retlen<=list_size) {
46 strcpy(list, XATTR_TRUSTED_PREFIX);
47 strcpy(list + XATTR_TRUSTED_PREFIX_LEN, name);
48 }
49
50 return retlen;
51} 38}
52 39
53const struct xattr_handler jffs2_trusted_xattr_handler = { 40const struct xattr_handler jffs2_trusted_xattr_handler = {
diff --git a/fs/jffs2/xattr_user.c b/fs/jffs2/xattr_user.c
index b04335b84833..539bd630b5e4 100644
--- a/fs/jffs2/xattr_user.c
+++ b/fs/jffs2/xattr_user.c
@@ -32,24 +32,8 @@ static int jffs2_user_setxattr(const struct xattr_handler *handler,
32 name, buffer, size, flags); 32 name, buffer, size, flags);
33} 33}
34 34
35static size_t jffs2_user_listxattr(const struct xattr_handler *handler,
36 struct dentry *dentry, char *list,
37 size_t list_size, const char *name,
38 size_t name_len)
39{
40 size_t retlen = XATTR_USER_PREFIX_LEN + name_len + 1;
41
42 if (list && retlen <= list_size) {
43 strcpy(list, XATTR_USER_PREFIX);
44 strcpy(list + XATTR_USER_PREFIX_LEN, name);
45 }
46
47 return retlen;
48}
49
50const struct xattr_handler jffs2_user_xattr_handler = { 35const struct xattr_handler jffs2_user_xattr_handler = {
51 .prefix = XATTR_USER_PREFIX, 36 .prefix = XATTR_USER_PREFIX,
52 .list = jffs2_user_listxattr,
53 .set = jffs2_user_setxattr, 37 .set = jffs2_user_setxattr,
54 .get = jffs2_user_getxattr 38 .get = jffs2_user_getxattr
55}; 39};
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index dbfade2602c9..c57d1332c1c8 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -6263,19 +6263,9 @@ static int nfs4_xattr_get_nfs4_acl(const struct xattr_handler *handler,
6263 return nfs4_proc_get_acl(d_inode(dentry), buf, buflen); 6263 return nfs4_proc_get_acl(d_inode(dentry), buf, buflen);
6264} 6264}
6265 6265
6266static size_t nfs4_xattr_list_nfs4_acl(const struct xattr_handler *handler, 6266static bool nfs4_xattr_list_nfs4_acl(struct dentry *dentry)
6267 struct dentry *dentry, char *list,
6268 size_t list_len, const char *name,
6269 size_t name_len)
6270{ 6267{
6271 size_t len = sizeof(XATTR_NAME_NFSV4_ACL); 6268 return nfs4_server_supports_acls(NFS_SERVER(d_inode(dentry)));
6272
6273 if (!nfs4_server_supports_acls(NFS_SERVER(d_inode(dentry))))
6274 return 0;
6275
6276 if (list && len <= list_len)
6277 memcpy(list, XATTR_NAME_NFSV4_ACL, len);
6278 return len;
6279} 6269}
6280 6270
6281#ifdef CONFIG_NFS_V4_SECURITY_LABEL 6271#ifdef CONFIG_NFS_V4_SECURITY_LABEL
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index 17efd76978c8..711dd5170376 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -823,21 +823,10 @@ out:
823 return ret; 823 return ret;
824} 824}
825 825
826static size_t 826static bool
827posix_acl_xattr_list(const struct xattr_handler *handler, 827posix_acl_xattr_list(struct dentry *dentry)
828 struct dentry *dentry, char *list, size_t list_size,
829 const char *name, size_t name_len)
830{ 828{
831 const char *xname = handler->name; 829 return IS_POSIXACL(d_backing_inode(dentry));
832 size_t size;
833
834 if (!IS_POSIXACL(d_backing_inode(dentry)))
835 return 0;
836
837 size = strlen(xname) + 1;
838 if (list && size <= list_size)
839 memcpy(list, xname, size);
840 return size;
841} 830}
842 831
843const struct xattr_handler posix_acl_access_xattr_handler = { 832const struct xattr_handler posix_acl_access_xattr_handler = {
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index efe2ed3c13c5..e5ddb4e5ea94 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -840,19 +840,16 @@ static int listxattr_filler(struct dir_context *ctx, const char *name,
840 840
841 handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr, 841 handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr,
842 name); 842 name);
843 if (!handler) /* Unsupported xattr name */ 843 if (!handler /* Unsupported xattr name */ ||
844 (handler->list && !handler->list(b->dentry)))
844 return 0; 845 return 0;
846 size = namelen + 1;
845 if (b->buf) { 847 if (b->buf) {
846 size = handler->list(handler, b->dentry,
847 b->buf + b->pos, b->size, name,
848 namelen);
849 if (size > b->size) 848 if (size > b->size)
850 return -ERANGE; 849 return -ERANGE;
851 } else { 850 memcpy(b->buf + b->pos, name, namelen);
852 size = handler->list(handler, b->dentry, 851 b->buf[b->pos + namelen] = 0;
853 NULL, 0, name, namelen);
854 } 852 }
855
856 b->pos += size; 853 b->pos += size;
857 } 854 }
858 return 0; 855 return 0;
diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c
index ac659af431ae..ab0217d32039 100644
--- a/fs/reiserfs/xattr_security.c
+++ b/fs/reiserfs/xattr_security.c
@@ -34,21 +34,9 @@ security_set(const struct xattr_handler *handler, struct dentry *dentry,
34 return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); 34 return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags);
35} 35}
36 36
37static size_t security_list(const struct xattr_handler *handler, 37static bool security_list(struct dentry *dentry)
38 struct dentry *dentry, char *list, size_t list_len,
39 const char *name, size_t namelen)
40{ 38{
41 const size_t len = namelen + 1; 39 return !IS_PRIVATE(d_inode(dentry));
42
43 if (IS_PRIVATE(d_inode(dentry)))
44 return 0;
45
46 if (list && len <= list_len) {
47 memcpy(list, name, namelen);
48 list[namelen] = '\0';
49 }
50
51 return len;
52} 40}
53 41
54/* Initializes the security context for a new inode and returns the number 42/* Initializes the security context for a new inode and returns the number
diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c
index a338adf1b8b4..64b67aa643a9 100644
--- a/fs/reiserfs/xattr_trusted.c
+++ b/fs/reiserfs/xattr_trusted.c
@@ -33,20 +33,9 @@ trusted_set(const struct xattr_handler *handler, struct dentry *dentry,
33 return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); 33 return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags);
34} 34}
35 35
36static size_t trusted_list(const struct xattr_handler *handler, 36static bool trusted_list(struct dentry *dentry)
37 struct dentry *dentry, char *list, size_t list_size,
38 const char *name, size_t name_len)
39{ 37{
40 const size_t len = name_len + 1; 38 return capable(CAP_SYS_ADMIN) && !IS_PRIVATE(d_inode(dentry));
41
42 if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(d_inode(dentry)))
43 return 0;
44
45 if (list && len <= list_size) {
46 memcpy(list, name, name_len);
47 list[name_len] = '\0';
48 }
49 return len;
50} 39}
51 40
52const struct xattr_handler reiserfs_xattr_trusted_handler = { 41const struct xattr_handler reiserfs_xattr_trusted_handler = {
diff --git a/fs/reiserfs/xattr_user.c b/fs/reiserfs/xattr_user.c
index 39c9667191c5..12e6306f562a 100644
--- a/fs/reiserfs/xattr_user.c
+++ b/fs/reiserfs/xattr_user.c
@@ -30,19 +30,9 @@ user_set(const struct xattr_handler *handler, struct dentry *dentry,
30 return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); 30 return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags);
31} 31}
32 32
33static size_t user_list(const struct xattr_handler *handler, 33static bool user_list(struct dentry *dentry)
34 struct dentry *dentry, char *list, size_t list_size,
35 const char *name, size_t name_len)
36{ 34{
37 const size_t len = name_len + 1; 35 return reiserfs_xattrs_user(dentry->d_sb);
38
39 if (!reiserfs_xattrs_user(dentry->d_sb))
40 return 0;
41 if (list && len <= list_size) {
42 memcpy(list, name, name_len);
43 list[name_len] = '\0';
44 }
45 return len;
46} 36}
47 37
48const struct xattr_handler reiserfs_xattr_user_handler = { 38const struct xattr_handler reiserfs_xattr_user_handler = {
diff --git a/fs/squashfs/xattr.c b/fs/squashfs/xattr.c
index 2f0ccbaa2d92..1e9de96288d8 100644
--- a/fs/squashfs/xattr.c
+++ b/fs/squashfs/xattr.c
@@ -58,7 +58,7 @@ ssize_t squashfs_listxattr(struct dentry *d, char *buffer,
58 struct squashfs_xattr_entry entry; 58 struct squashfs_xattr_entry entry;
59 struct squashfs_xattr_val val; 59 struct squashfs_xattr_val val;
60 const struct xattr_handler *handler; 60 const struct xattr_handler *handler;
61 int name_size, prefix_size = 0; 61 int name_size;
62 62
63 err = squashfs_read_metadata(sb, &entry, &start, &offset, 63 err = squashfs_read_metadata(sb, &entry, &start, &offset,
64 sizeof(entry)); 64 sizeof(entry));
@@ -67,15 +67,16 @@ ssize_t squashfs_listxattr(struct dentry *d, char *buffer,
67 67
68 name_size = le16_to_cpu(entry.size); 68 name_size = le16_to_cpu(entry.size);
69 handler = squashfs_xattr_handler(le16_to_cpu(entry.type)); 69 handler = squashfs_xattr_handler(le16_to_cpu(entry.type));
70 if (handler) 70 if (handler && (!handler->list || handler->list(d))) {
71 prefix_size = handler->list(handler, d, buffer, rest, 71 const char *prefix = handler->prefix ?: handler->name;
72 NULL, name_size); 72 size_t prefix_size = strlen(prefix);
73 if (prefix_size) { 73
74 if (buffer) { 74 if (buffer) {
75 if (prefix_size + name_size + 1 > rest) { 75 if (prefix_size + name_size + 1 > rest) {
76 err = -ERANGE; 76 err = -ERANGE;
77 goto failed; 77 goto failed;
78 } 78 }
79 memcpy(buffer, prefix, prefix_size);
79 buffer += prefix_size; 80 buffer += prefix_size;
80 } 81 }
81 err = squashfs_read_metadata(sb, buffer, &start, 82 err = squashfs_read_metadata(sb, buffer, &start,
@@ -212,18 +213,6 @@ failed:
212} 213}
213 214
214 215
215static size_t squashfs_xattr_handler_list(const struct xattr_handler *handler,
216 struct dentry *d, char *list,
217 size_t list_size, const char *name,
218 size_t name_len)
219{
220 int len = strlen(handler->prefix);
221
222 if (list && len <= list_size)
223 memcpy(list, handler->prefix, len);
224 return len;
225}
226
227static int squashfs_xattr_handler_get(const struct xattr_handler *handler, 216static int squashfs_xattr_handler_get(const struct xattr_handler *handler,
228 struct dentry *d, const char *name, 217 struct dentry *d, const char *name,
229 void *buffer, size_t size) 218 void *buffer, size_t size)
@@ -238,22 +227,15 @@ static int squashfs_xattr_handler_get(const struct xattr_handler *handler,
238static const struct xattr_handler squashfs_xattr_user_handler = { 227static const struct xattr_handler squashfs_xattr_user_handler = {
239 .prefix = XATTR_USER_PREFIX, 228 .prefix = XATTR_USER_PREFIX,
240 .flags = SQUASHFS_XATTR_USER, 229 .flags = SQUASHFS_XATTR_USER,
241 .list = squashfs_xattr_handler_list,
242 .get = squashfs_xattr_handler_get 230 .get = squashfs_xattr_handler_get
243}; 231};
244 232
245/* 233/*
246 * Trusted namespace support 234 * Trusted namespace support
247 */ 235 */
248static size_t squashfs_trusted_xattr_handler_list(const struct xattr_handler *handler, 236static bool squashfs_trusted_xattr_handler_list(struct dentry *d)
249 struct dentry *d, char *list,
250 size_t list_size, const char *name,
251 size_t name_len)
252{ 237{
253 if (!capable(CAP_SYS_ADMIN)) 238 return capable(CAP_SYS_ADMIN);
254 return 0;
255 return squashfs_xattr_handler_list(handler, d, list, list_size, name,
256 name_len);
257} 239}
258 240
259static const struct xattr_handler squashfs_xattr_trusted_handler = { 241static const struct xattr_handler squashfs_xattr_trusted_handler = {
@@ -269,7 +251,6 @@ static const struct xattr_handler squashfs_xattr_trusted_handler = {
269static const struct xattr_handler squashfs_xattr_security_handler = { 251static const struct xattr_handler squashfs_xattr_security_handler = {
270 .prefix = XATTR_SECURITY_PREFIX, 252 .prefix = XATTR_SECURITY_PREFIX,
271 .flags = SQUASHFS_XATTR_SECURITY, 253 .flags = SQUASHFS_XATTR_SECURITY,
272 .list = squashfs_xattr_handler_list,
273 .get = squashfs_xattr_handler_get 254 .get = squashfs_xattr_handler_get
274}; 255};
275 256
diff --git a/fs/xattr.c b/fs/xattr.c
index 2c7776403aba..d7f5037a17b5 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -723,23 +723,25 @@ generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
723 723
724 if (!buffer) { 724 if (!buffer) {
725 for_each_xattr_handler(handlers, handler) { 725 for_each_xattr_handler(handlers, handler) {
726 if (!handler->list) 726 if (!handler->name ||
727 (handler->list && !handler->list(dentry)))
727 continue; 728 continue;
728 size += handler->list(handler, dentry, NULL, 0, 729 size += strlen(handler->name) + 1;
729 NULL, 0);
730 } 730 }
731 } else { 731 } else {
732 char *buf = buffer; 732 char *buf = buffer;
733 size_t len;
733 734
734 for_each_xattr_handler(handlers, handler) { 735 for_each_xattr_handler(handlers, handler) {
735 if (!handler->list) 736 if (!handler->name ||
737 (handler->list && !handler->list(dentry)))
736 continue; 738 continue;
737 size = handler->list(handler, dentry, buf, buffer_size, 739 len = strlen(handler->name);
738 NULL, 0); 740 if (len + 1 > buffer_size)
739 if (size > buffer_size)
740 return -ERANGE; 741 return -ERANGE;
741 buf += size; 742 memcpy(buf, handler->name, len + 1);
742 buffer_size -= size; 743 buf += len + 1;
744 buffer_size -= len + 1;
743 } 745 }
744 size = buf - buffer; 746 size = buf - buffer;
745 } 747 }
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index d23ce8e9af6f..4457541de3c9 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -28,9 +28,7 @@ struct xattr_handler {
28 const char *name; 28 const char *name;
29 const char *prefix; 29 const char *prefix;
30 int flags; /* fs private flags */ 30 int flags; /* fs private flags */
31 size_t (*list)(const struct xattr_handler *, struct dentry *dentry, 31 bool (*list)(struct dentry *dentry);
32 char *list, size_t list_size, const char *name,
33 size_t name_len);
34 int (*get)(const struct xattr_handler *, struct dentry *dentry, 32 int (*get)(const struct xattr_handler *, struct dentry *dentry,
35 const char *name, void *buffer, size_t size); 33 const char *name, void *buffer, size_t size);
36 int (*set)(const struct xattr_handler *, struct dentry *dentry, 34 int (*set)(const struct xattr_handler *, struct dentry *dentry,