summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/posix_acl.c12
-rw-r--r--fs/xattr.c25
2 files changed, 28 insertions, 9 deletions
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index e262c428f869..7fa1b738bbab 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -1131,12 +1131,10 @@ retry_deleg:
if (error)
goto out_inode_unlock;
- if (inode->i_opflags & IOP_XATTR)
+ if (likely(!is_bad_inode(inode)))
error = set_posix_acl(idmap, dentry, acl_type, kacl);
- else if (unlikely(is_bad_inode(inode)))
- error = -EIO;
else
- error = -EOPNOTSUPP;
+ error = -EIO;
if (!error) {
fsnotify_xattr(dentry);
evm_inode_post_set_acl(dentry, acl_name, kacl);
@@ -1241,12 +1239,10 @@ retry_deleg:
if (error)
goto out_inode_unlock;
- if (inode->i_opflags & IOP_XATTR)
+ if (likely(!is_bad_inode(inode)))
error = set_posix_acl(idmap, dentry, acl_type, NULL);
- else if (unlikely(is_bad_inode(inode)))
- error = -EIO;
else
- error = -EOPNOTSUPP;
+ error = -EIO;
if (!error) {
fsnotify_xattr(dentry);
evm_inode_post_remove_acl(idmap, dentry, acl_name);
diff --git a/fs/xattr.c b/fs/xattr.c
index 95bb6b30ab13..fcf67d80d7f9 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -458,6 +458,28 @@ nolsm:
}
EXPORT_SYMBOL_GPL(vfs_getxattr);
+/**
+ * vfs_listxattr - retrieve \0 separated list of xattr names
+ * @dentry: the dentry from whose inode the xattr names are retrieved
+ * @list: buffer to store xattr names into
+ * @size: size of the buffer
+ *
+ * This function returns the names of all xattrs associated with the
+ * inode of @dentry.
+ *
+ * Note, for legacy reasons the vfs_listxattr() function lists POSIX
+ * ACLs as well. Since POSIX ACLs are decoupled from IOP_XATTR the
+ * vfs_listxattr() function doesn't check for this flag since a
+ * filesystem could implement POSIX ACLs without implementing any other
+ * xattrs.
+ *
+ * However, since all codepaths that remove IOP_XATTR also assign of
+ * inode operations that either don't implement or implement a stub
+ * ->listxattr() operation.
+ *
+ * Return: On success, the size of the buffer that was used. On error a
+ * negative error code.
+ */
ssize_t
vfs_listxattr(struct dentry *dentry, char *list, size_t size)
{
@@ -467,7 +489,8 @@ vfs_listxattr(struct dentry *dentry, char *list, size_t size)
error = security_inode_listxattr(dentry);
if (error)
return error;
- if (inode->i_op->listxattr && (inode->i_opflags & IOP_XATTR)) {
+
+ if (inode->i_op->listxattr) {
error = inode->i_op->listxattr(dentry, list, size);
} else {
error = security_inode_listsecurity(inode, list, size);