@@ -58,6 +58,7 @@ prototypes:
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *);
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
+ ssize_t (*igetxattr) (struct inode *, const char *, void *, size_t);
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*removexattr) (struct dentry *, const char *);
@@ -90,6 +91,7 @@ permission: no (may not block if called in rcu-walk mode)
get_acl: no
getattr: no
setxattr: yes
+igetxattr: no
getxattr: no
listxattr: no
removexattr: yes
@@ -357,6 +357,7 @@ struct inode_operations {
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
+ ssize_t (*igetxattr) (struct inode *, const char *, void *, size_t);
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*removexattr) (struct dentry *, const char *);
@@ -473,6 +474,9 @@ otherwise noted.
attribute name. This method is called by getxattr(2) function
call.
+ igetxattr: retrieve the value of an extended attribute name of an
+ inode; otherwise identical to getxattr which takes a dentry.
+
listxattr: called by the VFS to list all extended attributes for a
given file. This method is called by listxattr(2) system call.
@@ -702,14 +702,20 @@ xattr_resolve_name(const struct xattr_handler **handlers, const char **name)
* Find the handler for the prefix and dispatch its get() operation.
*/
ssize_t
-generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size)
+generic_igetxattr(struct inode *inode, const char *name, void *buffer, size_t size)
{
const struct xattr_handler *handler;
- handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
+ handler = xattr_resolve_name(inode->i_sb->s_xattr, &name);
if (!handler)
return -EOPNOTSUPP;
- return handler->get(dentry->d_inode, name, buffer, size, handler);
+ return handler->get(inode, name, buffer, size, handler);
+}
+
+ssize_t
+generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size)
+{
+ return generic_igetxattr(dentry->d_inode, name, buffer, size);
}
/*
@@ -1657,6 +1657,7 @@ struct inode_operations {
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
+ ssize_t (*igetxattr) (struct inode *, const char *, void *, size_t);
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*removexattr) (struct dentry *, const char *);
@@ -44,6 +44,7 @@ int __vfs_setxattr_noperm(struct dentry *, const char *, const void *, size_t, i
int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int);
int vfs_removexattr(struct dentry *, const char *);
+ssize_t generic_igetxattr(struct inode *inode, const char *name, void *buffer, size_t size);
ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size);
ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
int generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags);
Add an igetxattr inode operation that behaves as getxattr but operates on inodes instead of dentries. File systems that support this operation can implement igetxattr for reading xattrs in contexts where a dentry is not available, such as within SELinux inode security checks. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> --- Documentation/filesystems/Locking | 2 ++ Documentation/filesystems/vfs.txt | 4 ++++ fs/xattr.c | 12 +++++++++--- include/linux/fs.h | 1 + include/linux/xattr.h | 1 + 5 files changed, 17 insertions(+), 3 deletions(-)