diff options
Diffstat (limited to 'fs/hfsplus/posix_acl.c')
| -rw-r--r-- | fs/hfsplus/posix_acl.c | 168 | 
1 files changed, 17 insertions, 151 deletions
diff --git a/fs/hfsplus/posix_acl.c b/fs/hfsplus/posix_acl.c index b609cc14c72..df0c9af68d0 100644 --- a/fs/hfsplus/posix_acl.c +++ b/fs/hfsplus/posix_acl.c @@ -17,9 +17,7 @@ struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type)  	char *value = NULL;  	ssize_t size; -	acl = get_cached_acl(inode, type); -	if (acl != ACL_NOT_CACHED) -		return acl; +	hfs_dbg(ACL_MOD, "[%s]: ino %lu\n", __func__, inode->i_ino);  	switch (type) {  	case ACL_TYPE_ACCESS: @@ -56,17 +54,15 @@ struct posix_acl *hfsplus_get_posix_acl(struct inode *inode, int type)  	return acl;  } -static int hfsplus_set_posix_acl(struct inode *inode, -					int type, -					struct posix_acl *acl) +int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl, +		int type)  {  	int err;  	char *xattr_name;  	size_t size = 0;  	char *value = NULL; -	if (S_ISLNK(inode->i_mode)) -		return -EOPNOTSUPP; +	hfs_dbg(ACL_MOD, "[%s]: ino %lu\n", __func__, inode->i_ino);  	switch (type) {  	case ACL_TYPE_ACCESS: @@ -115,7 +111,7 @@ end_set_acl:  int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir)  {  	int err = 0; -	struct posix_acl *acl = NULL; +	struct posix_acl *default_acl, *acl;  	hfs_dbg(ACL_MOD,  		"[%s]: ino %lu, dir->ino %lu\n", @@ -124,151 +120,21 @@ int hfsplus_init_posix_acl(struct inode *inode, struct inode *dir)  	if (S_ISLNK(inode->i_mode))  		return 0; -	acl = hfsplus_get_posix_acl(dir, ACL_TYPE_DEFAULT); -	if (IS_ERR(acl)) -		return PTR_ERR(acl); - -	if (acl) { -		if (S_ISDIR(inode->i_mode)) { -			err = hfsplus_set_posix_acl(inode, -							ACL_TYPE_DEFAULT, -							acl); -			if (unlikely(err)) -				goto init_acl_cleanup; -		} - -		err = posix_acl_create(&acl, GFP_NOFS, &inode->i_mode); -		if (unlikely(err < 0)) -			return err; - -		if (err > 0) -			err = hfsplus_set_posix_acl(inode, -							ACL_TYPE_ACCESS, -							acl); -	} else -		inode->i_mode &= ~current_umask(); - -init_acl_cleanup: -	posix_acl_release(acl); -	return err; -} - -int hfsplus_posix_acl_chmod(struct inode *inode) -{ -	int err; -	struct posix_acl *acl; - -	hfs_dbg(ACL_MOD, "[%s]: ino %lu\n", __func__, inode->i_ino); - -	if (S_ISLNK(inode->i_mode)) -		return -EOPNOTSUPP; - -	acl = hfsplus_get_posix_acl(inode, ACL_TYPE_ACCESS); -	if (IS_ERR(acl) || !acl) -		return PTR_ERR(acl); - -	err = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); -	if (unlikely(err)) +	err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl); +	if (err)  		return err; -	err = hfsplus_set_posix_acl(inode, ACL_TYPE_ACCESS, acl); -	posix_acl_release(acl); -	return err; -} - -static int hfsplus_xattr_get_posix_acl(struct dentry *dentry, -					const char *name, -					void *buffer, -					size_t size, -					int type) -{ -	int err = 0; -	struct posix_acl *acl; - -	hfs_dbg(ACL_MOD, -		"[%s]: ino %lu, buffer %p, size %zu, type %#x\n", -		__func__, dentry->d_inode->i_ino, buffer, size, type); - -	if (strcmp(name, "") != 0) -		return -EINVAL; - -	acl = hfsplus_get_posix_acl(dentry->d_inode, type); -	if (IS_ERR(acl)) -		return PTR_ERR(acl); -	if (acl == NULL) -		return -ENODATA; - -	err = posix_acl_to_xattr(&init_user_ns, acl, buffer, size); -	posix_acl_release(acl); - -	return err; -} - -static int hfsplus_xattr_set_posix_acl(struct dentry *dentry, -					const char *name, -					const void *value, -					size_t size, -					int flags, -					int type) -{ -	int err = 0; -	struct inode *inode = dentry->d_inode; -	struct posix_acl *acl = NULL; - -	hfs_dbg(ACL_MOD, -		"[%s]: ino %lu, value %p, size %zu, flags %#x, type %#x\n", -		__func__, inode->i_ino, value, size, flags, type); - -	if (strcmp(name, "") != 0) -		return -EINVAL; - -	if (!inode_owner_or_capable(inode)) -		return -EPERM; - -	if (value) { -		acl = posix_acl_from_xattr(&init_user_ns, value, size); -		if (IS_ERR(acl)) -			return PTR_ERR(acl); -		else if (acl) { -			err = posix_acl_valid(acl); -			if (err) -				goto end_xattr_set_acl; -		} +	if (default_acl) { +		err = hfsplus_set_posix_acl(inode, default_acl, +					    ACL_TYPE_DEFAULT); +		posix_acl_release(default_acl);  	} -	err = hfsplus_set_posix_acl(inode, type, acl); - -end_xattr_set_acl: -	posix_acl_release(acl); +	if (acl) { +		if (!err) +			err = hfsplus_set_posix_acl(inode, acl, +						    ACL_TYPE_ACCESS); +		posix_acl_release(acl); +	}  	return err;  } - -static size_t hfsplus_xattr_list_posix_acl(struct dentry *dentry, -						char *list, -						size_t list_size, -						const char *name, -						size_t name_len, -						int type) -{ -	/* -	 * This method is not used. -	 * It is used hfsplus_listxattr() instead of generic_listxattr(). -	 */ -	return -EOPNOTSUPP; -} - -const struct xattr_handler hfsplus_xattr_acl_access_handler = { -	.prefix	= POSIX_ACL_XATTR_ACCESS, -	.flags	= ACL_TYPE_ACCESS, -	.list	= hfsplus_xattr_list_posix_acl, -	.get	= hfsplus_xattr_get_posix_acl, -	.set	= hfsplus_xattr_set_posix_acl, -}; - -const struct xattr_handler hfsplus_xattr_acl_default_handler = { -	.prefix	= POSIX_ACL_XATTR_DEFAULT, -	.flags	= ACL_TYPE_DEFAULT, -	.list	= hfsplus_xattr_list_posix_acl, -	.get	= hfsplus_xattr_get_posix_acl, -	.set	= hfsplus_xattr_set_posix_acl, -};  | 
