diff options
39 files changed, 533 insertions, 815 deletions
| diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 361604244271..52cbe47022bf 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c @@ -73,13 +73,13 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)  	return acl;  } -static int btrfs_xattr_get_acl(struct inode *inode, int type, -			       void *value, size_t size) +static int btrfs_xattr_acl_get(struct dentry *dentry, const char *name, +		void *value, size_t size, int type)  {  	struct posix_acl *acl;  	int ret = 0; -	acl = btrfs_get_acl(inode, type); +	acl = btrfs_get_acl(dentry->d_inode, type);  	if (IS_ERR(acl))  		return PTR_ERR(acl); @@ -151,8 +151,8 @@ out:  	return ret;  } -static int btrfs_xattr_set_acl(struct inode *inode, int type, -			       const void *value, size_t size) +static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int type)  {  	int ret = 0;  	struct posix_acl *acl = NULL; @@ -167,38 +167,13 @@ static int btrfs_xattr_set_acl(struct inode *inode, int type,  		}  	} -	ret = btrfs_set_acl(inode, acl, type); +	ret = btrfs_set_acl(dentry->d_inode, acl, type);  	posix_acl_release(acl);  	return ret;  } - -static int btrfs_xattr_acl_access_get(struct inode *inode, const char *name, -				      void *value, size_t size) -{ -	return btrfs_xattr_get_acl(inode, ACL_TYPE_ACCESS, value, size); -} - -static int btrfs_xattr_acl_access_set(struct inode *inode, const char *name, -				      const void *value, size_t size, int flags) -{ -	return btrfs_xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size); -} - -static int btrfs_xattr_acl_default_get(struct inode *inode, const char *name, -				       void *value, size_t size) -{ -	return btrfs_xattr_get_acl(inode, ACL_TYPE_DEFAULT, value, size); -} - -static int btrfs_xattr_acl_default_set(struct inode *inode, const char *name, -			       const void *value, size_t size, int flags) -{ -	return btrfs_xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); -} -  int btrfs_check_acl(struct inode *inode, int mask)  {  	struct posix_acl *acl; @@ -303,14 +278,16 @@ int btrfs_acl_chmod(struct inode *inode)  struct xattr_handler btrfs_xattr_acl_default_handler = {  	.prefix = POSIX_ACL_XATTR_DEFAULT, -	.get	= btrfs_xattr_acl_default_get, -	.set	= btrfs_xattr_acl_default_set, +	.flags	= ACL_TYPE_DEFAULT, +	.get	= btrfs_xattr_acl_get, +	.set	= btrfs_xattr_acl_set,  };  struct xattr_handler btrfs_xattr_acl_access_handler = {  	.prefix = POSIX_ACL_XATTR_ACCESS, -	.get	= btrfs_xattr_acl_access_get, -	.set	= btrfs_xattr_acl_access_set, +	.flags	= ACL_TYPE_ACCESS, +	.get	= btrfs_xattr_acl_get, +	.set	= btrfs_xattr_acl_set,  };  #else /* CONFIG_BTRFS_FS_POSIX_ACL */ diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index a63d44256a70..a99e54318c3d 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -339,12 +339,12 @@ ext2_acl_chmod(struct inode *inode)   * Extended attribut handlers   */  static size_t -ext2_xattr_list_acl_access(struct inode *inode, char *list, size_t list_size, -			   const char *name, size_t name_len) +ext2_xattr_list_acl_access(struct dentry *dentry, char *list, size_t list_size, +			   const char *name, size_t name_len, int type)  {  	const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS); -	if (!test_opt(inode->i_sb, POSIX_ACL)) +	if (!test_opt(dentry->d_sb, POSIX_ACL))  		return 0;  	if (list && size <= list_size)  		memcpy(list, POSIX_ACL_XATTR_ACCESS, size); @@ -352,12 +352,12 @@ ext2_xattr_list_acl_access(struct inode *inode, char *list, size_t list_size,  }  static size_t -ext2_xattr_list_acl_default(struct inode *inode, char *list, size_t list_size, -			    const char *name, size_t name_len) +ext2_xattr_list_acl_default(struct dentry *dentry, char *list, size_t list_size, +			    const char *name, size_t name_len, int type)  {  	const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT); -	if (!test_opt(inode->i_sb, POSIX_ACL)) +	if (!test_opt(dentry->d_sb, POSIX_ACL))  		return 0;  	if (list && size <= list_size)  		memcpy(list, POSIX_ACL_XATTR_DEFAULT, size); @@ -365,15 +365,18 @@ ext2_xattr_list_acl_default(struct inode *inode, char *list, size_t list_size,  }  static int -ext2_xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size) +ext2_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer, +		   size_t size, int type)  {  	struct posix_acl *acl;  	int error; -	if (!test_opt(inode->i_sb, POSIX_ACL)) +	if (strcmp(name, "") != 0) +		return -EINVAL; +	if (!test_opt(dentry->d_sb, POSIX_ACL))  		return -EOPNOTSUPP; -	acl = ext2_get_acl(inode, type); +	acl = ext2_get_acl(dentry->d_inode, type);  	if (IS_ERR(acl))  		return PTR_ERR(acl);  	if (acl == NULL) @@ -385,33 +388,17 @@ ext2_xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size)  }  static int -ext2_xattr_get_acl_access(struct inode *inode, const char *name, -			  void *buffer, size_t size) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return ext2_xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size); -} - -static int -ext2_xattr_get_acl_default(struct inode *inode, const char *name, -			   void *buffer, size_t size) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return ext2_xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size); -} - -static int -ext2_xattr_set_acl(struct inode *inode, int type, const void *value, -		   size_t size) +ext2_xattr_set_acl(struct dentry *dentry, const char *name, const void *value, +		   size_t size, int flags, int type)  {  	struct posix_acl *acl;  	int error; -	if (!test_opt(inode->i_sb, POSIX_ACL)) +	if (strcmp(name, "") != 0) +		return -EINVAL; +	if (!test_opt(dentry->d_sb, POSIX_ACL))  		return -EOPNOTSUPP; -	if (!is_owner_or_cap(inode)) +	if (!is_owner_or_cap(dentry->d_inode))  		return -EPERM;  	if (value) { @@ -426,41 +413,25 @@ ext2_xattr_set_acl(struct inode *inode, int type, const void *value,  	} else  		acl = NULL; -	error = ext2_set_acl(inode, type, acl); +	error = ext2_set_acl(dentry->d_inode, type, acl);  release_and_out:  	posix_acl_release(acl);  	return error;  } -static int -ext2_xattr_set_acl_access(struct inode *inode, const char *name, -			  const void *value, size_t size, int flags) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return ext2_xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size); -} - -static int -ext2_xattr_set_acl_default(struct inode *inode, const char *name, -			   const void *value, size_t size, int flags) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return ext2_xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); -} -  struct xattr_handler ext2_xattr_acl_access_handler = {  	.prefix	= POSIX_ACL_XATTR_ACCESS, +	.flags	= ACL_TYPE_ACCESS,  	.list	= ext2_xattr_list_acl_access, -	.get	= ext2_xattr_get_acl_access, -	.set	= ext2_xattr_set_acl_access, +	.get	= ext2_xattr_get_acl, +	.set	= ext2_xattr_set_acl,  };  struct xattr_handler ext2_xattr_acl_default_handler = {  	.prefix	= POSIX_ACL_XATTR_DEFAULT, +	.flags	= ACL_TYPE_DEFAULT,  	.list	= ext2_xattr_list_acl_default, -	.get	= ext2_xattr_get_acl_default, -	.set	= ext2_xattr_set_acl_default, +	.get	= ext2_xattr_get_acl, +	.set	= ext2_xattr_set_acl,  }; diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 7913531ec6d5..904f00642f84 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c @@ -60,6 +60,7 @@  #include <linux/mbcache.h>  #include <linux/quotaops.h>  #include <linux/rwsem.h> +#include <linux/security.h>  #include "ext2.h"  #include "xattr.h"  #include "acl.h" @@ -249,8 +250,9 @@ cleanup:   * used / required on success.   */  static int -ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) +ext2_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)  { +	struct inode *inode = dentry->d_inode;  	struct buffer_head *bh = NULL;  	struct ext2_xattr_entry *entry;  	char *end; @@ -300,9 +302,10 @@ bad_block:	ext2_error(inode->i_sb, "ext2_xattr_list",  			ext2_xattr_handler(entry->e_name_index);  		if (handler) { -			size_t size = handler->list(inode, buffer, rest, +			size_t size = handler->list(dentry, buffer, rest,  						    entry->e_name, -						    entry->e_name_len); +						    entry->e_name_len, +						    handler->flags);  			if (buffer) {  				if (size > rest) {  					error = -ERANGE; @@ -330,7 +333,7 @@ cleanup:  ssize_t  ext2_listxattr(struct dentry *dentry, char *buffer, size_t size)  { -	return ext2_xattr_list(dentry->d_inode, buffer, size); +	return ext2_xattr_list(dentry, buffer, size);  }  /* diff --git a/fs/ext2/xattr_security.c b/fs/ext2/xattr_security.c index 70c0dbdcdcb7..c8155845ac05 100644 --- a/fs/ext2/xattr_security.c +++ b/fs/ext2/xattr_security.c @@ -11,8 +11,8 @@  #include "xattr.h"  static size_t -ext2_xattr_security_list(struct inode *inode, char *list, size_t list_size, -			 const char *name, size_t name_len) +ext2_xattr_security_list(struct dentry *dentry, char *list, size_t list_size, +			 const char *name, size_t name_len, int type)  {  	const int prefix_len = XATTR_SECURITY_PREFIX_LEN;  	const size_t total_len = prefix_len + name_len + 1; @@ -26,22 +26,22 @@ ext2_xattr_security_list(struct inode *inode, char *list, size_t list_size,  }  static int -ext2_xattr_security_get(struct inode *inode, const char *name, -		       void *buffer, size_t size) +ext2_xattr_security_get(struct dentry *dentry, const char *name, +		       void *buffer, size_t size, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return ext2_xattr_get(inode, EXT2_XATTR_INDEX_SECURITY, name, +	return ext2_xattr_get(dentry->d_inode, EXT2_XATTR_INDEX_SECURITY, name,  			      buffer, size);  }  static int -ext2_xattr_security_set(struct inode *inode, const char *name, -		       const void *value, size_t size, int flags) +ext2_xattr_security_set(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return ext2_xattr_set(inode, EXT2_XATTR_INDEX_SECURITY, name, +	return ext2_xattr_set(dentry->d_inode, EXT2_XATTR_INDEX_SECURITY, name,  			      value, size, flags);  } diff --git a/fs/ext2/xattr_trusted.c b/fs/ext2/xattr_trusted.c index e8219f8eae9f..2a26d71f4771 100644 --- a/fs/ext2/xattr_trusted.c +++ b/fs/ext2/xattr_trusted.c @@ -13,8 +13,8 @@  #include "xattr.h"  static size_t -ext2_xattr_trusted_list(struct inode *inode, char *list, size_t list_size, -			const char *name, size_t name_len) +ext2_xattr_trusted_list(struct dentry *dentry, char *list, size_t list_size, +		const char *name, size_t name_len, int type)  {  	const int prefix_len = XATTR_TRUSTED_PREFIX_LEN;  	const size_t total_len = prefix_len + name_len + 1; @@ -31,22 +31,22 @@ ext2_xattr_trusted_list(struct inode *inode, char *list, size_t list_size,  }  static int -ext2_xattr_trusted_get(struct inode *inode, const char *name, -		       void *buffer, size_t size) +ext2_xattr_trusted_get(struct dentry *dentry, const char *name, +		void *buffer, size_t size, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return ext2_xattr_get(inode, EXT2_XATTR_INDEX_TRUSTED, name, +	return ext2_xattr_get(dentry->d_inode, EXT2_XATTR_INDEX_TRUSTED, name,  			      buffer, size);  }  static int -ext2_xattr_trusted_set(struct inode *inode, const char *name, -		       const void *value, size_t size, int flags) +ext2_xattr_trusted_set(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return ext2_xattr_set(inode, EXT2_XATTR_INDEX_TRUSTED, name, +	return ext2_xattr_set(dentry->d_inode, EXT2_XATTR_INDEX_TRUSTED, name,  			      value, size, flags);  } diff --git a/fs/ext2/xattr_user.c b/fs/ext2/xattr_user.c index 92495d28c62f..3f6caf3684b4 100644 --- a/fs/ext2/xattr_user.c +++ b/fs/ext2/xattr_user.c @@ -12,13 +12,13 @@  #include "xattr.h"  static size_t -ext2_xattr_user_list(struct inode *inode, char *list, size_t list_size, -		     const char *name, size_t name_len) +ext2_xattr_user_list(struct dentry *dentry, char *list, size_t list_size, +		const char *name, size_t name_len, int type)  {  	const size_t prefix_len = XATTR_USER_PREFIX_LEN;  	const size_t total_len = prefix_len + name_len + 1; -	if (!test_opt(inode->i_sb, XATTR_USER)) +	if (!test_opt(dentry->d_sb, XATTR_USER))  		return 0;  	if (list && total_len <= list_size) { @@ -30,27 +30,28 @@ ext2_xattr_user_list(struct inode *inode, char *list, size_t list_size,  }  static int -ext2_xattr_user_get(struct inode *inode, const char *name, -		    void *buffer, size_t size) +ext2_xattr_user_get(struct dentry *dentry, const char *name, +		void *buffer, size_t size, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	if (!test_opt(inode->i_sb, XATTR_USER)) +	if (!test_opt(dentry->d_sb, XATTR_USER))  		return -EOPNOTSUPP; -	return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name, buffer, size); +	return ext2_xattr_get(dentry->d_inode, EXT2_XATTR_INDEX_USER, +			      name, buffer, size);  }  static int -ext2_xattr_user_set(struct inode *inode, const char *name, -		    const void *value, size_t size, int flags) +ext2_xattr_user_set(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	if (!test_opt(inode->i_sb, XATTR_USER)) +	if (!test_opt(dentry->d_sb, XATTR_USER))  		return -EOPNOTSUPP; -	return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name, -			      value, size, flags); +	return ext2_xattr_set(dentry->d_inode, EXT2_XATTR_INDEX_USER, +			      name, value, size, flags);  }  struct xattr_handler ext2_xattr_user_handler = { diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index c9b0df376b5f..82ba34158661 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c @@ -366,12 +366,12 @@ out:   * Extended attribute handlers   */  static size_t -ext3_xattr_list_acl_access(struct inode *inode, char *list, size_t list_len, -			   const char *name, size_t name_len) +ext3_xattr_list_acl_access(struct dentry *dentry, char *list, size_t list_len, +			   const char *name, size_t name_len, int type)  {  	const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS); -	if (!test_opt(inode->i_sb, POSIX_ACL)) +	if (!test_opt(dentry->d_sb, POSIX_ACL))  		return 0;  	if (list && size <= list_len)  		memcpy(list, POSIX_ACL_XATTR_ACCESS, size); @@ -379,12 +379,12 @@ ext3_xattr_list_acl_access(struct inode *inode, char *list, size_t list_len,  }  static size_t -ext3_xattr_list_acl_default(struct inode *inode, char *list, size_t list_len, -			    const char *name, size_t name_len) +ext3_xattr_list_acl_default(struct dentry *dentry, char *list, size_t list_len, +			    const char *name, size_t name_len, int type)  {  	const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT); -	if (!test_opt(inode->i_sb, POSIX_ACL)) +	if (!test_opt(dentry->d_sb, POSIX_ACL))  		return 0;  	if (list && size <= list_len)  		memcpy(list, POSIX_ACL_XATTR_DEFAULT, size); @@ -392,15 +392,18 @@ ext3_xattr_list_acl_default(struct inode *inode, char *list, size_t list_len,  }  static int -ext3_xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size) +ext3_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer, +		   size_t size, int type)  {  	struct posix_acl *acl;  	int error; -	if (!test_opt(inode->i_sb, POSIX_ACL)) +	if (strcmp(name, "") != 0) +		return -EINVAL; +	if (!test_opt(dentry->d_sb, POSIX_ACL))  		return -EOPNOTSUPP; -	acl = ext3_get_acl(inode, type); +	acl = ext3_get_acl(dentry->d_inode, type);  	if (IS_ERR(acl))  		return PTR_ERR(acl);  	if (acl == NULL) @@ -412,31 +415,16 @@ ext3_xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size)  }  static int -ext3_xattr_get_acl_access(struct inode *inode, const char *name, -			  void *buffer, size_t size) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return ext3_xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size); -} - -static int -ext3_xattr_get_acl_default(struct inode *inode, const char *name, -			   void *buffer, size_t size) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return ext3_xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size); -} - -static int -ext3_xattr_set_acl(struct inode *inode, int type, const void *value, -		   size_t size) +ext3_xattr_set_acl(struct dentry *dentry, const char *name, const void *value, +		   size_t size, int flags, int type)  { +	struct inode *inode = dentry->d_inode;  	handle_t *handle;  	struct posix_acl *acl;  	int error, retries = 0; +	if (strcmp(name, "") != 0) +		return -EINVAL;  	if (!test_opt(inode->i_sb, POSIX_ACL))  		return -EOPNOTSUPP;  	if (!is_owner_or_cap(inode)) @@ -468,34 +456,18 @@ release_and_out:  	return error;  } -static int -ext3_xattr_set_acl_access(struct inode *inode, const char *name, -			  const void *value, size_t size, int flags) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return ext3_xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size); -} - -static int -ext3_xattr_set_acl_default(struct inode *inode, const char *name, -			   const void *value, size_t size, int flags) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return ext3_xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); -} -  struct xattr_handler ext3_xattr_acl_access_handler = {  	.prefix	= POSIX_ACL_XATTR_ACCESS, +	.flags	= ACL_TYPE_ACCESS,  	.list	= ext3_xattr_list_acl_access, -	.get	= ext3_xattr_get_acl_access, -	.set	= ext3_xattr_set_acl_access, +	.get	= ext3_xattr_get_acl, +	.set	= ext3_xattr_set_acl,  };  struct xattr_handler ext3_xattr_acl_default_handler = {  	.prefix	= POSIX_ACL_XATTR_DEFAULT, +	.flags	= ACL_TYPE_DEFAULT,  	.list	= ext3_xattr_list_acl_default, -	.get	= ext3_xattr_get_acl_default, -	.set	= ext3_xattr_set_acl_default, +	.get	= ext3_xattr_get_acl, +	.set	= ext3_xattr_set_acl,  }; diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index 387d92d00b97..66895ccf76c7 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c @@ -99,7 +99,7 @@ static struct buffer_head *ext3_xattr_cache_find(struct inode *,  						 struct mb_cache_entry **);  static void ext3_xattr_rehash(struct ext3_xattr_header *,  			      struct ext3_xattr_entry *); -static int ext3_xattr_list(struct inode *inode, char *buffer, +static int ext3_xattr_list(struct dentry *dentry, char *buffer,  			   size_t buffer_size);  static struct mb_cache *ext3_xattr_cache; @@ -147,7 +147,7 @@ ext3_xattr_handler(int name_index)  ssize_t  ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)  { -	return ext3_xattr_list(dentry->d_inode, buffer, size); +	return ext3_xattr_list(dentry, buffer, size);  }  static int @@ -332,7 +332,7 @@ ext3_xattr_get(struct inode *inode, int name_index, const char *name,  }  static int -ext3_xattr_list_entries(struct inode *inode, struct ext3_xattr_entry *entry, +ext3_xattr_list_entries(struct dentry *dentry, struct ext3_xattr_entry *entry,  			char *buffer, size_t buffer_size)  {  	size_t rest = buffer_size; @@ -342,9 +342,10 @@ ext3_xattr_list_entries(struct inode *inode, struct ext3_xattr_entry *entry,  			ext3_xattr_handler(entry->e_name_index);  		if (handler) { -			size_t size = handler->list(inode, buffer, rest, +			size_t size = handler->list(dentry, buffer, rest,  						    entry->e_name, -						    entry->e_name_len); +						    entry->e_name_len, +						    handler->flags);  			if (buffer) {  				if (size > rest)  					return -ERANGE; @@ -357,8 +358,9 @@ ext3_xattr_list_entries(struct inode *inode, struct ext3_xattr_entry *entry,  }  static int -ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size) +ext3_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size)  { +	struct inode *inode = dentry->d_inode;  	struct buffer_head *bh = NULL;  	int error; @@ -383,7 +385,7 @@ ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)  		goto cleanup;  	}  	ext3_xattr_cache_insert(bh); -	error = ext3_xattr_list_entries(inode, BFIRST(bh), buffer, buffer_size); +	error = ext3_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size);  cleanup:  	brelse(bh); @@ -392,8 +394,9 @@ cleanup:  }  static int -ext3_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size) +ext3_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size)  { +	struct inode *inode = dentry->d_inode;  	struct ext3_xattr_ibody_header *header;  	struct ext3_inode *raw_inode;  	struct ext3_iloc iloc; @@ -411,7 +414,7 @@ ext3_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size)  	error = ext3_xattr_check_names(IFIRST(header), end);  	if (error)  		goto cleanup; -	error = ext3_xattr_list_entries(inode, IFIRST(header), +	error = ext3_xattr_list_entries(dentry, IFIRST(header),  					buffer, buffer_size);  cleanup: @@ -430,12 +433,12 @@ cleanup:   * used / required on success.   */  static int -ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) +ext3_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)  {  	int i_error, b_error; -	down_read(&EXT3_I(inode)->xattr_sem); -	i_error = ext3_xattr_ibody_list(inode, buffer, buffer_size); +	down_read(&EXT3_I(dentry->d_inode)->xattr_sem); +	i_error = ext3_xattr_ibody_list(dentry, buffer, buffer_size);  	if (i_error < 0) {  		b_error = 0;  	} else { @@ -443,11 +446,11 @@ ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)  			buffer += i_error;  			buffer_size -= i_error;  		} -		b_error = ext3_xattr_block_list(inode, buffer, buffer_size); +		b_error = ext3_xattr_block_list(dentry, buffer, buffer_size);  		if (b_error < 0)  			i_error = 0;  	} -	up_read(&EXT3_I(inode)->xattr_sem); +	up_read(&EXT3_I(dentry->d_inode)->xattr_sem);  	return i_error + b_error;  } diff --git a/fs/ext3/xattr_security.c b/fs/ext3/xattr_security.c index 37b81097bdf2..474348788dd9 100644 --- a/fs/ext3/xattr_security.c +++ b/fs/ext3/xattr_security.c @@ -12,8 +12,8 @@  #include "xattr.h"  static size_t -ext3_xattr_security_list(struct inode *inode, char *list, size_t list_size, -			 const char *name, size_t name_len) +ext3_xattr_security_list(struct dentry *dentry, char *list, size_t list_size, +			 const char *name, size_t name_len, int type)  {  	const size_t prefix_len = XATTR_SECURITY_PREFIX_LEN;  	const size_t total_len = prefix_len + name_len + 1; @@ -28,23 +28,23 @@ ext3_xattr_security_list(struct inode *inode, char *list, size_t list_size,  }  static int -ext3_xattr_security_get(struct inode *inode, const char *name, -		       void *buffer, size_t size) +ext3_xattr_security_get(struct dentry *dentry, const char *name, +		void *buffer, size_t size, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return ext3_xattr_get(inode, EXT3_XATTR_INDEX_SECURITY, name, -			      buffer, size); +	return ext3_xattr_get(dentry->d_inode, EXT3_XATTR_INDEX_SECURITY, +			      name, buffer, size);  }  static int -ext3_xattr_security_set(struct inode *inode, const char *name, -		       const void *value, size_t size, int flags) +ext3_xattr_security_set(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return ext3_xattr_set(inode, EXT3_XATTR_INDEX_SECURITY, name, -			      value, size, flags); +	return ext3_xattr_set(dentry->d_inode, EXT3_XATTR_INDEX_SECURITY, +			      name, value, size, flags);  }  int diff --git a/fs/ext3/xattr_trusted.c b/fs/ext3/xattr_trusted.c index c7c41a410c4b..e5562845ed96 100644 --- a/fs/ext3/xattr_trusted.c +++ b/fs/ext3/xattr_trusted.c @@ -14,8 +14,8 @@  #include "xattr.h"  static size_t -ext3_xattr_trusted_list(struct inode *inode, char *list, size_t list_size, -			const char *name, size_t name_len) +ext3_xattr_trusted_list(struct dentry *dentry, char *list, size_t list_size, +		const char *name, size_t name_len, int type)  {  	const size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN;  	const size_t total_len = prefix_len + name_len + 1; @@ -32,22 +32,22 @@ ext3_xattr_trusted_list(struct inode *inode, char *list, size_t list_size,  }  static int -ext3_xattr_trusted_get(struct inode *inode, const char *name, -		       void *buffer, size_t size) +ext3_xattr_trusted_get(struct dentry *dentry, const char *name, +		       void *buffer, size_t size, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return ext3_xattr_get(inode, EXT3_XATTR_INDEX_TRUSTED, name, -			      buffer, size); +	return ext3_xattr_get(dentry->d_inode, EXT3_XATTR_INDEX_TRUSTED, +			      name, buffer, size);  }  static int -ext3_xattr_trusted_set(struct inode *inode, const char *name, -		       const void *value, size_t size, int flags) +ext3_xattr_trusted_set(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return ext3_xattr_set(inode, EXT3_XATTR_INDEX_TRUSTED, name, +	return ext3_xattr_set(dentry->d_inode, EXT3_XATTR_INDEX_TRUSTED, name,  			      value, size, flags);  } diff --git a/fs/ext3/xattr_user.c b/fs/ext3/xattr_user.c index 430fe63b31b3..3bcfe9ee0a68 100644 --- a/fs/ext3/xattr_user.c +++ b/fs/ext3/xattr_user.c @@ -13,13 +13,13 @@  #include "xattr.h"  static size_t -ext3_xattr_user_list(struct inode *inode, char *list, size_t list_size, -		     const char *name, size_t name_len) +ext3_xattr_user_list(struct dentry *dentry, char *list, size_t list_size, +		const char *name, size_t name_len, int type)  {  	const size_t prefix_len = XATTR_USER_PREFIX_LEN;  	const size_t total_len = prefix_len + name_len + 1; -	if (!test_opt(inode->i_sb, XATTR_USER)) +	if (!test_opt(dentry->d_sb, XATTR_USER))  		return 0;  	if (list && total_len <= list_size) { @@ -31,26 +31,27 @@ ext3_xattr_user_list(struct inode *inode, char *list, size_t list_size,  }  static int -ext3_xattr_user_get(struct inode *inode, const char *name, -		    void *buffer, size_t size) +ext3_xattr_user_get(struct dentry *dentry, const char *name, void *buffer, +		size_t size, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	if (!test_opt(inode->i_sb, XATTR_USER)) +	if (!test_opt(dentry->d_sb, XATTR_USER))  		return -EOPNOTSUPP; -	return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name, buffer, size); +	return ext3_xattr_get(dentry->d_inode, EXT3_XATTR_INDEX_USER, +			      name, buffer, size);  }  static int -ext3_xattr_user_set(struct inode *inode, const char *name, -		    const void *value, size_t size, int flags) +ext3_xattr_user_set(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	if (!test_opt(inode->i_sb, XATTR_USER)) +	if (!test_opt(dentry->d_sb, XATTR_USER))  		return -EOPNOTSUPP; -	return ext3_xattr_set(inode, EXT3_XATTR_INDEX_USER, name, -			      value, size, flags); +	return ext3_xattr_set(dentry->d_inode, EXT3_XATTR_INDEX_USER, +			      name, value, size, flags);  }  struct xattr_handler ext3_xattr_user_handler = { diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 0df88b2a69b0..8a2a29d35a6f 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c @@ -364,12 +364,12 @@ out:   * Extended attribute handlers   */  static size_t -ext4_xattr_list_acl_access(struct inode *inode, char *list, size_t list_len, -			   const char *name, size_t name_len) +ext4_xattr_list_acl_access(struct dentry *dentry, char *list, size_t list_len, +			   const char *name, size_t name_len, int type)  {  	const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS); -	if (!test_opt(inode->i_sb, POSIX_ACL)) +	if (!test_opt(dentry->d_sb, POSIX_ACL))  		return 0;  	if (list && size <= list_len)  		memcpy(list, POSIX_ACL_XATTR_ACCESS, size); @@ -377,12 +377,12 @@ ext4_xattr_list_acl_access(struct inode *inode, char *list, size_t list_len,  }  static size_t -ext4_xattr_list_acl_default(struct inode *inode, char *list, size_t list_len, -			    const char *name, size_t name_len) +ext4_xattr_list_acl_default(struct dentry *dentry, char *list, size_t list_len, +			    const char *name, size_t name_len, int type)  {  	const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT); -	if (!test_opt(inode->i_sb, POSIX_ACL)) +	if (!test_opt(dentry->d_sb, POSIX_ACL))  		return 0;  	if (list && size <= list_len)  		memcpy(list, POSIX_ACL_XATTR_DEFAULT, size); @@ -390,15 +390,18 @@ ext4_xattr_list_acl_default(struct inode *inode, char *list, size_t list_len,  }  static int -ext4_xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size) +ext4_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer, +		   size_t size, int type)  {  	struct posix_acl *acl;  	int error; -	if (!test_opt(inode->i_sb, POSIX_ACL)) +	if (strcmp(name, "") != 0) +		return -EINVAL; +	if (!test_opt(dentry->d_sb, POSIX_ACL))  		return -EOPNOTSUPP; -	acl = ext4_get_acl(inode, type); +	acl = ext4_get_acl(dentry->d_inode, type);  	if (IS_ERR(acl))  		return PTR_ERR(acl);  	if (acl == NULL) @@ -410,31 +413,16 @@ ext4_xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size)  }  static int -ext4_xattr_get_acl_access(struct inode *inode, const char *name, -			  void *buffer, size_t size) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return ext4_xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size); -} - -static int -ext4_xattr_get_acl_default(struct inode *inode, const char *name, -			   void *buffer, size_t size) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return ext4_xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size); -} - -static int -ext4_xattr_set_acl(struct inode *inode, int type, const void *value, -		   size_t size) +ext4_xattr_set_acl(struct dentry *dentry, const char *name, const void *value, +		   size_t size, int flags, int type)  { +	struct inode *inode = dentry->d_inode;  	handle_t *handle;  	struct posix_acl *acl;  	int error, retries = 0; +	if (strcmp(name, "") != 0) +		return -EINVAL;  	if (!test_opt(inode->i_sb, POSIX_ACL))  		return -EOPNOTSUPP;  	if (!is_owner_or_cap(inode)) @@ -466,34 +454,18 @@ release_and_out:  	return error;  } -static int -ext4_xattr_set_acl_access(struct inode *inode, const char *name, -			  const void *value, size_t size, int flags) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return ext4_xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size); -} - -static int -ext4_xattr_set_acl_default(struct inode *inode, const char *name, -			   const void *value, size_t size, int flags) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return ext4_xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); -} -  struct xattr_handler ext4_xattr_acl_access_handler = {  	.prefix	= POSIX_ACL_XATTR_ACCESS, +	.flags	= ACL_TYPE_ACCESS,  	.list	= ext4_xattr_list_acl_access, -	.get	= ext4_xattr_get_acl_access, -	.set	= ext4_xattr_set_acl_access, +	.get	= ext4_xattr_get_acl, +	.set	= ext4_xattr_set_acl,  };  struct xattr_handler ext4_xattr_acl_default_handler = {  	.prefix	= POSIX_ACL_XATTR_DEFAULT, +	.flags	= ACL_TYPE_DEFAULT,  	.list	= ext4_xattr_list_acl_default, -	.get	= ext4_xattr_get_acl_default, -	.set	= ext4_xattr_set_acl_default, +	.get	= ext4_xattr_get_acl, +	.set	= ext4_xattr_set_acl,  }; diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 910bf9a59cb3..83218bebbc7c 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -92,7 +92,7 @@ static struct buffer_head *ext4_xattr_cache_find(struct inode *,  						 struct mb_cache_entry **);  static void ext4_xattr_rehash(struct ext4_xattr_header *,  			      struct ext4_xattr_entry *); -static int ext4_xattr_list(struct inode *inode, char *buffer, +static int ext4_xattr_list(struct dentry *dentry, char *buffer,  			   size_t buffer_size);  static struct mb_cache *ext4_xattr_cache; @@ -140,7 +140,7 @@ ext4_xattr_handler(int name_index)  ssize_t  ext4_listxattr(struct dentry *dentry, char *buffer, size_t size)  { -	return ext4_xattr_list(dentry->d_inode, buffer, size); +	return ext4_xattr_list(dentry, buffer, size);  }  static int @@ -325,7 +325,7 @@ ext4_xattr_get(struct inode *inode, int name_index, const char *name,  }  static int -ext4_xattr_list_entries(struct inode *inode, struct ext4_xattr_entry *entry, +ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,  			char *buffer, size_t buffer_size)  {  	size_t rest = buffer_size; @@ -335,9 +335,10 @@ ext4_xattr_list_entries(struct inode *inode, struct ext4_xattr_entry *entry,  			ext4_xattr_handler(entry->e_name_index);  		if (handler) { -			size_t size = handler->list(inode, buffer, rest, +			size_t size = handler->list(dentry, buffer, rest,  						    entry->e_name, -						    entry->e_name_len); +						    entry->e_name_len, +						    handler->flags);  			if (buffer) {  				if (size > rest)  					return -ERANGE; @@ -350,8 +351,9 @@ ext4_xattr_list_entries(struct inode *inode, struct ext4_xattr_entry *entry,  }  static int -ext4_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size) +ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size)  { +	struct inode *inode = dentry->d_inode;  	struct buffer_head *bh = NULL;  	int error; @@ -376,7 +378,7 @@ ext4_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)  		goto cleanup;  	}  	ext4_xattr_cache_insert(bh); -	error = ext4_xattr_list_entries(inode, BFIRST(bh), buffer, buffer_size); +	error = ext4_xattr_list_entries(dentry, BFIRST(bh), buffer, buffer_size);  cleanup:  	brelse(bh); @@ -385,8 +387,9 @@ cleanup:  }  static int -ext4_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size) +ext4_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size)  { +	struct inode *inode = dentry->d_inode;  	struct ext4_xattr_ibody_header *header;  	struct ext4_inode *raw_inode;  	struct ext4_iloc iloc; @@ -404,7 +407,7 @@ ext4_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size)  	error = ext4_xattr_check_names(IFIRST(header), end);  	if (error)  		goto cleanup; -	error = ext4_xattr_list_entries(inode, IFIRST(header), +	error = ext4_xattr_list_entries(dentry, IFIRST(header),  					buffer, buffer_size);  cleanup: @@ -423,12 +426,12 @@ cleanup:   * used / required on success.   */  static int -ext4_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) +ext4_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)  {  	int i_error, b_error; -	down_read(&EXT4_I(inode)->xattr_sem); -	i_error = ext4_xattr_ibody_list(inode, buffer, buffer_size); +	down_read(&EXT4_I(dentry->d_inode)->xattr_sem); +	i_error = ext4_xattr_ibody_list(dentry, buffer, buffer_size);  	if (i_error < 0) {  		b_error = 0;  	} else { @@ -436,11 +439,11 @@ ext4_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)  			buffer += i_error;  			buffer_size -= i_error;  		} -		b_error = ext4_xattr_block_list(inode, buffer, buffer_size); +		b_error = ext4_xattr_block_list(dentry, buffer, buffer_size);  		if (b_error < 0)  			i_error = 0;  	} -	up_read(&EXT4_I(inode)->xattr_sem); +	up_read(&EXT4_I(dentry->d_inode)->xattr_sem);  	return i_error + b_error;  } diff --git a/fs/ext4/xattr_security.c b/fs/ext4/xattr_security.c index ca5f89fc6cae..983c253999a7 100644 --- a/fs/ext4/xattr_security.c +++ b/fs/ext4/xattr_security.c @@ -12,8 +12,8 @@  #include "xattr.h"  static size_t -ext4_xattr_security_list(struct inode *inode, char *list, size_t list_size, -			 const char *name, size_t name_len) +ext4_xattr_security_list(struct dentry *dentry, char *list, size_t list_size, +		const char *name, size_t name_len, int type)  {  	const size_t prefix_len = sizeof(XATTR_SECURITY_PREFIX)-1;  	const size_t total_len = prefix_len + name_len + 1; @@ -28,23 +28,23 @@ ext4_xattr_security_list(struct inode *inode, char *list, size_t list_size,  }  static int -ext4_xattr_security_get(struct inode *inode, const char *name, -		       void *buffer, size_t size) +ext4_xattr_security_get(struct dentry *dentry, const char *name, +		       void *buffer, size_t size, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return ext4_xattr_get(inode, EXT4_XATTR_INDEX_SECURITY, name, -			      buffer, size); +	return ext4_xattr_get(dentry->d_inode, EXT4_XATTR_INDEX_SECURITY, +			      name, buffer, size);  }  static int -ext4_xattr_security_set(struct inode *inode, const char *name, -		       const void *value, size_t size, int flags) +ext4_xattr_security_set(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return ext4_xattr_set(inode, EXT4_XATTR_INDEX_SECURITY, name, -			      value, size, flags); +	return ext4_xattr_set(dentry->d_inode, EXT4_XATTR_INDEX_SECURITY, +			      name, value, size, flags);  }  int diff --git a/fs/ext4/xattr_trusted.c b/fs/ext4/xattr_trusted.c index ac1a52cf2a37..15b50edc6587 100644 --- a/fs/ext4/xattr_trusted.c +++ b/fs/ext4/xattr_trusted.c @@ -14,8 +14,8 @@  #include "xattr.h"  static size_t -ext4_xattr_trusted_list(struct inode *inode, char *list, size_t list_size, -			const char *name, size_t name_len) +ext4_xattr_trusted_list(struct dentry *dentry, char *list, size_t list_size, +		const char *name, size_t name_len, int type)  {  	const size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN;  	const size_t total_len = prefix_len + name_len + 1; @@ -32,23 +32,23 @@ ext4_xattr_trusted_list(struct inode *inode, char *list, size_t list_size,  }  static int -ext4_xattr_trusted_get(struct inode *inode, const char *name, -		       void *buffer, size_t size) +ext4_xattr_trusted_get(struct dentry *dentry, const char *name, void *buffer, +		size_t size, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return ext4_xattr_get(inode, EXT4_XATTR_INDEX_TRUSTED, name, -			      buffer, size); +	return ext4_xattr_get(dentry->d_inode, EXT4_XATTR_INDEX_TRUSTED, +			      name, buffer, size);  }  static int -ext4_xattr_trusted_set(struct inode *inode, const char *name, -		       const void *value, size_t size, int flags) +ext4_xattr_trusted_set(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return ext4_xattr_set(inode, EXT4_XATTR_INDEX_TRUSTED, name, -			      value, size, flags); +	return ext4_xattr_set(dentry->d_inode, EXT4_XATTR_INDEX_TRUSTED, +			      name, value, size, flags);  }  struct xattr_handler ext4_xattr_trusted_handler = { diff --git a/fs/ext4/xattr_user.c b/fs/ext4/xattr_user.c index d91aa61b42aa..c4ce05746ce1 100644 --- a/fs/ext4/xattr_user.c +++ b/fs/ext4/xattr_user.c @@ -13,13 +13,13 @@  #include "xattr.h"  static size_t -ext4_xattr_user_list(struct inode *inode, char *list, size_t list_size, -		     const char *name, size_t name_len) +ext4_xattr_user_list(struct dentry *dentry, char *list, size_t list_size, +		     const char *name, size_t name_len, int type)  {  	const size_t prefix_len = XATTR_USER_PREFIX_LEN;  	const size_t total_len = prefix_len + name_len + 1; -	if (!test_opt(inode->i_sb, XATTR_USER)) +	if (!test_opt(dentry->d_sb, XATTR_USER))  		return 0;  	if (list && total_len <= list_size) { @@ -31,26 +31,27 @@ ext4_xattr_user_list(struct inode *inode, char *list, size_t list_size,  }  static int -ext4_xattr_user_get(struct inode *inode, const char *name, -		    void *buffer, size_t size) +ext4_xattr_user_get(struct dentry *dentry, const char *name, +		    void *buffer, size_t size, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	if (!test_opt(inode->i_sb, XATTR_USER)) +	if (!test_opt(dentry->d_sb, XATTR_USER))  		return -EOPNOTSUPP; -	return ext4_xattr_get(inode, EXT4_XATTR_INDEX_USER, name, buffer, size); +	return ext4_xattr_get(dentry->d_inode, EXT4_XATTR_INDEX_USER, +			      name, buffer, size);  }  static int -ext4_xattr_user_set(struct inode *inode, const char *name, -		    const void *value, size_t size, int flags) +ext4_xattr_user_set(struct dentry *dentry, const char *name, +		    const void *value, size_t size, int flags, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	if (!test_opt(inode->i_sb, XATTR_USER)) +	if (!test_opt(dentry->d_sb, XATTR_USER))  		return -EOPNOTSUPP; -	return ext4_xattr_set(inode, EXT4_XATTR_INDEX_USER, name, -			      value, size, flags); +	return ext4_xattr_set(dentry->d_inode, EXT4_XATTR_INDEX_USER, +			      name, value, size, flags);  }  struct xattr_handler ext4_xattr_user_handler = { diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 3eb1ea846173..87ee309d4c24 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c @@ -126,7 +126,7 @@ static int gfs2_acl_set(struct inode *inode, int type, struct posix_acl *acl)  	error = posix_acl_to_xattr(acl, data, len);  	if (error < 0)  		goto out; -	error = gfs2_xattr_set(inode, GFS2_EATYPE_SYS, name, data, len, 0); +	error = __gfs2_xattr_set(inode, name, data, len, 0, GFS2_EATYPE_SYS);  	if (!error)  		set_cached_acl(inode, type, acl);  out: @@ -232,9 +232,10 @@ static int gfs2_acl_type(const char *name)  	return -EINVAL;  } -static int gfs2_xattr_system_get(struct inode *inode, const char *name, -				 void *buffer, size_t size) +static int gfs2_xattr_system_get(struct dentry *dentry, const char *name, +				 void *buffer, size_t size, int xtype)  { +	struct inode *inode = dentry->d_inode;  	struct posix_acl *acl;  	int type;  	int error; @@ -255,9 +256,11 @@ static int gfs2_xattr_system_get(struct inode *inode, const char *name,  	return error;  } -static int gfs2_xattr_system_set(struct inode *inode, const char *name, -				 const void *value, size_t size, int flags) +static int gfs2_xattr_system_set(struct dentry *dentry, const char *name, +				 const void *value, size_t size, int flags, +				 int xtype)  { +	struct inode *inode = dentry->d_inode;  	struct gfs2_sbd *sdp = GFS2_SB(inode);  	struct posix_acl *acl = NULL;  	int error = 0, type; @@ -319,7 +322,7 @@ static int gfs2_xattr_system_set(struct inode *inode, const char *name,  	}  set_acl: -	error = gfs2_xattr_set(inode, GFS2_EATYPE_SYS, name, value, size, 0); +	error = __gfs2_xattr_set(inode, name, value, size, 0, GFS2_EATYPE_SYS);  	if (!error) {  		if (acl)  			set_cached_acl(inode, type, acl); @@ -334,6 +337,7 @@ out:  struct xattr_handler gfs2_xattr_system_handler = {  	.prefix = XATTR_SYSTEM_PREFIX, +	.flags  = GFS2_EATYPE_SYS,  	.get    = gfs2_xattr_system_get,  	.set    = gfs2_xattr_system_set,  }; diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 26ba2a4c4a2d..3ff32fa793da 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -801,7 +801,8 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip)  		return err;  	} -	err = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SECURITY, name, value, len, 0); +	err = __gfs2_xattr_set(&ip->i_inode, name, value, len, 0, +			       GFS2_EATYPE_SECURITY);  	kfree(value);  	kfree(name); diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index 912f5cbc4740..8a04108e0c22 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c @@ -567,18 +567,17 @@ out:  /**   * gfs2_xattr_get - Get a GFS2 extended attribute   * @inode: The inode - * @type: The type of extended attribute   * @name: The name of the extended attribute   * @buffer: The buffer to write the result into   * @size: The size of the buffer + * @type: The type of extended attribute   *   * Returns: actual size of data on success, -errno on error   */ - -int gfs2_xattr_get(struct inode *inode, int type, const char *name, -		   void *buffer, size_t size) +static int gfs2_xattr_get(struct dentry *dentry, const char *name, +		void *buffer, size_t size, int type)  { -	struct gfs2_inode *ip = GFS2_I(inode); +	struct gfs2_inode *ip = GFS2_I(dentry->d_inode);  	struct gfs2_ea_location el;  	int error; @@ -1119,7 +1118,7 @@ static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el)  /**   * gfs2_xattr_remove - Remove a GFS2 extended attribute - * @inode: The inode + * @ip: The inode   * @type: The type of the extended attribute   * @name: The name of the extended attribute   * @@ -1130,9 +1129,8 @@ static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el)   * Returns: 0, or errno on failure   */ -static int gfs2_xattr_remove(struct inode *inode, int type, const char *name) +static int gfs2_xattr_remove(struct gfs2_inode *ip, int type, const char *name)  { -	struct gfs2_inode *ip = GFS2_I(inode);  	struct gfs2_ea_location el;  	int error; @@ -1156,24 +1154,24 @@ static int gfs2_xattr_remove(struct inode *inode, int type, const char *name)  }  /** - * gfs2_xattr_set - Set (or remove) a GFS2 extended attribute - * @inode: The inode - * @type: The type of the extended attribute + * __gfs2_xattr_set - Set (or remove) a GFS2 extended attribute + * @ip: The inode   * @name: The name of the extended attribute   * @value: The value of the extended attribute (NULL for remove)   * @size: The size of the @value argument   * @flags: Create or Replace + * @type: The type of the extended attribute   *   * See gfs2_xattr_remove() for details of the removal of xattrs.   *   * Returns: 0 or errno on failure   */ -int gfs2_xattr_set(struct inode *inode, int type, const char *name, -		   const void *value, size_t size, int flags) +int __gfs2_xattr_set(struct inode *inode, const char *name, +		   const void *value, size_t size, int flags, int type)  { -	struct gfs2_sbd *sdp = GFS2_SB(inode);  	struct gfs2_inode *ip = GFS2_I(inode); +	struct gfs2_sbd *sdp = GFS2_SB(inode);  	struct gfs2_ea_location el;  	unsigned int namel = strlen(name);  	int error; @@ -1184,7 +1182,7 @@ int gfs2_xattr_set(struct inode *inode, int type, const char *name,  		return -ERANGE;  	if (value == NULL) -		return gfs2_xattr_remove(inode, type, name); +		return gfs2_xattr_remove(ip, type, name);  	if (ea_check_size(sdp, namel, size))  		return -ERANGE; @@ -1224,6 +1222,13 @@ int gfs2_xattr_set(struct inode *inode, int type, const char *name,  	return error;  } +static int gfs2_xattr_set(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int type) +{ +	return __gfs2_xattr_set(dentry->d_inode, name, value, +				size, flags, type); +} +  static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip,  				  struct gfs2_ea_header *ea, char *data)  { @@ -1529,40 +1534,18 @@ out_alloc:  	return error;  } -static int gfs2_xattr_user_get(struct inode *inode, const char *name, -			       void *buffer, size_t size) -{ -	return gfs2_xattr_get(inode, GFS2_EATYPE_USR, name, buffer, size); -} - -static int gfs2_xattr_user_set(struct inode *inode, const char *name, -			       const void *value, size_t size, int flags) -{ -	return gfs2_xattr_set(inode, GFS2_EATYPE_USR, name, value, size, flags); -} - -static int gfs2_xattr_security_get(struct inode *inode, const char *name, -				   void *buffer, size_t size) -{ -	return gfs2_xattr_get(inode, GFS2_EATYPE_SECURITY, name, buffer, size); -} - -static int gfs2_xattr_security_set(struct inode *inode, const char *name, -				   const void *value, size_t size, int flags) -{ -	return gfs2_xattr_set(inode, GFS2_EATYPE_SECURITY, name, value, size, flags); -} -  static struct xattr_handler gfs2_xattr_user_handler = {  	.prefix = XATTR_USER_PREFIX, -	.get    = gfs2_xattr_user_get, -	.set    = gfs2_xattr_user_set, +	.flags  = GFS2_EATYPE_USR, +	.get    = gfs2_xattr_get, +	.set    = gfs2_xattr_set,  };  static struct xattr_handler gfs2_xattr_security_handler = {  	.prefix = XATTR_SECURITY_PREFIX, -	.get    = gfs2_xattr_security_get, -	.set    = gfs2_xattr_security_set, +	.flags  = GFS2_EATYPE_SECURITY, +	.get    = gfs2_xattr_get, +	.set    = gfs2_xattr_set,  };  struct xattr_handler *gfs2_xattr_handlers[] = { diff --git a/fs/gfs2/xattr.h b/fs/gfs2/xattr.h index 8d6ae5813c4d..d392f8358f2f 100644 --- a/fs/gfs2/xattr.h +++ b/fs/gfs2/xattr.h @@ -53,10 +53,9 @@ struct gfs2_ea_location {  	struct gfs2_ea_header *el_prev;  }; -extern int gfs2_xattr_get(struct inode *inode, int type, const char *name, -			  void *buffer, size_t size); -extern int gfs2_xattr_set(struct inode *inode, int type, const char *name, -			  const void *value, size_t size, int flags); +extern int __gfs2_xattr_set(struct inode *inode, const char *name, +			    const void *value, size_t size, +			    int flags, int type);  extern ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size);  extern int gfs2_ea_dealloc(struct gfs2_inode *ip); diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 7edb62e97419..7cdc3196476a 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -350,8 +350,8 @@ int jffs2_acl_chmod(struct inode *inode)  	return rc;  } -static size_t jffs2_acl_access_listxattr(struct inode *inode, char *list, size_t list_size, -					 const char *name, size_t name_len) +static size_t jffs2_acl_access_listxattr(struct dentry *dentry, char *list, +		size_t list_size, const char *name, size_t name_len, int type)  {  	const int retlen = sizeof(POSIX_ACL_XATTR_ACCESS); @@ -360,8 +360,8 @@ static size_t jffs2_acl_access_listxattr(struct inode *inode, char *list, size_t  	return retlen;  } -static size_t jffs2_acl_default_listxattr(struct inode *inode, char *list, size_t list_size, -					  const char *name, size_t name_len) +static size_t jffs2_acl_default_listxattr(struct dentry *dentry, char *list, +		size_t list_size, const char *name, size_t name_len, int type)  {  	const int retlen = sizeof(POSIX_ACL_XATTR_DEFAULT); @@ -370,12 +370,16 @@ static size_t jffs2_acl_default_listxattr(struct inode *inode, char *list, size_  	return retlen;  } -static int jffs2_acl_getxattr(struct inode *inode, int type, void *buffer, size_t size) +static int jffs2_acl_getxattr(struct dentry *dentry, const char *name, +		void *buffer, size_t size, int type)  {  	struct posix_acl *acl;  	int rc; -	acl = jffs2_get_acl(inode, type); +	if (name[0] != '\0') +		return -EINVAL; + +	acl = jffs2_get_acl(dentry->d_inode, type);  	if (IS_ERR(acl))  		return PTR_ERR(acl);  	if (!acl) @@ -386,26 +390,15 @@ static int jffs2_acl_getxattr(struct inode *inode, int type, void *buffer, size_  	return rc;  } -static int jffs2_acl_access_getxattr(struct inode *inode, const char *name, void *buffer, size_t size) -{ -	if (name[0] != '\0') -		return -EINVAL; -	return jffs2_acl_getxattr(inode, ACL_TYPE_ACCESS, buffer, size); -} - -static int jffs2_acl_default_getxattr(struct inode *inode, const char *name, void *buffer, size_t size) -{ -	if (name[0] != '\0') -		return -EINVAL; -	return jffs2_acl_getxattr(inode, ACL_TYPE_DEFAULT, buffer, size); -} - -static int jffs2_acl_setxattr(struct inode *inode, int type, const void *value, size_t size) +static int jffs2_acl_setxattr(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int type)  {  	struct posix_acl *acl;  	int rc; -	if (!is_owner_or_cap(inode)) +	if (name[0] != '\0') +		return -EINVAL; +	if (!is_owner_or_cap(dentry->d_inode))  		return -EPERM;  	if (value) { @@ -420,38 +413,24 @@ static int jffs2_acl_setxattr(struct inode *inode, int type, const void *value,  	} else {  		acl = NULL;  	} -	rc = jffs2_set_acl(inode, type, acl); +	rc = jffs2_set_acl(dentry->d_inode, type, acl);   out:  	posix_acl_release(acl);  	return rc;  } -static int jffs2_acl_access_setxattr(struct inode *inode, const char *name, -				     const void *buffer, size_t size, int flags) -{ -	if (name[0] != '\0') -		return -EINVAL; -	return jffs2_acl_setxattr(inode, ACL_TYPE_ACCESS, buffer, size); -} - -static int jffs2_acl_default_setxattr(struct inode *inode, const char *name, -				      const void *buffer, size_t size, int flags) -{ -	if (name[0] != '\0') -		return -EINVAL; -	return jffs2_acl_setxattr(inode, ACL_TYPE_DEFAULT, buffer, size); -} -  struct xattr_handler jffs2_acl_access_xattr_handler = {  	.prefix	= POSIX_ACL_XATTR_ACCESS, +	.flags	= ACL_TYPE_DEFAULT,  	.list	= jffs2_acl_access_listxattr, -	.get	= jffs2_acl_access_getxattr, -	.set	= jffs2_acl_access_setxattr, +	.get	= jffs2_acl_getxattr, +	.set	= jffs2_acl_setxattr,  };  struct xattr_handler jffs2_acl_default_xattr_handler = {  	.prefix	= POSIX_ACL_XATTR_DEFAULT, +	.flags	= ACL_TYPE_DEFAULT,  	.list	= jffs2_acl_default_listxattr, -	.get	= jffs2_acl_default_getxattr, -	.set	= jffs2_acl_default_setxattr, +	.get	= jffs2_acl_getxattr, +	.set	= jffs2_acl_setxattr,  }; diff --git a/fs/jffs2/security.c b/fs/jffs2/security.c index 02c39c64ecb3..eaccee058583 100644 --- a/fs/jffs2/security.c +++ b/fs/jffs2/security.c @@ -44,26 +44,28 @@ int jffs2_init_security(struct inode *inode, struct inode *dir)  }  /* ---- XATTR Handler for "security.*" ----------------- */ -static int jffs2_security_getxattr(struct inode *inode, const char *name, -				   void *buffer, size_t size) +static int jffs2_security_getxattr(struct dentry *dentry, const char *name, +				   void *buffer, size_t size, int type)  {  	if (!strcmp(name, ""))  		return -EINVAL; -	return do_jffs2_getxattr(inode, JFFS2_XPREFIX_SECURITY, name, buffer, size); +	return do_jffs2_getxattr(dentry->d_inode, JFFS2_XPREFIX_SECURITY, +				 name, buffer, size);  } -static int jffs2_security_setxattr(struct inode *inode, const char *name, const void *buffer, -				   size_t size, int flags) +static int jffs2_security_setxattr(struct dentry *dentry, const char *name, +		const void *buffer, size_t size, int flags, int type)  {  	if (!strcmp(name, ""))  		return -EINVAL; -	return do_jffs2_setxattr(inode, JFFS2_XPREFIX_SECURITY, name, buffer, size, flags); +	return do_jffs2_setxattr(dentry->d_inode, JFFS2_XPREFIX_SECURITY, +				 name, buffer, size, flags);  } -static size_t jffs2_security_listxattr(struct inode *inode, char *list, size_t list_size, -				       const char *name, size_t name_len) +static size_t jffs2_security_listxattr(struct dentry *dentry, char *list, +		size_t list_size, const char *name, size_t name_len, int type)  {  	size_t retlen = XATTR_SECURITY_PREFIX_LEN + name_len + 1; diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index 4b107881acd5..9e75c62c85d6 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c @@ -990,9 +990,11 @@ ssize_t jffs2_listxattr(struct dentry *dentry, char *buffer, size_t size)  		if (!xhandle)  			continue;  		if (buffer) { -			rc = xhandle->list(inode, buffer+len, size-len, xd->xname, xd->name_len); +			rc = xhandle->list(dentry, buffer+len, size-len, +					   xd->xname, xd->name_len, xd->flags);  		} else { -			rc = xhandle->list(inode, NULL, 0, xd->xname, xd->name_len); +			rc = xhandle->list(dentry, NULL, 0, xd->xname, +					   xd->name_len, xd->flags);  		}  		if (rc < 0)  			goto out; diff --git a/fs/jffs2/xattr_trusted.c b/fs/jffs2/xattr_trusted.c index 8ec5765ef348..3e5a5e356e05 100644 --- a/fs/jffs2/xattr_trusted.c +++ b/fs/jffs2/xattr_trusted.c @@ -16,24 +16,26 @@  #include <linux/mtd/mtd.h>  #include "nodelist.h" -static int jffs2_trusted_getxattr(struct inode *inode, const char *name, -				  void *buffer, size_t size) +static int jffs2_trusted_getxattr(struct dentry *dentry, const char *name, +		void *buffer, size_t size, int type)  {  	if (!strcmp(name, ""))  		return -EINVAL; -	return do_jffs2_getxattr(inode, JFFS2_XPREFIX_TRUSTED, name, buffer, size); +	return do_jffs2_getxattr(dentry->d_inode, JFFS2_XPREFIX_TRUSTED, +				 name, buffer, size);  } -static int jffs2_trusted_setxattr(struct inode *inode, const char *name, const void *buffer, -				  size_t size, int flags) +static int jffs2_trusted_setxattr(struct dentry *dentry, const char *name, +		const void *buffer, size_t size, int flags, int type)  {  	if (!strcmp(name, ""))  		return -EINVAL; -	return do_jffs2_setxattr(inode, JFFS2_XPREFIX_TRUSTED, name, buffer, size, flags); +	return do_jffs2_setxattr(dentry->d_inode, JFFS2_XPREFIX_TRUSTED, +				 name, buffer, size, flags);  } -static size_t jffs2_trusted_listxattr(struct inode *inode, char *list, size_t list_size, -				      const char *name, size_t name_len) +static size_t jffs2_trusted_listxattr(struct dentry *dentry, char *list, +		size_t list_size, const char *name, size_t name_len, int type)  {  	size_t retlen = XATTR_TRUSTED_PREFIX_LEN + name_len + 1; diff --git a/fs/jffs2/xattr_user.c b/fs/jffs2/xattr_user.c index 8bbeab90ada1..8544af67dffe 100644 --- a/fs/jffs2/xattr_user.c +++ b/fs/jffs2/xattr_user.c @@ -16,24 +16,26 @@  #include <linux/mtd/mtd.h>  #include "nodelist.h" -static int jffs2_user_getxattr(struct inode *inode, const char *name, -			       void *buffer, size_t size) +static int jffs2_user_getxattr(struct dentry *dentry, const char *name, +			       void *buffer, size_t size, int type)  {  	if (!strcmp(name, ""))  		return -EINVAL; -	return do_jffs2_getxattr(inode, JFFS2_XPREFIX_USER, name, buffer, size); +	return do_jffs2_getxattr(dentry->d_inode, JFFS2_XPREFIX_USER, +				 name, buffer, size);  } -static int jffs2_user_setxattr(struct inode *inode, const char *name, const void *buffer, -			       size_t size, int flags) +static int jffs2_user_setxattr(struct dentry *dentry, const char *name, +		const void *buffer, size_t size, int flags, int type)  {  	if (!strcmp(name, ""))  		return -EINVAL; -	return do_jffs2_setxattr(inode, JFFS2_XPREFIX_USER, name, buffer, size, flags); +	return do_jffs2_setxattr(dentry->d_inode, JFFS2_XPREFIX_USER, +				 name, buffer, size, flags);  } -static size_t jffs2_user_listxattr(struct inode *inode, char *list, size_t list_size, -				   const char *name, size_t name_len) +static size_t jffs2_user_listxattr(struct dentry *dentry, char *list, +		size_t list_size, const char *name, size_t name_len, int type)  {  	size_t retlen = XATTR_USER_PREFIX_LEN + name_len + 1; diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index fbeaec762103..e3e47415d851 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c @@ -331,13 +331,14 @@ cleanup:  	return ret;  } -static size_t ocfs2_xattr_list_acl_access(struct inode *inode, +static size_t ocfs2_xattr_list_acl_access(struct dentry *dentry,  					  char *list,  					  size_t list_len,  					  const char *name, -					  size_t name_len) +					  size_t name_len, +					  int type)  { -	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); +	struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);  	const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);  	if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL)) @@ -348,13 +349,14 @@ static size_t ocfs2_xattr_list_acl_access(struct inode *inode,  	return size;  } -static size_t ocfs2_xattr_list_acl_default(struct inode *inode, +static size_t ocfs2_xattr_list_acl_default(struct dentry *dentry,  					   char *list,  					   size_t list_len,  					   const char *name, -					   size_t name_len) +					   size_t name_len, +					   int type)  { -	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); +	struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);  	const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);  	if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL)) @@ -365,19 +367,19 @@ static size_t ocfs2_xattr_list_acl_default(struct inode *inode,  	return size;  } -static int ocfs2_xattr_get_acl(struct inode *inode, -			       int type, -			       void *buffer, -			       size_t size) +static int ocfs2_xattr_get_acl(struct dentry *dentry, const char *name, +		void *buffer, size_t size, int type)  { -	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); +	struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);  	struct posix_acl *acl;  	int ret; +	if (strcmp(name, "") != 0) +		return -EINVAL;  	if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))  		return -EOPNOTSUPP; -	acl = ocfs2_get_acl(inode, type); +	acl = ocfs2_get_acl(dentry->d_inode, type);  	if (IS_ERR(acl))  		return PTR_ERR(acl);  	if (acl == NULL) @@ -388,35 +390,16 @@ static int ocfs2_xattr_get_acl(struct inode *inode,  	return ret;  } -static int ocfs2_xattr_get_acl_access(struct inode *inode, -				      const char *name, -				      void *buffer, -				      size_t size) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return ocfs2_xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size); -} - -static int ocfs2_xattr_get_acl_default(struct inode *inode, -				       const char *name, -				       void *buffer, -				       size_t size) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return ocfs2_xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size); -} - -static int ocfs2_xattr_set_acl(struct inode *inode, -			       int type, -			       const void *value, -			       size_t size) +static int ocfs2_xattr_set_acl(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int type)  { +	struct inode *inode = dentry->d_inode;  	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);  	struct posix_acl *acl;  	int ret = 0; +	if (strcmp(name, "") != 0) +		return -EINVAL;  	if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))  		return -EOPNOTSUPP; @@ -442,38 +425,18 @@ cleanup:  	return ret;  } -static int ocfs2_xattr_set_acl_access(struct inode *inode, -				      const char *name, -				      const void *value, -				      size_t size, -				      int flags) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return ocfs2_xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size); -} - -static int ocfs2_xattr_set_acl_default(struct inode *inode, -				       const char *name, -				       const void *value, -				       size_t size, -				       int flags) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return ocfs2_xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); -} -  struct xattr_handler ocfs2_xattr_acl_access_handler = {  	.prefix	= POSIX_ACL_XATTR_ACCESS, +	.flags	= ACL_TYPE_ACCESS,  	.list	= ocfs2_xattr_list_acl_access, -	.get	= ocfs2_xattr_get_acl_access, -	.set	= ocfs2_xattr_set_acl_access, +	.get	= ocfs2_xattr_get_acl, +	.set	= ocfs2_xattr_set_acl,  };  struct xattr_handler ocfs2_xattr_acl_default_handler = {  	.prefix	= POSIX_ACL_XATTR_DEFAULT, +	.flags	= ACL_TYPE_DEFAULT,  	.list	= ocfs2_xattr_list_acl_default, -	.get	= ocfs2_xattr_get_acl_default, -	.set	= ocfs2_xattr_set_acl_default, +	.get	= ocfs2_xattr_get_acl, +	.set	= ocfs2_xattr_set_acl,  }; diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index fe3419068df2..43c114831c0d 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -205,8 +205,6 @@ static int ocfs2_get_xattr_tree_value_root(struct super_block *sb,  					   int offset,  					   struct ocfs2_xattr_value_root **xv,  					   struct buffer_head **bh); -static int ocfs2_xattr_security_set(struct inode *inode, const char *name, -				    const void *value, size_t size, int flags);  static inline u16 ocfs2_xattr_buckets_per_cluster(struct ocfs2_super *osb)  { @@ -6978,9 +6976,9 @@ int ocfs2_init_security_and_acl(struct inode *dir,  	ret = ocfs2_init_security_get(inode, dir, &si);  	if (!ret) { -		ret = ocfs2_xattr_security_set(inode, si.name, -					       si.value, si.value_len, -					       XATTR_CREATE); +		ret = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY, +				      si.name, si.value, si.value_len, +				      XATTR_CREATE);  		if (ret) {  			mlog_errno(ret);  			goto leave; @@ -7008,9 +7006,9 @@ leave:  /*   * 'security' attributes support   */ -static size_t ocfs2_xattr_security_list(struct inode *inode, char *list, +static size_t ocfs2_xattr_security_list(struct dentry *dentry, char *list,  					size_t list_size, const char *name, -					size_t name_len) +					size_t name_len, int type)  {  	const size_t prefix_len = XATTR_SECURITY_PREFIX_LEN;  	const size_t total_len = prefix_len + name_len + 1; @@ -7023,23 +7021,23 @@ static size_t ocfs2_xattr_security_list(struct inode *inode, char *list,  	return total_len;  } -static int ocfs2_xattr_security_get(struct inode *inode, const char *name, -				    void *buffer, size_t size) +static int ocfs2_xattr_security_get(struct dentry *dentry, const char *name, +				    void *buffer, size_t size, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return ocfs2_xattr_get(inode, OCFS2_XATTR_INDEX_SECURITY, name, -			       buffer, size); +	return ocfs2_xattr_get(dentry->d_inode, OCFS2_XATTR_INDEX_SECURITY, +			       name, buffer, size);  } -static int ocfs2_xattr_security_set(struct inode *inode, const char *name, -				    const void *value, size_t size, int flags) +static int ocfs2_xattr_security_set(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY, name, value, -			       size, flags); +	return ocfs2_xattr_set(dentry->d_inode, OCFS2_XATTR_INDEX_SECURITY, +			       name, value, size, flags);  }  int ocfs2_init_security_get(struct inode *inode, @@ -7076,9 +7074,9 @@ struct xattr_handler ocfs2_xattr_security_handler = {  /*   * 'trusted' attributes support   */ -static size_t ocfs2_xattr_trusted_list(struct inode *inode, char *list, +static size_t ocfs2_xattr_trusted_list(struct dentry *dentry, char *list,  				       size_t list_size, const char *name, -				       size_t name_len) +				       size_t name_len, int type)  {  	const size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN;  	const size_t total_len = prefix_len + name_len + 1; @@ -7091,23 +7089,23 @@ static size_t ocfs2_xattr_trusted_list(struct inode *inode, char *list,  	return total_len;  } -static int ocfs2_xattr_trusted_get(struct inode *inode, const char *name, -				   void *buffer, size_t size) +static int ocfs2_xattr_trusted_get(struct dentry *dentry, const char *name, +		void *buffer, size_t size, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return ocfs2_xattr_get(inode, OCFS2_XATTR_INDEX_TRUSTED, name, -			       buffer, size); +	return ocfs2_xattr_get(dentry->d_inode, OCFS2_XATTR_INDEX_TRUSTED, +			       name, buffer, size);  } -static int ocfs2_xattr_trusted_set(struct inode *inode, const char *name, -				   const void *value, size_t size, int flags) +static int ocfs2_xattr_trusted_set(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int type)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_TRUSTED, name, value, -			       size, flags); +	return ocfs2_xattr_set(dentry->d_inode, OCFS2_XATTR_INDEX_TRUSTED, +			       name, value, size, flags);  }  struct xattr_handler ocfs2_xattr_trusted_handler = { @@ -7120,13 +7118,13 @@ struct xattr_handler ocfs2_xattr_trusted_handler = {  /*   * 'user' attributes support   */ -static size_t ocfs2_xattr_user_list(struct inode *inode, char *list, +static size_t ocfs2_xattr_user_list(struct dentry *dentry, char *list,  				    size_t list_size, const char *name, -				    size_t name_len) +				    size_t name_len, int type)  {  	const size_t prefix_len = XATTR_USER_PREFIX_LEN;  	const size_t total_len = prefix_len + name_len + 1; -	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); +	struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);  	if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR)  		return 0; @@ -7139,31 +7137,31 @@ static size_t ocfs2_xattr_user_list(struct inode *inode, char *list,  	return total_len;  } -static int ocfs2_xattr_user_get(struct inode *inode, const char *name, -				void *buffer, size_t size) +static int ocfs2_xattr_user_get(struct dentry *dentry, const char *name, +		void *buffer, size_t size, int type)  { -	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); +	struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);  	if (strcmp(name, "") == 0)  		return -EINVAL;  	if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR)  		return -EOPNOTSUPP; -	return ocfs2_xattr_get(inode, OCFS2_XATTR_INDEX_USER, name, +	return ocfs2_xattr_get(dentry->d_inode, OCFS2_XATTR_INDEX_USER, name,  			       buffer, size);  } -static int ocfs2_xattr_user_set(struct inode *inode, const char *name, -				const void *value, size_t size, int flags) +static int ocfs2_xattr_user_set(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int type)  { -	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); +	struct ocfs2_super *osb = OCFS2_SB(dentry->d_sb);  	if (strcmp(name, "") == 0)  		return -EINVAL;  	if (osb->s_mount_opt & OCFS2_MOUNT_NOUSERXATTR)  		return -EOPNOTSUPP; -	return ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_USER, name, value, -			       size, flags); +	return ocfs2_xattr_set(dentry->d_inode, OCFS2_XATTR_INDEX_USER, +			       name, value, size, flags);  }  struct xattr_handler ocfs2_xattr_user_handler = { diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 58aa8e75f7f5..8c7033a8b67e 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -48,6 +48,7 @@  #include <net/checksum.h>  #include <linux/stat.h>  #include <linux/quotaops.h> +#include <linux/security.h>  #define PRIVROOT_NAME ".reiserfs_priv"  #define XAROOT_NAME   "xattrs" @@ -726,15 +727,14 @@ ssize_t  reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer,  		  size_t size)  { -	struct inode *inode = dentry->d_inode;  	struct xattr_handler *handler; -	handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name); +	handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); -	if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1) +	if (!handler || get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)  		return -EOPNOTSUPP; -	return handler->get(inode, name, buffer, size); +	return handler->get(dentry, name, buffer, size, handler->flags);  }  /* @@ -746,15 +746,14 @@ int  reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value,  		  size_t size, int flags)  { -	struct inode *inode = dentry->d_inode;  	struct xattr_handler *handler; -	handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name); +	handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); -	if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1) +	if (!handler || get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)  		return -EOPNOTSUPP; -	return handler->set(inode, name, value, size, flags); +	return handler->set(dentry, name, value, size, flags, handler->flags);  }  /* @@ -764,21 +763,20 @@ reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value,   */  int reiserfs_removexattr(struct dentry *dentry, const char *name)  { -	struct inode *inode = dentry->d_inode;  	struct xattr_handler *handler; -	handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name); +	handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name); -	if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1) +	if (!handler || get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)  		return -EOPNOTSUPP; -	return handler->set(inode, name, NULL, 0, XATTR_REPLACE); +	return handler->set(dentry, name, NULL, 0, XATTR_REPLACE, handler->flags);  }  struct listxattr_buf {  	size_t size;  	size_t pos;  	char *buf; -	struct inode *inode; +	struct dentry *dentry;  };  static int listxattr_filler(void *buf, const char *name, int namelen, @@ -789,17 +787,19 @@ static int listxattr_filler(void *buf, const char *name, int namelen,  	if (name[0] != '.' ||  	    (namelen != 1 && (name[1] != '.' || namelen != 2))) {  		struct xattr_handler *handler; -		handler = find_xattr_handler_prefix(b->inode->i_sb->s_xattr, +		handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr,  						    name);  		if (!handler)	/* Unsupported xattr name */  			return 0;  		if (b->buf) { -			size = handler->list(b->inode, b->buf + b->pos, -					 b->size, name, namelen); +			size = handler->list(b->dentry, b->buf + b->pos, +					 b->size, name, namelen, +					 handler->flags);  			if (size > b->size)  				return -ERANGE;  		} else { -			size = handler->list(b->inode, NULL, 0, name, namelen); +			size = handler->list(b->dentry, NULL, 0, name, +					     namelen, handler->flags);  		}  		b->pos += size; @@ -820,7 +820,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)  	int err = 0;  	loff_t pos = 0;  	struct listxattr_buf buf = { -		.inode = dentry->d_inode, +		.dentry = dentry,  		.buf = buffer,  		.size = buffer ? size : 0,  	}; diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index 35d6e672a279..cc32e6ada67b 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c @@ -15,8 +15,10 @@ static int reiserfs_set_acl(struct reiserfs_transaction_handle *th,  			    struct posix_acl *acl);  static int -xattr_set_acl(struct inode *inode, int type, const void *value, size_t size) +posix_acl_set(struct dentry *dentry, const char *name, const void *value, +		size_t size, int flags, int type)  { +	struct inode *inode = dentry->d_inode;  	struct posix_acl *acl;  	int error, error2;  	struct reiserfs_transaction_handle th; @@ -60,15 +62,16 @@ xattr_set_acl(struct inode *inode, int type, const void *value, size_t size)  }  static int -xattr_get_acl(struct inode *inode, int type, void *buffer, size_t size) +posix_acl_get(struct dentry *dentry, const char *name, void *buffer, +		size_t size, int type)  {  	struct posix_acl *acl;  	int error; -	if (!reiserfs_posixacl(inode->i_sb)) +	if (!reiserfs_posixacl(dentry->d_sb))  		return -EOPNOTSUPP; -	acl = reiserfs_get_acl(inode, type); +	acl = reiserfs_get_acl(dentry->d_inode, type);  	if (IS_ERR(acl))  		return PTR_ERR(acl);  	if (acl == NULL) @@ -482,30 +485,12 @@ int reiserfs_acl_chmod(struct inode *inode)  	return error;  } -static int -posix_acl_access_get(struct inode *inode, const char *name, -		     void *buffer, size_t size) -{ -	if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1) -		return -EINVAL; -	return xattr_get_acl(inode, ACL_TYPE_ACCESS, buffer, size); -} - -static int -posix_acl_access_set(struct inode *inode, const char *name, -		     const void *value, size_t size, int flags) -{ -	if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1) -		return -EINVAL; -	return xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size); -} - -static size_t posix_acl_access_list(struct inode *inode, char *list, +static size_t posix_acl_access_list(struct dentry *dentry, char *list,  				    size_t list_size, const char *name, -				    size_t name_len) +				    size_t name_len, int type)  {  	const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS); -	if (!reiserfs_posixacl(inode->i_sb)) +	if (!reiserfs_posixacl(dentry->d_sb))  		return 0;  	if (list && size <= list_size)  		memcpy(list, POSIX_ACL_XATTR_ACCESS, size); @@ -514,35 +499,18 @@ static size_t posix_acl_access_list(struct inode *inode, char *list,  struct xattr_handler reiserfs_posix_acl_access_handler = {  	.prefix = POSIX_ACL_XATTR_ACCESS, -	.get = posix_acl_access_get, -	.set = posix_acl_access_set, +	.flags = ACL_TYPE_ACCESS, +	.get = posix_acl_get, +	.set = posix_acl_set,  	.list = posix_acl_access_list,  }; -static int -posix_acl_default_get(struct inode *inode, const char *name, -		      void *buffer, size_t size) -{ -	if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) -		return -EINVAL; -	return xattr_get_acl(inode, ACL_TYPE_DEFAULT, buffer, size); -} - -static int -posix_acl_default_set(struct inode *inode, const char *name, -		      const void *value, size_t size, int flags) -{ -	if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) -		return -EINVAL; -	return xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); -} - -static size_t posix_acl_default_list(struct inode *inode, char *list, +static size_t posix_acl_default_list(struct dentry *dentry, char *list,  				     size_t list_size, const char *name, -				     size_t name_len) +				     size_t name_len, int type)  {  	const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT); -	if (!reiserfs_posixacl(inode->i_sb)) +	if (!reiserfs_posixacl(dentry->d_sb))  		return 0;  	if (list && size <= list_size)  		memcpy(list, POSIX_ACL_XATTR_DEFAULT, size); @@ -551,7 +519,8 @@ static size_t posix_acl_default_list(struct inode *inode, char *list,  struct xattr_handler reiserfs_posix_acl_default_handler = {  	.prefix = POSIX_ACL_XATTR_DEFAULT, -	.get = posix_acl_default_get, -	.set = posix_acl_default_set, +	.flags = ACL_TYPE_DEFAULT, +	.get = posix_acl_get, +	.set = posix_acl_set,  	.list = posix_acl_default_list,  }; diff --git a/fs/reiserfs/xattr_security.c b/fs/reiserfs/xattr_security.c index a92c8792c0f6..d8b5bfcbdd30 100644 --- a/fs/reiserfs/xattr_security.c +++ b/fs/reiserfs/xattr_security.c @@ -8,36 +8,37 @@  #include <asm/uaccess.h>  static int -security_get(struct inode *inode, const char *name, void *buffer, size_t size) +security_get(struct dentry *dentry, const char *name, void *buffer, size_t size, +		int handler_flags)  {  	if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))  		return -EINVAL; -	if (IS_PRIVATE(inode)) +	if (IS_PRIVATE(dentry->d_inode))  		return -EPERM; -	return reiserfs_xattr_get(inode, name, buffer, size); +	return reiserfs_xattr_get(dentry->d_inode, name, buffer, size);  }  static int -security_set(struct inode *inode, const char *name, const void *buffer, -	     size_t size, int flags) +security_set(struct dentry *dentry, const char *name, const void *buffer, +	     size_t size, int flags, int handler_flags)  {  	if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))  		return -EINVAL; -	if (IS_PRIVATE(inode)) +	if (IS_PRIVATE(dentry->d_inode))  		return -EPERM; -	return reiserfs_xattr_set(inode, name, buffer, size, flags); +	return reiserfs_xattr_set(dentry->d_inode, name, buffer, size, flags);  } -static size_t security_list(struct inode *inode, char *list, size_t list_len, -			    const char *name, size_t namelen) +static size_t security_list(struct dentry *dentry, char *list, size_t list_len, +			    const char *name, size_t namelen, int handler_flags)  {  	const size_t len = namelen + 1; -	if (IS_PRIVATE(inode)) +	if (IS_PRIVATE(dentry->d_inode))  		return 0;  	if (list && len <= list_len) { diff --git a/fs/reiserfs/xattr_trusted.c b/fs/reiserfs/xattr_trusted.c index a865042f75e2..5b08aaca3daf 100644 --- a/fs/reiserfs/xattr_trusted.c +++ b/fs/reiserfs/xattr_trusted.c @@ -8,36 +8,37 @@  #include <asm/uaccess.h>  static int -trusted_get(struct inode *inode, const char *name, void *buffer, size_t size) +trusted_get(struct dentry *dentry, const char *name, void *buffer, size_t size, +	    int handler_flags)  {  	if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))  		return -EINVAL; -	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)) +	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(dentry->d_inode))  		return -EPERM; -	return reiserfs_xattr_get(inode, name, buffer, size); +	return reiserfs_xattr_get(dentry->d_inode, name, buffer, size);  }  static int -trusted_set(struct inode *inode, const char *name, const void *buffer, -	    size_t size, int flags) +trusted_set(struct dentry *dentry, const char *name, const void *buffer, +	    size_t size, int flags, int handler_flags)  {  	if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))  		return -EINVAL; -	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)) +	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(dentry->d_inode))  		return -EPERM; -	return reiserfs_xattr_set(inode, name, buffer, size, flags); +	return reiserfs_xattr_set(dentry->d_inode, name, buffer, size, flags);  } -static size_t trusted_list(struct inode *inode, char *list, size_t list_size, -			   const char *name, size_t name_len) +static size_t trusted_list(struct dentry *dentry, char *list, size_t list_size, +			   const char *name, size_t name_len, int handler_flags)  {  	const size_t len = name_len + 1; -	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)) +	if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(dentry->d_inode))  		return 0;  	if (list && len <= list_size) { diff --git a/fs/reiserfs/xattr_user.c b/fs/reiserfs/xattr_user.c index e3238dc4f3db..75d59c49b911 100644 --- a/fs/reiserfs/xattr_user.c +++ b/fs/reiserfs/xattr_user.c @@ -7,34 +7,35 @@  #include <asm/uaccess.h>  static int -user_get(struct inode *inode, const char *name, void *buffer, size_t size) +user_get(struct dentry *dentry, const char *name, void *buffer, size_t size, +	 int handler_flags)  {  	if (strlen(name) < sizeof(XATTR_USER_PREFIX))  		return -EINVAL; -	if (!reiserfs_xattrs_user(inode->i_sb)) +	if (!reiserfs_xattrs_user(dentry->d_sb))  		return -EOPNOTSUPP; -	return reiserfs_xattr_get(inode, name, buffer, size); +	return reiserfs_xattr_get(dentry->d_inode, name, buffer, size);  }  static int -user_set(struct inode *inode, const char *name, const void *buffer, -	 size_t size, int flags) +user_set(struct dentry *dentry, const char *name, const void *buffer, +	 size_t size, int flags, int handler_flags)  {  	if (strlen(name) < sizeof(XATTR_USER_PREFIX))  		return -EINVAL; -	if (!reiserfs_xattrs_user(inode->i_sb)) +	if (!reiserfs_xattrs_user(dentry->d_sb))  		return -EOPNOTSUPP; -	return reiserfs_xattr_set(inode, name, buffer, size, flags); +	return reiserfs_xattr_set(dentry->d_inode, name, buffer, size, flags);  } -static size_t user_list(struct inode *inode, char *list, size_t list_size, -			const char *name, size_t name_len) +static size_t user_list(struct dentry *dentry, char *list, size_t list_size, +			const char *name, size_t name_len, int handler_flags)  {  	const size_t len = name_len + 1; -	if (!reiserfs_xattrs_user(inode->i_sb)) +	if (!reiserfs_xattrs_user(dentry->d_sb))  		return 0;  	if (list && len <= list_size) {  		memcpy(list, name, name_len); diff --git a/fs/xattr.c b/fs/xattr.c index 6d4f6d3449fb..46f87e828b48 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -615,12 +615,11 @@ ssize_t  generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size)  {  	struct xattr_handler *handler; -	struct inode *inode = dentry->d_inode; -	handler = xattr_resolve_name(inode->i_sb->s_xattr, &name); +	handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);  	if (!handler)  		return -EOPNOTSUPP; -	return handler->get(inode, name, buffer, size); +	return handler->get(dentry, name, buffer, size, handler->flags);  }  /* @@ -630,18 +629,20 @@ generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t s  ssize_t  generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)  { -	struct inode *inode = dentry->d_inode; -	struct xattr_handler *handler, **handlers = inode->i_sb->s_xattr; +	struct xattr_handler *handler, **handlers = dentry->d_sb->s_xattr;  	unsigned int size = 0;  	if (!buffer) { -		for_each_xattr_handler(handlers, handler) -			size += handler->list(inode, NULL, 0, NULL, 0); +		for_each_xattr_handler(handlers, handler) { +			size += handler->list(dentry, NULL, 0, NULL, 0, +					      handler->flags); +		}  	} else {  		char *buf = buffer;  		for_each_xattr_handler(handlers, handler) { -			size = handler->list(inode, buf, buffer_size, NULL, 0); +			size = handler->list(dentry, buf, buffer_size, +					     NULL, 0, handler->flags);  			if (size > buffer_size)  				return -ERANGE;  			buf += size; @@ -659,14 +660,13 @@ int  generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags)  {  	struct xattr_handler *handler; -	struct inode *inode = dentry->d_inode;  	if (size == 0)  		value = "";  /* empty EA, do not remove */ -	handler = xattr_resolve_name(inode->i_sb->s_xattr, &name); +	handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);  	if (!handler)  		return -EOPNOTSUPP; -	return handler->set(inode, name, value, size, flags); +	return handler->set(dentry, name, value, size, 0, handler->flags);  }  /* @@ -677,12 +677,12 @@ int  generic_removexattr(struct dentry *dentry, const char *name)  {  	struct xattr_handler *handler; -	struct inode *inode = dentry->d_inode; -	handler = xattr_resolve_name(inode->i_sb->s_xattr, &name); +	handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);  	if (!handler)  		return -EOPNOTSUPP; -	return handler->set(inode, name, NULL, 0, XATTR_REPLACE); +	return handler->set(dentry, name, NULL, 0, +			    XATTR_REPLACE, handler->flags);  }  EXPORT_SYMBOL(generic_getxattr); diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c index 69e598b6986f..2512125dfa7c 100644 --- a/fs/xfs/linux-2.6/xfs_acl.c +++ b/fs/xfs/linux-2.6/xfs_acl.c @@ -354,37 +354,14 @@ xfs_acl_chmod(struct inode *inode)  	return error;  } -/* - * System xattr handlers. - * - * Currently Posix ACLs are the only system namespace extended attribute - * handlers supported by XFS, so we just implement the handlers here. - * If we ever support other system extended attributes this will need - * some refactoring. - */ -  static int -xfs_decode_acl(const char *name) -{ -	if (strcmp(name, "posix_acl_access") == 0) -		return ACL_TYPE_ACCESS; -	else if (strcmp(name, "posix_acl_default") == 0) -		return ACL_TYPE_DEFAULT; -	return -EINVAL; -} - -static int -xfs_xattr_system_get(struct inode *inode, const char *name, -		void *value, size_t size) +xfs_xattr_acl_get(struct dentry *dentry, const char *name, +		void *value, size_t size, int type)  {  	struct posix_acl *acl; -	int type, error; - -	type = xfs_decode_acl(name); -	if (type < 0) -		return type; +	int error; -	acl = xfs_get_acl(inode, type); +	acl = xfs_get_acl(dentry->d_inode, type);  	if (IS_ERR(acl))  		return PTR_ERR(acl);  	if (acl == NULL) @@ -397,15 +374,13 @@ xfs_xattr_system_get(struct inode *inode, const char *name,  }  static int -xfs_xattr_system_set(struct inode *inode, const char *name, -		const void *value, size_t size, int flags) +xfs_xattr_acl_set(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int type)  { +	struct inode *inode = dentry->d_inode;  	struct posix_acl *acl = NULL; -	int error = 0, type; +	int error = 0; -	type = xfs_decode_acl(name); -	if (type < 0) -		return type;  	if (flags & XATTR_CREATE)  		return -EINVAL;  	if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) @@ -462,8 +437,16 @@ xfs_xattr_system_set(struct inode *inode, const char *name,  	return error;  } -struct xattr_handler xfs_xattr_system_handler = { -	.prefix	= XATTR_SYSTEM_PREFIX, -	.get	= xfs_xattr_system_get, -	.set	= xfs_xattr_system_set, +struct xattr_handler xfs_xattr_acl_access_handler = { +	.prefix	= POSIX_ACL_XATTR_ACCESS, +	.flags	= ACL_TYPE_ACCESS, +	.get	= xfs_xattr_acl_get, +	.set	= xfs_xattr_acl_set, +}; + +struct xattr_handler xfs_xattr_acl_default_handler = { +	.prefix	= POSIX_ACL_XATTR_DEFAULT, +	.flags	= ACL_TYPE_DEFAULT, +	.get	= xfs_xattr_acl_get, +	.set	= xfs_xattr_acl_set,  }; diff --git a/fs/xfs/linux-2.6/xfs_xattr.c b/fs/xfs/linux-2.6/xfs_xattr.c index 497c7fb75cc1..0b1878857fc3 100644 --- a/fs/xfs/linux-2.6/xfs_xattr.c +++ b/fs/xfs/linux-2.6/xfs_xattr.c @@ -30,10 +30,10 @@  static int -__xfs_xattr_get(struct inode *inode, const char *name, +xfs_xattr_get(struct dentry *dentry, const char *name,  		void *value, size_t size, int xflags)  { -	struct xfs_inode *ip = XFS_I(inode); +	struct xfs_inode *ip = XFS_I(dentry->d_inode);  	int error, asize = size;  	if (strcmp(name, "") == 0) @@ -52,10 +52,10 @@ __xfs_xattr_get(struct inode *inode, const char *name,  }  static int -__xfs_xattr_set(struct inode *inode, const char *name, const void *value, +xfs_xattr_set(struct dentry *dentry, const char *name, const void *value,  		size_t size, int flags, int xflags)  { -	struct xfs_inode *ip = XFS_I(inode); +	struct xfs_inode *ip = XFS_I(dentry->d_inode);  	if (strcmp(name, "") == 0)  		return -EINVAL; @@ -71,75 +71,34 @@ __xfs_xattr_set(struct inode *inode, const char *name, const void *value,  	return -xfs_attr_set(ip, name, (void *)value, size, xflags);  } -static int -xfs_xattr_user_get(struct inode *inode, const char *name, -		void *value, size_t size) -{ -	return __xfs_xattr_get(inode, name, value, size, 0); -} - -static int -xfs_xattr_user_set(struct inode *inode, const char *name, -		const void *value, size_t size, int flags) -{ -	return __xfs_xattr_set(inode, name, value, size, flags, 0); -} -  static struct xattr_handler xfs_xattr_user_handler = {  	.prefix	= XATTR_USER_PREFIX, -	.get	= xfs_xattr_user_get, -	.set	= xfs_xattr_user_set, +	.flags	= 0, /* no flags implies user namespace */ +	.get	= xfs_xattr_get, +	.set	= xfs_xattr_set,  }; - -static int -xfs_xattr_trusted_get(struct inode *inode, const char *name, -		void *value, size_t size) -{ -	return __xfs_xattr_get(inode, name, value, size, ATTR_ROOT); -} - -static int -xfs_xattr_trusted_set(struct inode *inode, const char *name, -		const void *value, size_t size, int flags) -{ -	return __xfs_xattr_set(inode, name, value, size, flags, ATTR_ROOT); -} -  static struct xattr_handler xfs_xattr_trusted_handler = {  	.prefix	= XATTR_TRUSTED_PREFIX, -	.get	= xfs_xattr_trusted_get, -	.set	= xfs_xattr_trusted_set, +	.flags	= ATTR_ROOT, +	.get	= xfs_xattr_get, +	.set	= xfs_xattr_set,  }; - -static int -xfs_xattr_secure_get(struct inode *inode, const char *name, -		void *value, size_t size) -{ -	return __xfs_xattr_get(inode, name, value, size, ATTR_SECURE); -} - -static int -xfs_xattr_secure_set(struct inode *inode, const char *name, -		const void *value, size_t size, int flags) -{ -	return __xfs_xattr_set(inode, name, value, size, flags, ATTR_SECURE); -} -  static struct xattr_handler xfs_xattr_security_handler = {  	.prefix	= XATTR_SECURITY_PREFIX, -	.get	= xfs_xattr_secure_get, -	.set	= xfs_xattr_secure_set, +	.flags	= ATTR_SECURE, +	.get	= xfs_xattr_get, +	.set	= xfs_xattr_set,  }; -  struct xattr_handler *xfs_xattr_handlers[] = {  	&xfs_xattr_user_handler,  	&xfs_xattr_trusted_handler,  	&xfs_xattr_security_handler,  #ifdef CONFIG_XFS_POSIX_ACL -	&xfs_xattr_system_handler, +	&xfs_xattr_acl_access_handler, +	&xfs_xattr_acl_default_handler,  #endif  	NULL  }; diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 947b150df8ed..00fd357c3e46 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -49,7 +49,8 @@ extern int xfs_acl_chmod(struct inode *inode);  extern int posix_acl_access_exists(struct inode *inode);  extern int posix_acl_default_exists(struct inode *inode); -extern struct xattr_handler xfs_xattr_system_handler; +extern struct xattr_handler xfs_xattr_acl_access_handler; +extern struct xattr_handler xfs_xattr_acl_default_handler;  #else  # define xfs_check_acl					NULL  # define xfs_get_acl(inode, type)			NULL diff --git a/include/linux/xattr.h b/include/linux/xattr.h index 5c84af8c5f6f..fb9b7e6e1e2d 100644 --- a/include/linux/xattr.h +++ b/include/linux/xattr.h @@ -38,12 +38,13 @@ struct dentry;  struct xattr_handler {  	char *prefix; -	size_t (*list)(struct inode *inode, char *list, size_t list_size, -		       const char *name, size_t name_len); -	int (*get)(struct inode *inode, const char *name, void *buffer, -		   size_t size); -	int (*set)(struct inode *inode, const char *name, const void *buffer, -		   size_t size, int flags); +	int flags;	/* fs private flags passed back to the handlers */ +	size_t (*list)(struct dentry *dentry, char *list, size_t list_size, +		       const char *name, size_t name_len, int handler_flags); +	int (*get)(struct dentry *dentry, const char *name, void *buffer, +		   size_t size, int handler_flags); +	int (*set)(struct dentry *dentry, const char *name, const void *buffer, +		   size_t size, int flags, int handler_flags);  };  ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t); diff --git a/mm/shmem.c b/mm/shmem.c index adf8033afd52..3cd32c2ea0a0 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -2042,27 +2042,28 @@ static const struct inode_operations shmem_symlink_inode_operations = {   * filesystem level, though.   */ -static size_t shmem_xattr_security_list(struct inode *inode, char *list, +static size_t shmem_xattr_security_list(struct dentry *dentry, char *list,  					size_t list_len, const char *name, -					size_t name_len) +					size_t name_len, int handler_flags)  { -	return security_inode_listsecurity(inode, list, list_len); +	return security_inode_listsecurity(dentry->d_inode, list, list_len);  } -static int shmem_xattr_security_get(struct inode *inode, const char *name, -				    void *buffer, size_t size) +static int shmem_xattr_security_get(struct dentry *dentry, const char *name, +		void *buffer, size_t size, int handler_flags)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return xattr_getsecurity(inode, name, buffer, size); +	return xattr_getsecurity(dentry->d_inode, name, buffer, size);  } -static int shmem_xattr_security_set(struct inode *inode, const char *name, -				    const void *value, size_t size, int flags) +static int shmem_xattr_security_set(struct dentry *dentry, const char *name, +		const void *value, size_t size, int flags, int handler_flags)  {  	if (strcmp(name, "") == 0)  		return -EINVAL; -	return security_inode_setsecurity(inode, name, value, size, flags); +	return security_inode_setsecurity(dentry->d_inode, name, value, +					  size, flags);  }  static struct xattr_handler shmem_xattr_security_handler = { diff --git a/mm/shmem_acl.c b/mm/shmem_acl.c index df2c87fdae50..f8d5330ec0d7 100644 --- a/mm/shmem_acl.c +++ b/mm/shmem_acl.c @@ -63,86 +63,48 @@ struct generic_acl_operations shmem_acl_ops = {  	.setacl = shmem_set_acl,  }; -/** - * shmem_list_acl_access, shmem_get_acl_access, shmem_set_acl_access, - * shmem_xattr_acl_access_handler  -  plumbing code to implement the - * system.posix_acl_access xattr using the generic acl functions. - */ -  static size_t -shmem_list_acl_access(struct inode *inode, char *list, size_t list_size, -		      const char *name, size_t name_len) +shmem_xattr_list_acl(struct dentry *dentry, char *list, size_t list_size, +		const char *name, size_t name_len, int type)  { -	return generic_acl_list(inode, &shmem_acl_ops, ACL_TYPE_ACCESS, -				list, list_size); +	return generic_acl_list(dentry->d_inode, &shmem_acl_ops, +				type, list, list_size);  }  static int -shmem_get_acl_access(struct inode *inode, const char *name, void *buffer, -		     size_t size) +shmem_xattr_get_acl(struct dentry *dentry, const char *name, void *buffer, +		     size_t size, int type)  {  	if (strcmp(name, "") != 0)  		return -EINVAL; -	return generic_acl_get(inode, &shmem_acl_ops, ACL_TYPE_ACCESS, buffer, -			       size); +	return generic_acl_get(dentry->d_inode, &shmem_acl_ops, type, +			       buffer, size);  }  static int -shmem_set_acl_access(struct inode *inode, const char *name, const void *value, -		     size_t size, int flags) +shmem_xattr_set_acl(struct dentry *dentry, const char *name, const void *value, +		     size_t size, int flags, int type)  {  	if (strcmp(name, "") != 0)  		return -EINVAL; -	return generic_acl_set(inode, &shmem_acl_ops, ACL_TYPE_ACCESS, value, -			       size); +	return generic_acl_set(dentry->d_inode, &shmem_acl_ops, type, +			       value, size);  }  struct xattr_handler shmem_xattr_acl_access_handler = {  	.prefix = POSIX_ACL_XATTR_ACCESS, -	.list	= shmem_list_acl_access, -	.get	= shmem_get_acl_access, -	.set	= shmem_set_acl_access, +	.flags	= ACL_TYPE_ACCESS, +	.list	= shmem_xattr_list_acl, +	.get	= shmem_xattr_get_acl, +	.set	= shmem_xattr_set_acl,  }; -/** - * shmem_list_acl_default, shmem_get_acl_default, shmem_set_acl_default, - * shmem_xattr_acl_default_handler  -  plumbing code to implement the - * system.posix_acl_default xattr using the generic acl functions. - */ - -static size_t -shmem_list_acl_default(struct inode *inode, char *list, size_t list_size, -		       const char *name, size_t name_len) -{ -	return generic_acl_list(inode, &shmem_acl_ops, ACL_TYPE_DEFAULT, -				list, list_size); -} - -static int -shmem_get_acl_default(struct inode *inode, const char *name, void *buffer, -		      size_t size) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return generic_acl_get(inode, &shmem_acl_ops, ACL_TYPE_DEFAULT, buffer, -			       size); -} - -static int -shmem_set_acl_default(struct inode *inode, const char *name, const void *value, -		      size_t size, int flags) -{ -	if (strcmp(name, "") != 0) -		return -EINVAL; -	return generic_acl_set(inode, &shmem_acl_ops, ACL_TYPE_DEFAULT, value, -			       size); -} -  struct xattr_handler shmem_xattr_acl_default_handler = {  	.prefix = POSIX_ACL_XATTR_DEFAULT, -	.list	= shmem_list_acl_default, -	.get	= shmem_get_acl_default, -	.set	= shmem_set_acl_default, +	.flags	= ACL_TYPE_DEFAULT, +	.list	= shmem_xattr_list_acl, +	.get	= shmem_xattr_get_acl, +	.set	= shmem_xattr_set_acl,  };  /** | 
