Skip to content

Commit d0a5b99

Browse files
Andreas GruenbacherAl Viro
authored andcommitted
vfs: Add IOP_XATTR inode operations flag
The IOP_XATTR inode operations flag in inode->i_opflags indicates that the inode has xattr support. The flag is automatically set by new_inode() on filesystems with xattr support (where sb->s_xattr is defined), and cleared otherwise. Filesystems can explicitly clear it for inodes that should not have xattr support. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent b6ba117 commit d0a5b99

File tree

3 files changed

+11
-4
lines changed

3 files changed

+11
-4
lines changed

fs/inode.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
140140
inode->i_fop = &no_open_fops;
141141
inode->__i_nlink = 1;
142142
inode->i_opflags = 0;
143+
if (sb->s_xattr)
144+
inode->i_opflags |= IOP_XATTR;
143145
i_uid_write(inode, 0);
144146
i_gid_write(inode, 0);
145147
atomic_set(&inode->i_writecount, 0);

fs/xattr.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,13 @@ strcmp_prefix(const char *a, const char *a_prefix)
5353
* Find the xattr_handler with the matching prefix.
5454
*/
5555
static const struct xattr_handler *
56-
xattr_resolve_name(const struct xattr_handler **handlers, const char **name)
56+
xattr_resolve_name(struct inode *inode, const char **name)
5757
{
58+
const struct xattr_handler **handlers = inode->i_sb->s_xattr;
5859
const struct xattr_handler *handler;
5960

61+
if (!(inode->i_opflags & IOP_XATTR))
62+
return ERR_PTR(-EOPNOTSUPP);
6063
for_each_xattr_handler(handlers, handler) {
6164
const char *n;
6265

@@ -298,6 +301,7 @@ vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
298301
error = -EOPNOTSUPP;
299302

300303
return error;
304+
301305
}
302306
EXPORT_SYMBOL_GPL(vfs_getxattr);
303307

@@ -700,7 +704,7 @@ generic_getxattr(struct dentry *dentry, struct inode *inode,
700704
{
701705
const struct xattr_handler *handler;
702706

703-
handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
707+
handler = xattr_resolve_name(inode, &name);
704708
if (IS_ERR(handler))
705709
return PTR_ERR(handler);
706710
return handler->get(handler, dentry, inode,
@@ -755,7 +759,7 @@ generic_setxattr(struct dentry *dentry, struct inode *inode, const char *name,
755759

756760
if (size == 0)
757761
value = ""; /* empty EA, do not remove */
758-
handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
762+
handler = xattr_resolve_name(inode, &name);
759763
if (IS_ERR(handler))
760764
return PTR_ERR(handler);
761765
return handler->set(handler, dentry, inode, name, value, size, flags);
@@ -770,7 +774,7 @@ generic_removexattr(struct dentry *dentry, const char *name)
770774
{
771775
const struct xattr_handler *handler;
772776

773-
handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
777+
handler = xattr_resolve_name(d_inode(dentry), &name);
774778
if (IS_ERR(handler))
775779
return PTR_ERR(handler);
776780
return handler->set(handler, dentry, d_inode(dentry), name, NULL,

include/linux/fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,7 @@ is_uncached_acl(struct posix_acl *acl)
591591
#define IOP_FASTPERM 0x0001
592592
#define IOP_LOOKUP 0x0002
593593
#define IOP_NOFOLLOW 0x0004
594+
#define IOP_XATTR 0x0008
594595

595596
/*
596597
* Keep mostly read-only and often accessed (especially for

0 commit comments

Comments
 (0)