diff mbox

[RFC,09/11] vfs: Add igetxattr inode operation

Message ID 1440094798-1411-10-git-send-email-agruenba@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Andreas Grünbacher Aug. 20, 2015, 6:19 p.m. UTC
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(-)

Comments

Christoph Hellwig Aug. 21, 2015, 6:48 a.m. UTC | #1
On Thu, Aug 20, 2015 at 08:19:56PM +0200, Andreas Gruenbacher wrote:
> 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.

And this is even worse - we should not have two operations doing the
same thing.
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 6a34a0f..77d6d50 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -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
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 5eb8456..4c9512e 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -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.
 
diff --git a/fs/xattr.c b/fs/xattr.c
index c45db57..e706e6b 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -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);
 }
 
 /*
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 84b783f..dbca464 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -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 *);
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index 0a0539e..9762025 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -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);