Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1cbd20d8 authored by Al Viro's avatar Al Viro
Browse files

switch xfs to generic acl caching helpers



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 073aaa1b
Loading
Loading
Loading
Loading
+9 −64
Original line number Original line Diff line number Diff line
@@ -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.
 *
 *
+0 −4
Original line number Original line Diff line number Diff line
@@ -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 */
+0 −2
Original line number Original line Diff line number Diff line
@@ -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);
}
}


+0 −5
Original line number Original line Diff line number Diff line
@@ -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 */