Commit 5d6c3191 authored by Andreas Gruenbacher's avatar Andreas Gruenbacher Committed by Al Viro
Browse files

xattr: Add __vfs_{get,set,remove}xattr helpers



Right now, various places in the kernel check for the existence of
getxattr, setxattr, and removexattr inode operations and directly call
those operations.  Switch to helper functions and test for the IOP_XATTR
flag instead.

Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
Acked-by: default avatarJames Morris <james.l.morris@oracle.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent f5c24438
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/mount.h>
#include <linux/mount.h>
#include <linux/statfs.h>
#include <linux/statfs.h>
#include <linux/ctype.h>
#include <linux/ctype.h>
#include <linux/xattr.h>
#include "internal.h"
#include "internal.h"


static int cachefiles_daemon_add_cache(struct cachefiles_cache *caches);
static int cachefiles_daemon_add_cache(struct cachefiles_cache *caches);
@@ -126,8 +127,7 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache)
	if (d_is_negative(root) ||
	if (d_is_negative(root) ||
	    !d_backing_inode(root)->i_op->lookup ||
	    !d_backing_inode(root)->i_op->lookup ||
	    !d_backing_inode(root)->i_op->mkdir ||
	    !d_backing_inode(root)->i_op->mkdir ||
	    !d_backing_inode(root)->i_op->setxattr ||
	    !(d_backing_inode(root)->i_opflags & IOP_XATTR) ||
	    !d_backing_inode(root)->i_op->getxattr ||
	    !root->d_sb->s_op->statfs ||
	    !root->d_sb->s_op->statfs ||
	    !root->d_sb->s_op->sync_fs)
	    !root->d_sb->s_op->sync_fs)
		goto error_unsupported;
		goto error_unsupported;
+2 −2
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@
#include <linux/namei.h>
#include <linux/namei.h>
#include <linux/security.h>
#include <linux/security.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/xattr.h>
#include "internal.h"
#include "internal.h"


