Skip to content

Commit e499214

Browse files
committed
acl: don't depend on IOP_XATTR
All codepaths that don't want to implement POSIX ACLs should simply not implement the associated inode operations instead of relying on IOP_XATTR. That's the case for all filesystems today. For vfs_listxattr() all filesystems that explicitly turn of xattrs for a given inode all set inode->i_op to a dedicated set of inode operations that doesn't implement ->listxattr(). We can remove the dependency of vfs_listxattr() on IOP_XATTR. Removing this dependency will allow us to decouple POSIX ACLs from IOP_XATTR and they can still be listed even if no other xattr handlers are implemented. Otherwise we would have to implement elaborate schemes to raise IOP_XATTR even if sb->s_xattr is set to NULL. Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
1 parent a1fbb60 commit e499214

2 files changed

Lines changed: 28 additions & 9 deletions

File tree

fs/posix_acl.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,12 +1131,10 @@ int vfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
11311131
if (error)
11321132
goto out_inode_unlock;
11331133

1134-
if (inode->i_opflags & IOP_XATTR)
1134+
if (likely(!is_bad_inode(inode)))
11351135
error = set_posix_acl(idmap, dentry, acl_type, kacl);
1136-
else if (unlikely(is_bad_inode(inode)))
1137-
error = -EIO;
11381136
else
1139-
error = -EOPNOTSUPP;
1137+
error = -EIO;
11401138
if (!error) {
11411139
fsnotify_xattr(dentry);
11421140
evm_inode_post_set_acl(dentry, acl_name, kacl);
@@ -1241,12 +1239,10 @@ int vfs_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry,
12411239
if (error)
12421240
goto out_inode_unlock;
12431241

1244-
if (inode->i_opflags & IOP_XATTR)
1242+
if (likely(!is_bad_inode(inode)))
12451243
error = set_posix_acl(idmap, dentry, acl_type, NULL);
1246-
else if (unlikely(is_bad_inode(inode)))
1247-
error = -EIO;
12481244
else
1249-
error = -EOPNOTSUPP;
1245+
error = -EIO;
12501246
if (!error) {
12511247
fsnotify_xattr(dentry);
12521248
evm_inode_post_remove_acl(idmap, dentry, acl_name);

fs/xattr.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,28 @@ vfs_getxattr(struct mnt_idmap *idmap, struct dentry *dentry,
458458
}
459459
EXPORT_SYMBOL_GPL(vfs_getxattr);
460460

461+
/**
462+
* vfs_listxattr - retrieve \0 separated list of xattr names
463+
* @dentry: the dentry from whose inode the xattr names are retrieved
464+
* @list: buffer to store xattr names into
465+
* @size: size of the buffer
466+
*
467+
* This function returns the names of all xattrs associated with the
468+
* inode of @dentry.
469+
*
470+
* Note, for legacy reasons the vfs_listxattr() function lists POSIX
471+
* ACLs as well. Since POSIX ACLs are decoupled from IOP_XATTR the
472+
* vfs_listxattr() function doesn't check for this flag since a
473+
* filesystem could implement POSIX ACLs without implementing any other
474+
* xattrs.
475+
*
476+
* However, since all codepaths that remove IOP_XATTR also assign of
477+
* inode operations that either don't implement or implement a stub
478+
* ->listxattr() operation.
479+
*
480+
* Return: On success, the size of the buffer that was used. On error a
481+
* negative error code.
482+
*/
461483
ssize_t
462484
vfs_listxattr(struct dentry *dentry, char *list, size_t size)
463485
{
@@ -467,7 +489,8 @@ vfs_listxattr(struct dentry *dentry, char *list, size_t size)
467489
error = security_inode_listxattr(dentry);
468490
if (error)
469491
return error;
470-
if (inode->i_op->listxattr && (inode->i_opflags & IOP_XATTR)) {
492+
493+
if (inode->i_op->listxattr) {
471494
error = inode->i_op->listxattr(dentry, list, size);
472495
} else {
473496
error = security_inode_listsecurity(inode, list, size);

0 commit comments

Comments
 (0)