switch xfs to generic acl caching helpers
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
073aaa1b14
commit
1cbd20d820
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue