diff options
Diffstat (limited to 'fs/ext4/acl.c')
| -rw-r--r-- | fs/ext4/acl.c | 93 | 
1 files changed, 29 insertions, 64 deletions
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 60d900fcc3d..dca2d1ded93 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c @@ -131,7 +131,7 @@ fail:   *   * inode->i_mutex: don't care   */ -static struct posix_acl * +struct posix_acl *  ext4_get_acl(struct inode *inode, int type)  {  	int name_index; @@ -237,29 +237,6 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type,  	return error;  } -int -ext4_check_acl(struct inode *inode, int mask) -{ -	struct posix_acl *acl; - -	if (mask & MAY_NOT_BLOCK) { -		if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) -			return -ECHILD; -		return -EAGAIN; -	} - -	acl = ext4_get_acl(inode, ACL_TYPE_ACCESS); -	if (IS_ERR(acl)) -		return PTR_ERR(acl); -	if (acl) { -		int error = posix_acl_permission(inode, acl, mask); -		posix_acl_release(acl); -		return error; -	} - -	return -EAGAIN; -} -  /*   * Initialize the ACLs of a new inode. Called from ext4_new_inode.   * @@ -282,8 +259,7 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)  			inode->i_mode &= ~current_umask();  	}  	if (test_opt(inode->i_sb, POSIX_ACL) && acl) { -		struct posix_acl *clone; -		mode_t mode; +		mode_t mode = inode->i_mode;  		if (S_ISDIR(inode->i_mode)) {  			error = ext4_set_acl(handle, inode, @@ -291,22 +267,15 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)  			if (error)  				goto cleanup;  		} -		clone = posix_acl_clone(acl, GFP_NOFS); -		error = -ENOMEM; -		if (!clone) -			goto cleanup; +		error = posix_acl_create(&acl, GFP_NOFS, &mode); +		if (error < 0) +			return error; -		mode = inode->i_mode; -		error = posix_acl_create_masq(clone, &mode); -		if (error >= 0) { -			inode->i_mode = mode; -			if (error > 0) { -				/* This is an extended ACL */ -				error = ext4_set_acl(handle, inode, -						     ACL_TYPE_ACCESS, clone); -			} +		inode->i_mode = mode; +		if (error > 0) { +			/* This is an extended ACL */ +			error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl);  		} -		posix_acl_release(clone);  	}  cleanup:  	posix_acl_release(acl); @@ -330,9 +299,12 @@ cleanup:  int  ext4_acl_chmod(struct inode *inode)  { -	struct posix_acl *acl, *clone; +	struct posix_acl *acl; +	handle_t *handle; +	int retries = 0;  	int error; +  	if (S_ISLNK(inode->i_mode))  		return -EOPNOTSUPP;  	if (!test_opt(inode->i_sb, POSIX_ACL)) @@ -340,31 +312,24 @@ ext4_acl_chmod(struct inode *inode)  	acl = ext4_get_acl(inode, ACL_TYPE_ACCESS);  	if (IS_ERR(acl) || !acl)  		return PTR_ERR(acl); -	clone = posix_acl_clone(acl, GFP_KERNEL); -	posix_acl_release(acl); -	if (!clone) -		return -ENOMEM; -	error = posix_acl_chmod_masq(clone, inode->i_mode); -	if (!error) { -		handle_t *handle; -		int retries = 0; - -	retry: -		handle = ext4_journal_start(inode, -				EXT4_DATA_TRANS_BLOCKS(inode->i_sb)); -		if (IS_ERR(handle)) { -			error = PTR_ERR(handle); -			ext4_std_error(inode->i_sb, error); -			goto out; -		} -		error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, clone); -		ext4_journal_stop(handle); -		if (error == -ENOSPC && -		    ext4_should_retry_alloc(inode->i_sb, &retries)) -			goto retry; +	error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode); +	if (error) +		return error; +retry: +	handle = ext4_journal_start(inode, +			EXT4_DATA_TRANS_BLOCKS(inode->i_sb)); +	if (IS_ERR(handle)) { +		error = PTR_ERR(handle); +		ext4_std_error(inode->i_sb, error); +		goto out;  	} +	error = ext4_set_acl(handle, inode, ACL_TYPE_ACCESS, acl); +	ext4_journal_stop(handle); +	if (error == -ENOSPC && +	    ext4_should_retry_alloc(inode->i_sb, &retries)) +		goto retry;  out: -	posix_acl_release(clone); +	posix_acl_release(acl);  	return error;  }  |