switch xfs to generic acl caching helpers

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2009-06-09 13:29:39 -04:00
parent 073aaa1b14
commit 1cbd20d820
4 changed files with 9 additions and 75 deletions

View file

@ -25,14 +25,10 @@
#include <linux/posix_acl_xattr.h>
#define XFS_ACL_NOT_CACHED ((void *)-1)
/*
* Locking scheme:
* - all ACL updates are protected by inode->i_mutex, which is taken before
* calling into this file.
* - access and updates to the ip->i_acl and ip->i_default_acl pointers are
* protected by inode->i_lock.
*/
STATIC struct posix_acl *
@ -102,59 +98,35 @@ xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl)
}
}
/*
* Update the cached ACL pointer in the inode.
*
* Because we don't hold any locks while reading/writing the attribute
* from/to disk another thread could have raced and updated the cached
* ACL value before us. In that case we release the previous cached value
* and update it with our new value.
*/
STATIC void
xfs_update_cached_acl(struct inode *inode, struct posix_acl **p_acl,
struct posix_acl *acl)
{
spin_lock(&inode->i_lock);
if (*p_acl && *p_acl != XFS_ACL_NOT_CACHED)
posix_acl_release(*p_acl);
*p_acl = posix_acl_dup(acl);
spin_unlock(&inode->i_lock);
}
struct posix_acl *
xfs_get_acl(struct inode *inode, int type)
{
struct xfs_inode *ip = XFS_I(inode);
struct posix_acl *acl = NULL, **p_acl;
struct posix_acl *acl;
struct xfs_acl *xfs_acl;
int len = sizeof(struct xfs_acl);
char *ea_name;
int error;
acl = get_cached_acl(inode, type);
if (acl != ACL_NOT_CACHED)
return acl;
switch (type) {
case ACL_TYPE_ACCESS:
ea_name = SGI_ACL_FILE;
p_acl = &ip->i_acl;
break;
case ACL_TYPE_DEFAULT:
ea_name = SGI_ACL_DEFAULT;
p_acl = &ip->i_default_acl;
break;
default:
return ERR_PTR(-EINVAL);
BUG();
}
spin_lock(&inode->i_lock);
if (*p_acl != XFS_ACL_NOT_CACHED)
acl = posix_acl_dup(*p_acl);
spin_unlock(&inode->i_lock);
/*
* If we have a cached ACLs value just return it, not need to
* go out to the disk.
*/
if (acl)
return acl;
xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL);
if (!xfs_acl)
@ -165,7 +137,7 @@ xfs_get_acl(struct inode *inode, int type)
/*
* If the attribute doesn't exist make sure we have a negative
* cache entry, for any other error assume it is transient and
* leave the cache entry as XFS_ACL_NOT_CACHED.
* leave the cache entry as ACL_NOT_CACHED.
*/
if (error == -ENOATTR) {
acl = NULL;
@ -179,7 +151,7 @@ xfs_get_acl(struct inode *inode, int type)
goto out;
out_update_cache:
xfs_update_cached_acl(inode, p_acl, acl);
set_cached_acl(inode, type, acl);
out:
kfree(xfs_acl);
return acl;
@ -189,7 +161,6 @@ STATIC int
xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
{
struct xfs_inode *ip = XFS_I(inode);
struct posix_acl **p_acl;
char *ea_name;
int error;
@ -199,13 +170,11 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
switch (type) {
case ACL_TYPE_ACCESS:
ea_name = SGI_ACL_FILE;
p_acl = &ip->i_acl;
break;
case ACL_TYPE_DEFAULT:
if (!S_ISDIR(inode->i_mode))
return acl ? -EACCES : 0;
ea_name = SGI_ACL_DEFAULT;
p_acl = &ip->i_default_acl;
break;
default:
return -EINVAL;
@ -242,7 +211,7 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
}
if (!error)
xfs_update_cached_acl(inode, p_acl, acl);
set_cached_acl(inode, type, acl);
return error;
}
@ -384,30 +353,6 @@ xfs_acl_chmod(struct inode *inode)
return error;
}
void
xfs_inode_init_acls(struct xfs_inode *ip)
{
/*
* No need for locking, inode is not live yet.
*/
ip->i_acl = XFS_ACL_NOT_CACHED;
ip->i_default_acl = XFS_ACL_NOT_CACHED;
}
void
xfs_inode_clear_acls(struct xfs_inode *ip)
{
/*
* No need for locking here, the inode is not live anymore
* and just about to be freed.
*/
if (ip->i_acl != XFS_ACL_NOT_CACHED)
posix_acl_release(ip->i_acl);
if (ip->i_default_acl != XFS_ACL_NOT_CACHED)
posix_acl_release(ip->i_default_acl);
}
/*
* System xattr handlers.
*

View file

@ -46,8 +46,6 @@ extern int xfs_check_acl(struct inode *inode, int mask);
extern struct posix_acl *xfs_get_acl(struct inode *inode, int type);
extern int xfs_inherit_acl(struct inode *inode, struct posix_acl *default_acl);
extern int xfs_acl_chmod(struct inode *inode);
extern void xfs_inode_init_acls(struct xfs_inode *ip);
extern void xfs_inode_clear_acls(struct xfs_inode *ip);
extern int posix_acl_access_exists(struct inode *inode);
extern int posix_acl_default_exists(struct inode *inode);
@ -57,8 +55,6 @@ extern struct xattr_handler xfs_xattr_system_handler;
# define xfs_get_acl(inode, type) NULL
# define xfs_inherit_acl(inode, default_acl) 0
# define xfs_acl_chmod(inode) 0
# define xfs_inode_init_acls(ip)
# define xfs_inode_clear_acls(ip)
# define posix_acl_access_exists(inode) 0
# define posix_acl_default_exists(inode) 0
#endif /* CONFIG_XFS_POSIX_ACL */

View file

@ -83,7 +83,6 @@ xfs_inode_alloc(
memset(&ip->i_d, 0, sizeof(xfs_icdinode_t));
ip->i_size = 0;
ip->i_new_size = 0;
xfs_inode_init_acls(ip);
/*
* Initialize inode's trace buffers.
@ -560,7 +559,6 @@ xfs_ireclaim(
ASSERT(atomic_read(&ip->i_pincount) == 0);
ASSERT(!spin_is_locked(&ip->i_flags_lock));
ASSERT(completion_done(&ip->i_flush));
xfs_inode_clear_acls(ip);
kmem_zone_free(xfs_inode_zone, ip);
}

View file

@ -273,11 +273,6 @@ typedef struct xfs_inode {
/* VFS inode */
struct inode i_vnode; /* embedded VFS inode */
#ifdef CONFIG_XFS_POSIX_ACL
struct posix_acl *i_acl;
struct posix_acl *i_default_acl;
#endif
/* Trace buffers per inode. */
#ifdef XFS_INODE_TRACE
struct ktrace *i_trace; /* general inode trace */