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> #include <linux/posix_acl_xattr.h>
#define XFS_ACL_NOT_CACHED ((void *)-1)
/* /*
* Locking scheme: * Locking scheme:
* - all ACL updates are protected by inode->i_mutex, which is taken before * - all ACL updates are protected by inode->i_mutex, which is taken before
* calling into this file. * 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 * 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 * struct posix_acl *
xfs_get_acl(struct inode *inode, int type) xfs_get_acl(struct inode *inode, int type)
{ {
struct xfs_inode *ip = XFS_I(inode); struct xfs_inode *ip = XFS_I(inode);
struct posix_acl *acl = NULL, **p_acl; struct posix_acl *acl;
struct xfs_acl *xfs_acl; struct xfs_acl *xfs_acl;
int len = sizeof(struct xfs_acl); int len = sizeof(struct xfs_acl);
char *ea_name; char *ea_name;
int error; int error;
acl = get_cached_acl(inode, type);
if (acl != ACL_NOT_CACHED)
return acl;
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
ea_name = SGI_ACL_FILE; ea_name = SGI_ACL_FILE;
p_acl = &ip->i_acl;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
ea_name = SGI_ACL_DEFAULT; ea_name = SGI_ACL_DEFAULT;
p_acl = &ip->i_default_acl;
break; break;
default: 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 * If we have a cached ACLs value just return it, not need to
* go out to the disk. * go out to the disk.
*/ */
if (acl)
return acl;
xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL); xfs_acl = kzalloc(sizeof(struct xfs_acl), GFP_KERNEL);
if (!xfs_acl) 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 * If the attribute doesn't exist make sure we have a negative
* cache entry, for any other error assume it is transient and * 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) { if (error == -ENOATTR) {
acl = NULL; acl = NULL;
@ -179,7 +151,7 @@ xfs_get_acl(struct inode *inode, int type)
goto out; goto out;
out_update_cache: out_update_cache:
xfs_update_cached_acl(inode, p_acl, acl); set_cached_acl(inode, type, acl);
out: out:
kfree(xfs_acl); kfree(xfs_acl);
return acl; return acl;
@ -189,7 +161,6 @@ STATIC int
xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
{ {
struct xfs_inode *ip = XFS_I(inode); struct xfs_inode *ip = XFS_I(inode);
struct posix_acl **p_acl;
char *ea_name; char *ea_name;
int error; int error;
@ -199,13 +170,11 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
switch (type) { switch (type) {
case ACL_TYPE_ACCESS: case ACL_TYPE_ACCESS:
ea_name = SGI_ACL_FILE; ea_name = SGI_ACL_FILE;
p_acl = &ip->i_acl;
break; break;
case ACL_TYPE_DEFAULT: case ACL_TYPE_DEFAULT:
if (!S_ISDIR(inode->i_mode)) if (!S_ISDIR(inode->i_mode))
return acl ? -EACCES : 0; return acl ? -EACCES : 0;
ea_name = SGI_ACL_DEFAULT; ea_name = SGI_ACL_DEFAULT;
p_acl = &ip->i_default_acl;
break; break;
default: default:
return -EINVAL; return -EINVAL;
@ -242,7 +211,7 @@ xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
} }
if (!error) if (!error)
xfs_update_cached_acl(inode, p_acl, acl); set_cached_acl(inode, type, acl);
return error; return error;
} }
@ -384,30 +353,6 @@ xfs_acl_chmod(struct inode *inode)
return error; 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. * 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 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_inherit_acl(struct inode *inode, struct posix_acl *default_acl);
extern int xfs_acl_chmod(struct inode *inode); 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_access_exists(struct inode *inode);
extern int posix_acl_default_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_get_acl(inode, type) NULL
# define xfs_inherit_acl(inode, default_acl) 0 # define xfs_inherit_acl(inode, default_acl) 0
# define xfs_acl_chmod(inode) 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_access_exists(inode) 0
# define posix_acl_default_exists(inode) 0 # define posix_acl_default_exists(inode) 0
#endif /* CONFIG_XFS_POSIX_ACL */ #endif /* CONFIG_XFS_POSIX_ACL */

View File

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

View File

@ -273,11 +273,6 @@ typedef struct xfs_inode {
/* VFS inode */ /* VFS inode */
struct inode i_vnode; /* embedded 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. */ /* Trace buffers per inode. */
#ifdef XFS_INODE_TRACE #ifdef XFS_INODE_TRACE
struct ktrace *i_trace; /* general inode trace */ struct ktrace *i_trace; /* general inode trace */