#define CACHEFILES_KEYBUF_SIZE 512
#define CACHEFILES_KEYBUF_SIZE 512
@@ -799,8 +800,7 @@ struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
	}
	}


	ret = -EPERM;
	ret = -EPERM;
	if (!d_backing_inode(subdir)->i_op->setxattr ||
	if (!(d_backing_inode(subdir)->i_opflags & IOP_XATTR) ||
	    !d_backing_inode(subdir)->i_op->getxattr ||
	    !d_backing_inode(subdir)->i_op->lookup ||
	    !d_backing_inode(subdir)->i_op->lookup ||
	    !d_backing_inode(subdir)->i_op->mkdir ||
	    !d_backing_inode(subdir)->i_op->mkdir ||
	    !d_backing_inode(subdir)->i_op->create ||
	    !d_backing_inode(subdir)->i_op->create ||
+8 −10
Original line number Original line Diff line number Diff line
@@ -1005,15 +1005,14 @@ ecryptfs_setxattr(struct dentry *dentry, struct inode *inode,
		  const char *name, const void *value,
		  const char *name, const void *value,
		  size_t size, int flags)
		  size_t size, int flags)
{
{
	int rc = 0;
	int rc;
	struct dentry *lower_dentry;
	struct dentry *lower_dentry;


	lower_dentry = ecryptfs_dentry_to_lower(dentry);
	lower_dentry = ecryptfs_dentry_to_lower(dentry);
	if (!d_inode(lower_dentry)->i_op->setxattr) {
	if (!(d_inode(lower_dentry)->i_opflags & IOP_XATTR)) {
		rc = -EOPNOTSUPP;
		rc = -EOPNOTSUPP;
		goto out;
		goto out;
	}
	}

	rc = vfs_setxattr(lower_dentry, name, value, size, flags);
	rc = vfs_setxattr(lower_dentry, name, value, size, flags);
	if (!rc && inode)
	if (!rc && inode)
		fsstack_copy_attr_all(inode, d_inode(lower_dentry));
		fsstack_copy_attr_all(inode, d_inode(lower_dentry));
@@ -1025,15 +1024,14 @@ ssize_t
ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode,
ecryptfs_getxattr_lower(struct dentry *lower_dentry, struct inode *lower_inode,
			const char *name, void *value, size_t size)
			const char *name, void *value, size_t size)
{
{
	int rc = 0;
	int rc;


	if (!lower_inode->i_op->getxattr) {
	if (!(lower_inode->i_opflags & IOP_XATTR)) {
		rc = -EOPNOTSUPP;
		rc = -EOPNOTSUPP;
		goto out;
		goto out;
	}
	}
	inode_lock(lower_inode);
	inode_lock(lower_inode);
	rc = lower_inode->i_op->getxattr(lower_dentry, lower_inode,
	rc = __vfs_getxattr(lower_dentry, lower_inode, name, value, size);
					 name, value, size);
	inode_unlock(lower_inode);
	inode_unlock(lower_inode);
out:
out:
	return rc;
	return rc;
@@ -1069,18 +1067,18 @@ ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size)
static int ecryptfs_removexattr(struct dentry *dentry, struct inode *inode,
static int ecryptfs_removexattr(struct dentry *dentry, struct inode *inode,
				const char *name)
				const char *name)
{
{
	int rc = 0;
	int rc;
	struct dentry *lower_dentry;
	struct dentry *lower_dentry;
	struct inode *lower_inode;
	struct inode *lower_inode;


	lower_dentry = ecryptfs_dentry_to_lower(dentry);
	lower_dentry = ecryptfs_dentry_to_lower(dentry);
	lower_inode = ecryptfs_inode_to_lower(inode);
	lower_inode = ecryptfs_inode_to_lower(inode);
	if (!lower_inode->i_op->removexattr) {
	if (!(lower_inode->i_opflags & IOP_XATTR)) {
		rc = -EOPNOTSUPP;
		rc = -EOPNOTSUPP;
		goto out;
		goto out;
	}
	}
	inode_lock(lower_inode);
	inode_lock(lower_inode);
	rc = lower_inode->i_op->removexattr(lower_dentry, name);
	rc = __vfs_removexattr(lower_dentry, name);
	inode_unlock(lower_inode);
	inode_unlock(lower_inode);
out:
out:
	return rc;
	return rc;
+6 −7
Original line number Original line Diff line number Diff line
@@ -32,6 +32,7 @@
#include <linux/file.h>
#include <linux/file.h>
#include <linux/scatterlist.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/xattr.h>
#include <asm/unaligned.h>
#include <asm/unaligned.h>
#include "ecryptfs_kernel.h"
#include "ecryptfs_kernel.h"


@@ -422,7 +423,7 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
	struct inode *lower_inode = d_inode(lower_dentry);
	struct inode *lower_inode = d_inode(lower_dentry);
	int rc;
	int rc;


	if (!lower_inode->i_op->getxattr || !lower_inode->i_op->setxattr) {
	if (!(lower_inode->i_opflags & IOP_XATTR)) {
		printk(KERN_WARNING
		printk(KERN_WARNING
		       "No support for setting xattr in lower filesystem\n");
		       "No support for setting xattr in lower filesystem\n");
		rc = -ENOSYS;
		rc = -ENOSYS;
@@ -436,14 +437,12 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
		goto out;
		goto out;
	}
	}
	inode_lock(lower_inode);
	inode_lock(lower_inode);
	size = lower_inode->i_op->getxattr(lower_dentry, lower_inode,
	size = __vfs_getxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME,
					   ECRYPTFS_XATTR_NAME,
			      xattr_virt, PAGE_SIZE);
			      xattr_virt, PAGE_SIZE);
	if (size < 0)
	if (size < 0)
		size = 8;
		size = 8;
	put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt);
	put_unaligned_be64(i_size_read(ecryptfs_inode), xattr_virt);
	rc = lower_inode->i_op->setxattr(lower_dentry, lower_inode,
	rc = __vfs_setxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME,
					 ECRYPTFS_XATTR_NAME,
			    xattr_virt, size, 0);
			    xattr_virt, size, 0);
	inode_unlock(lower_inode);
	inode_unlock(lower_inode);
	if (rc)
	if (rc)
+2 −2
Original line number Original line Diff line number Diff line
@@ -58,8 +58,8 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new)
	char *buf, *name, *value = NULL;
	char *buf, *name, *value = NULL;
	int uninitialized_var(error);
	int uninitialized_var(error);


	if (!old->d_inode->i_op->getxattr ||
	if (!(old->d_inode->i_opflags & IOP_XATTR) ||
	    !new->d_inode->i_op->getxattr)
	    !(new->d_inode->i_opflags & IOP_XATTR))
		return 0;
		return 0;


	list_size = vfs_listxattr(old, NULL, 0);
	list_size = vfs_listxattr(old, NULL, 0);
Loading