Skip to content

Commit f2620f1

Browse files
committed
xattr: simplify listxattr helpers
The generic_listxattr() and simple_xattr_list() helpers list xattrs and contain duplicated code. Add two helpers that both generic_listxattr() and simple_xattr_list() can use. Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Christian Brauner (Microsoft) <[email protected]>
1 parent fe15c26 commit f2620f1

File tree

4 files changed

+66
-56
lines changed

4 files changed

+66
-56
lines changed

fs/posix_acl.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -957,6 +957,31 @@ set_posix_acl(struct mnt_idmap *idmap, struct dentry *dentry,
957957
}
958958
EXPORT_SYMBOL(set_posix_acl);
959959

960+
int posix_acl_listxattr(struct inode *inode, char **buffer,
961+
ssize_t *remaining_size)
962+
{
963+
int err;
964+
965+
if (!IS_POSIXACL(inode))
966+
return 0;
967+
968+
if (inode->i_acl) {
969+
err = xattr_list_one(buffer, remaining_size,
970+
XATTR_NAME_POSIX_ACL_ACCESS);
971+
if (err)
972+
return err;
973+
}
974+
975+
if (inode->i_default_acl) {
976+
err = xattr_list_one(buffer, remaining_size,
977+
XATTR_NAME_POSIX_ACL_DEFAULT);
978+
if (err)
979+
return err;
980+
}
981+
982+
return 0;
983+
}
984+
960985
static bool
961986
posix_acl_xattr_list(struct dentry *dentry)
962987
{

fs/xattr.c

Lines changed: 33 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,21 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
949949
return error;
950950
}
951951

952+
int xattr_list_one(char **buffer, ssize_t *remaining_size, const char *name)
953+
{
954+
size_t len;
955+
956+
len = strlen(name) + 1;
957+
if (*buffer) {
958+
if (*remaining_size < len)
959+
return -ERANGE;
960+
memcpy(*buffer, name, len);
961+
*buffer += len;
962+
}
963+
*remaining_size -= len;
964+
return 0;
965+
}
966+
952967
/*
953968
* Combine the results of the list() operation from every xattr_handler in the
954969
* list.
@@ -957,33 +972,22 @@ ssize_t
957972
generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
958973
{
959974
const struct xattr_handler *handler, **handlers = dentry->d_sb->s_xattr;
960-
unsigned int size = 0;
961-
962-
if (!buffer) {
963-
for_each_xattr_handler(handlers, handler) {
964-
if (!handler->name ||
965-
(handler->list && !handler->list(dentry)))
966-
continue;
967-
size += strlen(handler->name) + 1;
968-
}
969-
} else {
970-
char *buf = buffer;
971-
size_t len;
972-
973-
for_each_xattr_handler(handlers, handler) {
974-
if (!handler->name ||
975-
(handler->list && !handler->list(dentry)))
976-
continue;
977-
len = strlen(handler->name);
978-
if (len + 1 > buffer_size)
979-
return -ERANGE;
980-
memcpy(buf, handler->name, len + 1);
981-
buf += len + 1;
982-
buffer_size -= len + 1;
983-
}
984-
size = buf - buffer;
975+
ssize_t remaining_size = buffer_size;
976+
int err = 0;
977+
978+
err = posix_acl_listxattr(d_inode(dentry), &buffer, &remaining_size);
979+
if (err)
980+
return err;
981+
982+
for_each_xattr_handler(handlers, handler) {
983+
if (!handler->name || (handler->list && !handler->list(dentry)))
984+
continue;
985+
err = xattr_list_one(&buffer, &remaining_size, handler->name);
986+
if (err)
987+
return err;
985988
}
986-
return size;
989+
990+
return err ? err : buffer_size - remaining_size;
987991
}
988992
EXPORT_SYMBOL(generic_listxattr);
989993

@@ -1245,20 +1249,6 @@ static bool xattr_is_trusted(const char *name)
12451249
return !strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN);
12461250
}
12471251

1248-
static int xattr_list_one(char **buffer, ssize_t *remaining_size,
1249-
const char *name)
1250-
{
1251-
size_t len = strlen(name) + 1;
1252-
if (*buffer) {
1253-
if (*remaining_size < len)
1254-
return -ERANGE;
1255-
memcpy(*buffer, name, len);
1256-
*buffer += len;
1257-
}
1258-
*remaining_size -= len;
1259-
return 0;
1260-
}
1261-
12621252
/**
12631253
* simple_xattr_list - list all xattr objects
12641254
* @inode: inode from which to get the xattrs
@@ -1287,22 +1277,9 @@ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
12871277
ssize_t remaining_size = size;
12881278
int err = 0;
12891279

1290-
#ifdef CONFIG_FS_POSIX_ACL
1291-
if (IS_POSIXACL(inode)) {
1292-
if (inode->i_acl) {
1293-
err = xattr_list_one(&buffer, &remaining_size,
1294-
XATTR_NAME_POSIX_ACL_ACCESS);
1295-
if (err)
1296-
return err;
1297-
}
1298-
if (inode->i_default_acl) {
1299-
err = xattr_list_one(&buffer, &remaining_size,
1300-
XATTR_NAME_POSIX_ACL_DEFAULT);
1301-
if (err)
1302-
return err;
1303-
}
1304-
}
1305-
#endif
1280+
err = posix_acl_listxattr(inode, &buffer, &remaining_size);
1281+
if (err)
1282+
return err;
13061283

13071284
read_lock(&xattrs->lock);
13081285
for (rbp = rb_first(&xattrs->rb_root); rbp; rbp = rb_next(rbp)) {

include/linux/posix_acl.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ struct posix_acl *vfs_get_acl(struct mnt_idmap *idmap,
106106
struct dentry *dentry, const char *acl_name);
107107
int vfs_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
108108
const char *acl_name);
109+
int posix_acl_listxattr(struct inode *inode, char **buffer,
110+
ssize_t *remaining_size);
109111
#else
110112
static inline int posix_acl_chmod(struct mnt_idmap *idmap,
111113
struct dentry *dentry, umode_t mode)
@@ -153,6 +155,11 @@ static inline int vfs_remove_acl(struct mnt_idmap *idmap,
153155
{
154156
return -EOPNOTSUPP;
155157
}
158+
static inline int posix_acl_listxattr(struct inode *inode, char **buffer,
159+
ssize_t *remaining_size)
160+
{
161+
return 0;
162+
}
156163
#endif /* CONFIG_FS_POSIX_ACL */
157164

158165
struct posix_acl *get_inode_acl(struct inode *inode, int type);

include/linux/xattr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,5 +109,6 @@ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
109109
char *buffer, size_t size);
110110
void simple_xattr_add(struct simple_xattrs *xattrs,
111111
struct simple_xattr *new_xattr);
112+
int xattr_list_one(char **buffer, ssize_t *remaining_size, const char *name);
112113

113114
#endif /* _LINUX_XATTR_H */

0 commit comments

Comments
 (0)