Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xattr handlers: Simplify list operation

Change the list operation to only return whether or not an attribute
should be listed. Copying the attribute names into the buffer is moved
to the callers.

Since the result only depends on the dentry and not on the attribute
name, we do not pass the attribute name to list operations.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

authored by

Andreas Gruenbacher and committed by
Al Viro
764a5c6b 1046cb11

+113 -335
+10 -5
fs/ext2/xattr.c
··· 292 292 const struct xattr_handler *handler = 293 293 ext2_xattr_handler(entry->e_name_index); 294 294 295 - if (handler) { 296 - size_t size = handler->list(handler, dentry, buffer, 297 - rest, entry->e_name, 298 - entry->e_name_len); 295 + if (handler && (!handler->list || handler->list(dentry))) { 296 + const char *prefix = handler->prefix ?: handler->name; 297 + size_t prefix_len = strlen(prefix); 298 + size_t size = prefix_len + entry->e_name_len + 1; 299 + 299 300 if (buffer) { 300 301 if (size > rest) { 301 302 error = -ERANGE; 302 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 311 rest -= size; 307 312 }
-17
fs/ext2/xattr_security.c
··· 7 7 #include <linux/security.h> 8 8 #include "xattr.h" 9 9 10 - static size_t 11 - ext2_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 - 26 10 static int 27 11 ext2_xattr_security_get(const struct xattr_handler *handler, 28 12 struct dentry *dentry, const char *name, ··· 51 67 52 68 const struct xattr_handler ext2_xattr_security_handler = { 53 69 .prefix = XATTR_SECURITY_PREFIX, 54 - .list = ext2_xattr_security_list, 55 70 .get = ext2_xattr_security_get, 56 71 .set = ext2_xattr_security_set, 57 72 };
+3 -16
fs/ext2/xattr_trusted.c
··· 8 8 #include "ext2.h" 9 9 #include "xattr.h" 10 10 11 - static size_t 12 - ext2_xattr_trusted_list(const struct xattr_handler *handler, 13 - struct dentry *dentry, char *list, size_t list_size, 14 - const char *name, size_t name_len) 11 + static bool 12 + ext2_xattr_trusted_list(struct dentry *dentry) 15 13 { 16 - const int prefix_len = XATTR_TRUSTED_PREFIX_LEN; 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; 14 + return capable(CAP_SYS_ADMIN); 28 15 } 29 16 30 17 static int
+3 -16
fs/ext2/xattr_user.c
··· 10 10 #include "ext2.h" 11 11 #include "xattr.h" 12 12 13 - static size_t 14 - ext2_xattr_user_list(const struct xattr_handler *handler, 15 - struct dentry *dentry, char *list, size_t list_size, 16 - const char *name, size_t name_len) 13 + static bool 14 + ext2_xattr_user_list(struct dentry *dentry) 17 15 { 18 - const size_t prefix_len = XATTR_USER_PREFIX_LEN; 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; 16 + return test_opt(dentry->d_sb, XATTR_USER); 30 17 } 31 18 32 19 static int
+11 -6
fs/ext4/xattr.c
··· 404 404 const struct xattr_handler *handler = 405 405 ext4_xattr_handler(entry->e_name_index); 406 406 407 - if (handler) { 408 - size_t size = handler->list(handler, dentry, buffer, 409 - rest, entry->e_name, 410 - entry->e_name_len); 407 + if (handler && (!handler->list || handler->list(dentry))) { 408 + const char *prefix = handler->prefix ?: handler->name; 409 + size_t prefix_len = strlen(prefix); 410 + size_t size = prefix_len + entry->e_name_len + 1; 411 + 411 412 if (buffer) { 412 413 if (size > rest) 413 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 421 rest -= size; 417 422 } 418 423 } 419 - return buffer_size - rest; 424 + return buffer_size - rest; /* total size */ 420 425 } 421 426 422 427 static int
-18
fs/ext4/xattr_security.c
··· 11 11 #include "ext4.h" 12 12 #include "xattr.h" 13 13 14 - static size_t 15 - ext4_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 - 31 14 static int 32 15 ext4_xattr_security_get(const struct xattr_handler *handler, 33 16 struct dentry *dentry, const char *name, ··· 58 75 59 76 const struct xattr_handler ext4_xattr_security_handler = { 60 77 .prefix = XATTR_SECURITY_PREFIX, 61 - .list = ext4_xattr_security_list, 62 78 .get = ext4_xattr_security_get, 63 79 .set = ext4_xattr_security_set, 64 80 };
+3 -16
fs/ext4/xattr_trusted.c
··· 12 12 #include "ext4.h" 13 13 #include "xattr.h" 14 14 15 - static size_t 16 - ext4_xattr_trusted_list(const struct xattr_handler *handler, 17 - struct dentry *dentry, char *list, size_t list_size, 18 - const char *name, size_t name_len) 15 + static bool 16 + ext4_xattr_trusted_list(struct dentry *dentry) 19 17 { 20 - const size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN; 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; 18 + return capable(CAP_SYS_ADMIN); 32 19 } 33 20 34 21 static int
+3 -16
fs/ext4/xattr_user.c
··· 11 11 #include "ext4.h" 12 12 #include "xattr.h" 13 13 14 - static size_t 15 - ext4_xattr_user_list(const struct xattr_handler *handler, 16 - struct dentry *dentry, char *list, size_t list_size, 17 - const char *name, size_t name_len) 14 + static bool 15 + ext4_xattr_user_list(struct dentry *dentry) 18 16 { 19 - const size_t prefix_len = XATTR_USER_PREFIX_LEN; 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; 17 + return test_opt(dentry->d_sb, XATTR_USER); 31 18 } 32 19 33 20 static int
+26 -56
fs/f2fs/xattr.c
··· 25 25 #include "f2fs.h" 26 26 #include "xattr.h" 27 27 28 - static 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 - 62 28 static int f2fs_xattr_generic_get(const struct xattr_handler *handler, 63 29 struct dentry *dentry, const char *name, void *buffer, 64 30 size_t size) ··· 73 107 value, size, NULL, flags); 74 108 } 75 109 76 - static size_t f2fs_xattr_advise_list(const struct xattr_handler *handler, 77 - struct dentry *dentry, char *list, size_t list_size, 78 - const char *name, size_t len) 110 + static bool f2fs_xattr_user_list(struct dentry *dentry) 79 111 { 80 - const char *xname = F2FS_SYSTEM_ADVISE_NAME; 81 - size_t size; 112 + struct f2fs_sb_info *sbi = F2FS_SB(dentry->d_sb); 82 113 83 - size = strlen(xname) + 1; 84 - if (list && size <= list_size) 85 - memcpy(list, xname, size); 86 - return size; 114 + return test_opt(sbi, XATTR_USER); 115 + } 116 + 117 + static bool f2fs_xattr_trusted_list(struct dentry *dentry) 118 + { 119 + return capable(CAP_SYS_ADMIN); 87 120 } 88 121 89 122 static int f2fs_xattr_advise_get(const struct xattr_handler *handler, ··· 140 175 const struct xattr_handler f2fs_xattr_user_handler = { 141 176 .prefix = XATTR_USER_PREFIX, 142 177 .flags = F2FS_XATTR_INDEX_USER, 143 - .list = f2fs_xattr_generic_list, 178 + .list = f2fs_xattr_user_list, 144 179 .get = f2fs_xattr_generic_get, 145 180 .set = f2fs_xattr_generic_set, 146 181 }; ··· 148 183 const struct xattr_handler f2fs_xattr_trusted_handler = { 149 184 .prefix = XATTR_TRUSTED_PREFIX, 150 185 .flags = F2FS_XATTR_INDEX_TRUSTED, 151 - .list = f2fs_xattr_generic_list, 186 + .list = f2fs_xattr_trusted_list, 152 187 .get = f2fs_xattr_generic_get, 153 188 .set = f2fs_xattr_generic_set, 154 189 }; ··· 156 191 const struct xattr_handler f2fs_xattr_advise_handler = { 157 192 .name = F2FS_SYSTEM_ADVISE_NAME, 158 193 .flags = F2FS_XATTR_INDEX_ADVISE, 159 - .list = f2fs_xattr_advise_list, 160 194 .get = f2fs_xattr_advise_get, 161 195 .set = f2fs_xattr_advise_set, 162 196 }; ··· 163 199 const struct xattr_handler f2fs_xattr_security_handler = { 164 200 .prefix = XATTR_SECURITY_PREFIX, 165 201 .flags = F2FS_XATTR_INDEX_SECURITY, 166 - .list = f2fs_xattr_generic_list, 167 202 .get = f2fs_xattr_generic_get, 168 203 .set = f2fs_xattr_generic_set, 169 204 }; ··· 410 447 list_for_each_xattr(entry, base_addr) { 411 448 const struct xattr_handler *handler = 412 449 f2fs_xattr_handler(entry->e_name_index); 450 + const char *prefix; 451 + size_t prefix_len; 413 452 size_t size; 414 453 415 - if (!handler) 454 + if (!handler || (handler->list && !handler->list(dentry))) 416 455 continue; 417 456 418 - size = handler->list(handler, dentry, buffer, rest, 419 - entry->e_name, entry->e_name_len); 420 - if (buffer && size > rest) { 421 - error = -ERANGE; 422 - goto cleanup; 457 + prefix = handler->prefix ?: handler->name; 458 + prefix_len = strlen(prefix); 459 + size = prefix_len + entry->e_name_len + 1; 460 + if (buffer) { 461 + if (size > rest) { 462 + error = -ERANGE; 463 + goto cleanup; 464 + } 465 + memcpy(buffer, prefix, prefix_len); 466 + buffer += prefix_len; 467 + memcpy(buffer, entry->e_name, entry->e_name_len); 468 + buffer += entry->e_name_len; 469 + *buffer++ = 0; 423 470 } 424 - 425 - if (buffer) 426 - buffer += size; 427 471 rest -= size; 428 472 } 429 473 error = buffer_size - rest;
-16
fs/jffs2/security.c
··· 64 64 name, buffer, size, flags); 65 65 } 66 66 67 - static 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 - 82 67 const struct xattr_handler jffs2_security_xattr_handler = { 83 68 .prefix = XATTR_SECURITY_PREFIX, 84 - .list = jffs2_security_listxattr, 85 69 .set = jffs2_security_setxattr, 86 70 .get = jffs2_security_getxattr 87 71 };
+16 -10
fs/jffs2/xattr.c
··· 967 967 struct jffs2_xattr_ref *ref, **pref; 968 968 struct jffs2_xattr_datum *xd; 969 969 const struct xattr_handler *xhandle; 970 - ssize_t len, rc; 970 + const char *prefix; 971 + ssize_t prefix_len, len, rc; 971 972 int retry = 0; 972 973 973 974 rc = check_xattr_ref_inode(c, ic); ··· 999 998 } 1000 999 } 1001 1000 xhandle = xprefix_to_handler(xd->xprefix); 1002 - if (!xhandle) 1001 + if (!xhandle || (xhandle->list && !xhandle->list(dentry))) 1003 1002 continue; 1003 + prefix = xhandle->prefix ?: xhandle->name; 1004 + prefix_len = strlen(prefix); 1005 + rc = prefix_len + xd->name_len + 1; 1006 + 1004 1007 if (buffer) { 1005 - rc = xhandle->list(xhandle, dentry, buffer + len, 1006 - size - len, xd->xname, 1007 - xd->name_len); 1008 - } else { 1009 - rc = xhandle->list(xhandle, dentry, NULL, 0, 1010 - xd->xname, xd->name_len); 1008 + if (rc > size - len) { 1009 + rc = -ERANGE; 1010 + goto out; 1011 + } 1012 + memcpy(buffer, prefix, prefix_len); 1013 + buffer += prefix_len; 1014 + memcpy(buffer, xd->xname, xd->name_len); 1015 + buffer += xd->name_len; 1016 + *buffer++ = 0; 1011 1017 } 1012 - if (rc < 0) 1013 - goto out; 1014 1018 len += rc; 1015 1019 } 1016 1020 rc = len;
+2 -15
fs/jffs2/xattr_trusted.c
··· 32 32 name, buffer, size, flags); 33 33 } 34 34 35 - static size_t jffs2_trusted_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) 35 + static bool jffs2_trusted_listxattr(struct dentry *dentry) 39 36 { 40 - size_t retlen = XATTR_TRUSTED_PREFIX_LEN + name_len + 1; 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; 37 + return capable(CAP_SYS_ADMIN); 51 38 } 52 39 53 40 const struct xattr_handler jffs2_trusted_xattr_handler = {
-16
fs/jffs2/xattr_user.c
··· 32 32 name, buffer, size, flags); 33 33 } 34 34 35 - static 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 - 50 35 const struct xattr_handler jffs2_user_xattr_handler = { 51 36 .prefix = XATTR_USER_PREFIX, 52 - .list = jffs2_user_listxattr, 53 37 .set = jffs2_user_setxattr, 54 38 .get = jffs2_user_getxattr 55 39 };
+2 -12
fs/nfs/nfs4proc.c
··· 6263 6263 return nfs4_proc_get_acl(d_inode(dentry), buf, buflen); 6264 6264 } 6265 6265 6266 - static size_t nfs4_xattr_list_nfs4_acl(const struct xattr_handler *handler, 6267 - struct dentry *dentry, char *list, 6268 - size_t list_len, const char *name, 6269 - size_t name_len) 6266 + static bool nfs4_xattr_list_nfs4_acl(struct dentry *dentry) 6270 6267 { 6271 - size_t len = sizeof(XATTR_NAME_NFSV4_ACL); 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; 6268 + return nfs4_server_supports_acls(NFS_SERVER(d_inode(dentry))); 6279 6269 } 6280 6270 6281 6271 #ifdef CONFIG_NFS_V4_SECURITY_LABEL
+3 -14
fs/posix_acl.c
··· 823 823 return ret; 824 824 } 825 825 826 - static size_t 827 - posix_acl_xattr_list(const struct xattr_handler *handler, 828 - struct dentry *dentry, char *list, size_t list_size, 829 - const char *name, size_t name_len) 826 + static bool 827 + posix_acl_xattr_list(struct dentry *dentry) 830 828 { 831 - const char *xname = handler->name; 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; 829 + return IS_POSIXACL(d_backing_inode(dentry)); 841 830 } 842 831 843 832 const struct xattr_handler posix_acl_access_xattr_handler = {
+5 -8
fs/reiserfs/xattr.c
··· 840 840 841 841 handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr, 842 842 name); 843 - if (!handler) /* Unsupported xattr name */ 843 + if (!handler /* Unsupported xattr name */ || 844 + (handler->list && !handler->list(b->dentry))) 844 845 return 0; 846 + size = namelen + 1; 845 847 if (b->buf) { 846 - size = handler->list(handler, b->dentry, 847 - b->buf + b->pos, b->size, name, 848 - namelen); 849 848 if (size > b->size) 850 849 return -ERANGE; 851 - } else { 852 - size = handler->list(handler, b->dentry, 853 - NULL, 0, name, namelen); 850 + memcpy(b->buf + b->pos, name, namelen); 851 + b->buf[b->pos + namelen] = 0; 854 852 } 855 - 856 853 b->pos += size; 857 854 } 858 855 return 0;
+2 -14
fs/reiserfs/xattr_security.c
··· 34 34 return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); 35 35 } 36 36 37 - static size_t security_list(const struct xattr_handler *handler, 38 - struct dentry *dentry, char *list, size_t list_len, 39 - const char *name, size_t namelen) 37 + static bool security_list(struct dentry *dentry) 40 38 { 41 - const size_t len = namelen + 1; 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; 39 + return !IS_PRIVATE(d_inode(dentry)); 52 40 } 53 41 54 42 /* Initializes the security context for a new inode and returns the number
+2 -13
fs/reiserfs/xattr_trusted.c
··· 33 33 return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); 34 34 } 35 35 36 - static size_t trusted_list(const struct xattr_handler *handler, 37 - struct dentry *dentry, char *list, size_t list_size, 38 - const char *name, size_t name_len) 36 + static bool trusted_list(struct dentry *dentry) 39 37 { 40 - const size_t len = name_len + 1; 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; 38 + return capable(CAP_SYS_ADMIN) && !IS_PRIVATE(d_inode(dentry)); 50 39 } 51 40 52 41 const struct xattr_handler reiserfs_xattr_trusted_handler = {
+2 -12
fs/reiserfs/xattr_user.c
··· 30 30 return reiserfs_xattr_set(d_inode(dentry), name, buffer, size, flags); 31 31 } 32 32 33 - static size_t user_list(const struct xattr_handler *handler, 34 - struct dentry *dentry, char *list, size_t list_size, 35 - const char *name, size_t name_len) 33 + static bool user_list(struct dentry *dentry) 36 34 { 37 - const size_t len = name_len + 1; 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; 35 + return reiserfs_xattrs_user(dentry->d_sb); 46 36 } 47 37 48 38 const struct xattr_handler reiserfs_xattr_user_handler = {
+8 -27
fs/squashfs/xattr.c
··· 58 58 struct squashfs_xattr_entry entry; 59 59 struct squashfs_xattr_val val; 60 60 const struct xattr_handler *handler; 61 - int name_size, prefix_size = 0; 61 + int name_size; 62 62 63 63 err = squashfs_read_metadata(sb, &entry, &start, &offset, 64 64 sizeof(entry)); ··· 67 67 68 68 name_size = le16_to_cpu(entry.size); 69 69 handler = squashfs_xattr_handler(le16_to_cpu(entry.type)); 70 - if (handler) 71 - prefix_size = handler->list(handler, d, buffer, rest, 72 - NULL, name_size); 73 - if (prefix_size) { 70 + if (handler && (!handler->list || handler->list(d))) { 71 + const char *prefix = handler->prefix ?: handler->name; 72 + size_t prefix_size = strlen(prefix); 73 + 74 74 if (buffer) { 75 75 if (prefix_size + name_size + 1 > rest) { 76 76 err = -ERANGE; 77 77 goto failed; 78 78 } 79 + memcpy(buffer, prefix, prefix_size); 79 80 buffer += prefix_size; 80 81 } 81 82 err = squashfs_read_metadata(sb, buffer, &start, ··· 213 212 } 214 213 215 214 216 - static size_t squashfs_xattr_handler_list(const struct xattr_handler *handler, 217 - struct dentry *d, char *list, 218 - size_t list_size, const char *name, 219 - size_t name_len) 220 - { 221 - int len = strlen(handler->prefix); 222 - 223 - if (list && len <= list_size) 224 - memcpy(list, handler->prefix, len); 225 - return len; 226 - } 227 - 228 215 static int squashfs_xattr_handler_get(const struct xattr_handler *handler, 229 216 struct dentry *d, const char *name, 230 217 void *buffer, size_t size) ··· 227 238 static const struct xattr_handler squashfs_xattr_user_handler = { 228 239 .prefix = XATTR_USER_PREFIX, 229 240 .flags = SQUASHFS_XATTR_USER, 230 - .list = squashfs_xattr_handler_list, 231 241 .get = squashfs_xattr_handler_get 232 242 }; 233 243 234 244 /* 235 245 * Trusted namespace support 236 246 */ 237 - static size_t squashfs_trusted_xattr_handler_list(const struct xattr_handler *handler, 238 - struct dentry *d, char *list, 239 - size_t list_size, const char *name, 240 - size_t name_len) 247 + static bool squashfs_trusted_xattr_handler_list(struct dentry *d) 241 248 { 242 - if (!capable(CAP_SYS_ADMIN)) 243 - return 0; 244 - return squashfs_xattr_handler_list(handler, d, list, list_size, name, 245 - name_len); 249 + return capable(CAP_SYS_ADMIN); 246 250 } 247 251 248 252 static const struct xattr_handler squashfs_xattr_trusted_handler = { ··· 251 269 static const struct xattr_handler squashfs_xattr_security_handler = { 252 270 .prefix = XATTR_SECURITY_PREFIX, 253 271 .flags = SQUASHFS_XATTR_SECURITY, 254 - .list = squashfs_xattr_handler_list, 255 272 .get = squashfs_xattr_handler_get 256 273 }; 257 274
+11 -9
fs/xattr.c
··· 723 723 724 724 if (!buffer) { 725 725 for_each_xattr_handler(handlers, handler) { 726 - if (!handler->list) 726 + if (!handler->name || 727 + (handler->list && !handler->list(dentry))) 727 728 continue; 728 - size += handler->list(handler, dentry, NULL, 0, 729 - NULL, 0); 729 + size += strlen(handler->name) + 1; 730 730 } 731 731 } else { 732 732 char *buf = buffer; 733 + size_t len; 733 734 734 735 for_each_xattr_handler(handlers, handler) { 735 - if (!handler->list) 736 + if (!handler->name || 737 + (handler->list && !handler->list(dentry))) 736 738 continue; 737 - size = handler->list(handler, dentry, buf, buffer_size, 738 - NULL, 0); 739 - if (size > buffer_size) 739 + len = strlen(handler->name); 740 + if (len + 1 > buffer_size) 740 741 return -ERANGE; 741 - buf += size; 742 - buffer_size -= size; 742 + memcpy(buf, handler->name, len + 1); 743 + buf += len + 1; 744 + buffer_size -= len + 1; 743 745 } 744 746 size = buf - buffer; 745 747 }
+1 -3
include/linux/xattr.h
··· 28 28 const char *name; 29 29 const char *prefix; 30 30 int flags; /* fs private flags */ 31 - size_t (*list)(const struct xattr_handler *, struct dentry *dentry, 32 - char *list, size_t list_size, const char *name, 33 - size_t name_len); 31 + bool (*list)(struct dentry *dentry); 34 32 int (*get)(const struct xattr_handler *, struct dentry *dentry, 35 33 const char *name, void *buffer, size_t size); 36 34 int (*set)(const struct xattr_handler *, struct dentry *dentry,