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

Commit 073aaa1b authored by Al Viro's avatar Al Viro
Browse files

helpers for acl caching + switch to those



helpers: get_cached_acl(inode, type), set_cached_acl(inode, type, acl),
forget_cached_acl(inode, type).

ubifs/xattr.c needed includes reordered, the rest is a plain switchover.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 06b16e9f
Loading
Loading
Loading
Loading
+9 −35
Original line number Diff line number Diff line
@@ -29,51 +29,28 @@

#ifdef CONFIG_FS_POSIX_ACL

static void btrfs_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 != ACL_NOT_CACHED)
		posix_acl_release(*p_acl);
	*p_acl = posix_acl_dup(acl);
	spin_unlock(&inode->i_lock);
}

static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
{
	int size;
	const char *name;
	char *value = NULL;
	struct posix_acl *acl = NULL, **p_acl;
	struct posix_acl *acl;

	acl = get_cached_acl(inode, type);
	if (acl != ACL_NOT_CACHED)
		return acl;

	switch (type) {
	case ACL_TYPE_ACCESS:
		name = POSIX_ACL_XATTR_ACCESS;
		p_acl = &inode->i_acl;
		break;
	case ACL_TYPE_DEFAULT:
		name = POSIX_ACL_XATTR_DEFAULT;
		p_acl = &inode->i_default_acl;
		break;
	default:
		return ERR_PTR(-EINVAL);
		BUG();
	}

	/* Handle the cached NULL acl case without locking */
	acl = ACCESS_ONCE(*p_acl);
	if (!acl)
		return acl;

	spin_lock(&inode->i_lock);
	acl = *p_acl;
	if (acl != ACL_NOT_CACHED)
		acl = posix_acl_dup(acl);
	spin_unlock(&inode->i_lock);

	if (acl != ACL_NOT_CACHED)
		return acl;

	size = __btrfs_getxattr(inode, name, "", 0);
	if (size > 0) {
		value = kzalloc(size, GFP_NOFS);
@@ -82,13 +59,13 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
		size = __btrfs_getxattr(inode, name, value, size);
		if (size > 0) {
			acl = posix_acl_from_xattr(value, size);
			btrfs_update_cached_acl(inode, p_acl, acl);
			set_cached_acl(inode, type, acl);
		}
		kfree(value);
	} else if (size == -ENOENT || size == -ENODATA || size == 0) {
		/* FIXME, who returns -ENOENT?  I think nobody */
		acl = NULL;
		btrfs_update_cached_acl(inode, p_acl, acl);
		set_cached_acl(inode, type, acl);
	} else {
		acl = ERR_PTR(-EIO);
	}
@@ -121,7 +98,6 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
{
	int ret, size = 0;
	const char *name;
	struct posix_acl **p_acl;
	char *value = NULL;
	mode_t mode;

@@ -141,13 +117,11 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
		ret = 0;
		inode->i_mode = mode;
		name = POSIX_ACL_XATTR_ACCESS;
		p_acl = &inode->i_acl;
		break;
	case ACL_TYPE_DEFAULT:
		if (!S_ISDIR(inode->i_mode))
			return acl ? -EINVAL : 0;
		name = POSIX_ACL_XATTR_DEFAULT;
		p_acl = &inode->i_default_acl;
		break;
	default:
		return -EINVAL;
@@ -172,7 +146,7 @@ static int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
	kfree(value);

	if (!ret)
		btrfs_update_cached_acl(inode, p_acl, acl);
		set_cached_acl(inode, type, acl);

	return ret;
}
+17 −62
Original line number Diff line number Diff line
@@ -125,30 +125,6 @@ ext2_acl_to_disk(const struct posix_acl *acl, size_t *size)
	return ERR_PTR(-EINVAL);
}

static inline struct posix_acl *
ext2_iget_acl(struct inode *inode, struct posix_acl **i_acl)
{
	struct posix_acl *acl = ACL_NOT_CACHED;

	spin_lock(&inode->i_lock);
	if (*i_acl != ACL_NOT_CACHED)
		acl = posix_acl_dup(*i_acl);
	spin_unlock(&inode->i_lock);

	return acl;
}

static inline void
ext2_iset_acl(struct inode *inode, struct posix_acl **i_acl,
		   struct posix_acl *acl)
{
	spin_lock(&inode->i_lock);
	if (*i_acl != ACL_NOT_CACHED)
		posix_acl_release(*i_acl);
	*i_acl = posix_acl_dup(acl);
	spin_unlock(&inode->i_lock);
}

/*
 * inode->i_mutex: don't care
 */
@@ -163,23 +139,19 @@ ext2_get_acl(struct inode *inode, int type)
	if (!test_opt(inode->i_sb, POSIX_ACL))
		return NULL;

	switch(type) {
		case ACL_TYPE_ACCESS:
			acl = ext2_iget_acl(inode, &inode->i_acl);
	acl = get_cached_acl(inode, type);
	if (acl != ACL_NOT_CACHED)
		return acl;

	switch (type) {
	case ACL_TYPE_ACCESS:
		name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
		break;

	case ACL_TYPE_DEFAULT:
			acl = ext2_iget_acl(inode, &inode->i_default_acl);
			if (acl != ACL_NOT_CACHED)
				return acl;
		name_index = EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT;
		break;

	default:
			return ERR_PTR(-EINVAL);
		BUG();
	}
	retval = ext2_xattr_get(inode, name_index, "", NULL, 0);
	if (retval > 0) {
@@ -196,17 +168,9 @@ ext2_get_acl(struct inode *inode, int type)
		acl = ERR_PTR(retval);
	kfree(value);

	if (!IS_ERR(acl)) {
		switch(type) {
			case ACL_TYPE_ACCESS:
				ext2_iset_acl(inode, &inode->i_acl, acl);
				break;
	if (!IS_ERR(acl))
		set_cached_acl(inode, type, acl);

			case ACL_TYPE_DEFAULT:
				ext2_iset_acl(inode, &inode->i_default_acl, acl);
				break;
		}
	}
	return acl;
}

@@ -261,17 +225,8 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
	error = ext2_xattr_set(inode, name_index, "", value, size, 0);

	kfree(value);
	if (!error) {
		switch(type) {
			case ACL_TYPE_ACCESS:
				ext2_iset_acl(inode, &inode->i_acl, acl);
				break;

			case ACL_TYPE_DEFAULT:
				ext2_iset_acl(inode, &inode->i_default_acl, acl);
				break;
		}
	}
	if (!error)
		set_cached_acl(inode, type, acl);
	return error;
}

+19 −64
Original line number Diff line number Diff line
@@ -126,33 +126,6 @@ ext3_acl_to_disk(const struct posix_acl *acl, size_t *size)
	return ERR_PTR(-EINVAL);
}

static inline struct posix_acl *
ext3_iget_acl(struct inode *inode, struct posix_acl **i_acl)
{
	struct posix_acl *acl = ACCESS_ONCE(*i_acl);

	if (acl) {
		spin_lock(&inode->i_lock);
		acl = *i_acl;
		if (acl != ACL_NOT_CACHED)
			acl = posix_acl_dup(acl);
		spin_unlock(&inode->i_lock);
	}

	return acl;
}

static inline void
ext3_iset_acl(struct inode *inode, struct posix_acl **i_acl,
                  struct posix_acl *acl)
{
	spin_lock(&inode->i_lock);
	if (*i_acl != ACL_NOT_CACHED)
		posix_acl_release(*i_acl);
	*i_acl = posix_acl_dup(acl);
	spin_unlock(&inode->i_lock);
}

/*
 * Inode operation get_posix_acl().
 *
@@ -169,24 +142,21 @@ ext3_get_acl(struct inode *inode, int type)
	if (!test_opt(inode->i_sb, POSIX_ACL))
		return NULL;

	switch(type) {
		case ACL_TYPE_ACCESS:
			acl = ext3_iget_acl(inode, &inode->i_acl);
	acl = get_cached_acl(inode, type);
	if (acl != ACL_NOT_CACHED)
		return acl;

	switch (type) {
	case ACL_TYPE_ACCESS:
		name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS;
		break;

	case ACL_TYPE_DEFAULT:
			acl = ext3_iget_acl(inode, &inode->i_default_acl);
			if (acl != ACL_NOT_CACHED)
				return acl;
		name_index = EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT;
		break;

	default:
			return ERR_PTR(-EINVAL);
		BUG();
	}

	retval = ext3_xattr_get(inode, name_index, "", NULL, 0);
	if (retval > 0) {
		value = kmalloc(retval, GFP_NOFS);
@@ -202,17 +172,9 @@ ext3_get_acl(struct inode *inode, int type)
		acl = ERR_PTR(retval);
	kfree(value);

	if (!IS_ERR(acl)) {
		switch(type) {
			case ACL_TYPE_ACCESS:
				ext3_iset_acl(inode, &inode->i_acl, acl);
				break;
	if (!IS_ERR(acl))
		set_cached_acl(inode, type, acl);

			case ACL_TYPE_DEFAULT:
				ext3_iset_acl(inode, &inode->i_default_acl, acl);
				break;
		}
	}
	return acl;
}

@@ -269,17 +231,10 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type,
				      value, size, 0);

	kfree(value);
	if (!error) {
		switch(type) {
			case ACL_TYPE_ACCESS:
				ext3_iset_acl(inode, &inode->i_acl, acl);
				break;

			case ACL_TYPE_DEFAULT:
				ext3_iset_acl(inode, &inode->i_default_acl, acl);
				break;
		}
	}
	if (!error)
		set_cached_acl(inode, type, acl);

	return error;
}

+9 −56
Original line number Diff line number Diff line
@@ -126,33 +126,6 @@ ext4_acl_to_disk(const struct posix_acl *acl, size_t *size)
	return ERR_PTR(-EINVAL);
}

static inline struct posix_acl *
ext4_iget_acl(struct inode *inode, struct posix_acl **i_acl)
{
	struct posix_acl *acl = ACCESS_ONCE(*i_acl);

	if (acl) {
		spin_lock(&inode->i_lock);
		acl = *i_acl;
		if (acl != ACL_NOT_CACHED)
			acl = posix_acl_dup(acl);
		spin_unlock(&inode->i_lock);
	}

	return acl;
}

static inline void
ext4_iset_acl(struct inode *inode, struct posix_acl **i_acl,
		struct posix_acl *acl)
{
	spin_lock(&inode->i_lock);
	if (*i_acl != ACL_NOT_CACHED)
		posix_acl_release(*i_acl);
	*i_acl = posix_acl_dup(acl);
	spin_unlock(&inode->i_lock);
}

/*
 * Inode operation get_posix_acl().
 *
@@ -169,23 +142,19 @@ ext4_get_acl(struct inode *inode, int type)
	if (!test_opt(inode->i_sb, POSIX_ACL))
		return NULL;

	switch (type) {
	case ACL_TYPE_ACCESS:
		acl = ext4_iget_acl(inode, &inode->i_acl);
	acl = get_cached_acl(inode, type);
	if (acl != ACL_NOT_CACHED)
		return acl;

	switch (type) {
	case ACL_TYPE_ACCESS:
		name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
		break;

	case ACL_TYPE_DEFAULT:
		acl = ext4_iget_acl(inode, &inode->i_default_acl);
		if (acl != ACL_NOT_CACHED)
			return acl;
		name_index = EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT;
		break;

	default:
		return ERR_PTR(-EINVAL);
		BUG();
	}
	retval = ext4_xattr_get(inode, name_index, "", NULL, 0);
	if (retval > 0) {
@@ -202,17 +171,9 @@ ext4_get_acl(struct inode *inode, int type)
		acl = ERR_PTR(retval);
	kfree(value);

	if (!IS_ERR(acl)) {
		switch (type) {
		case ACL_TYPE_ACCESS:
			ext4_iset_acl(inode, &inode->i_acl, acl);
			break;
	if (!IS_ERR(acl))
		set_cached_acl(inode, type, acl);

		case ACL_TYPE_DEFAULT:
			ext4_iset_acl(inode, &inode->i_default_acl, acl);
			break;
		}
	}
	return acl;
}

@@ -269,17 +230,9 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type,
				      value, size, 0);

	kfree(value);
	if (!error) {
		switch (type) {
		case ACL_TYPE_ACCESS:
			ext4_iset_acl(inode, &inode->i_acl, acl);
			break;
	if (!error)
		set_cached_acl(inode, type, acl);

		case ACL_TYPE_DEFAULT:
			ext4_iset_acl(inode, &inode->i_default_acl, acl);
			break;
		}
	}
	return error;
}

+11 −49
Original line number Diff line number Diff line
@@ -156,47 +156,25 @@ static void *jffs2_acl_to_medium(const struct posix_acl *acl, size_t *size)
	return ERR_PTR(-EINVAL);
}

static struct posix_acl *jffs2_iget_acl(struct inode *inode, struct posix_acl **i_acl)
{
	struct posix_acl *acl = ACL_NOT_CACHED;

	spin_lock(&inode->i_lock);
	if (*i_acl != ACL_NOT_CACHED)
		acl = posix_acl_dup(*i_acl);
	spin_unlock(&inode->i_lock);
	return acl;
}

static void jffs2_iset_acl(struct inode *inode, struct posix_acl **i_acl, struct posix_acl *acl)
{
	spin_lock(&inode->i_lock);
	if (*i_acl != ACL_NOT_CACHED)
		posix_acl_release(*i_acl);
	*i_acl = posix_acl_dup(acl);
	spin_unlock(&inode->i_lock);
}

static struct posix_acl *jffs2_get_acl(struct inode *inode, int type)
{
	struct posix_acl *acl;
	char *value = NULL;
	int rc, xprefix;

	switch (type) {
	case ACL_TYPE_ACCESS:
		acl = jffs2_iget_acl(inode, &inode->i_acl);
	acl = get_cached_acl(inode, type);
	if (acl != ACL_NOT_CACHED)
		return acl;

	switch (type) {
	case ACL_TYPE_ACCESS:
		xprefix = JFFS2_XPREFIX_ACL_ACCESS;
		break;
	case ACL_TYPE_DEFAULT:
		acl = jffs2_iget_acl(inode, &inode->i_default_acl);
		if (acl != ACL_NOT_CACHED)
			return acl;
		xprefix = JFFS2_XPREFIX_ACL_DEFAULT;
		break;
	default:
		return ERR_PTR(-EINVAL);
		BUG();
	}
	rc = do_jffs2_getxattr(inode, xprefix, "", NULL, 0);
	if (rc > 0) {
@@ -214,16 +192,8 @@ static struct posix_acl *jffs2_get_acl(struct inode *inode, int type)
	}
	if (value)
		kfree(value);
	if (!IS_ERR(acl)) {
		switch (type) {
		case ACL_TYPE_ACCESS:
			jffs2_iset_acl(inode, &inode->i_acl, acl);
			break;
		case ACL_TYPE_DEFAULT:
			jffs2_iset_acl(inode, &inode->i_default_acl, acl);
			break;
		}
	}
	if (!IS_ERR(acl))
		set_cached_acl(inode, type, acl);
	return acl;
}

@@ -283,16 +253,8 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
		return -EINVAL;
	}
	rc = __jffs2_set_acl(inode, xprefix, acl);
	if (!rc) {
		switch(type) {
		case ACL_TYPE_ACCESS:
			jffs2_iset_acl(inode, &inode->i_acl, acl);
			break;
		case ACL_TYPE_DEFAULT:
			jffs2_iset_acl(inode, &inode->i_default_acl, acl);
			break;
		}
	}
	if (!rc)
		set_cached_acl(inode, type, acl);
	return rc;
}

@@ -336,7 +298,7 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
		*i_mode &= ~current_umask();
	} else {
		if (S_ISDIR(*i_mode))
			jffs2_iset_acl(inode, &inode->i_default_acl, acl);
			set_cached_acl(inode, ACL_TYPE_DEFAULT, acl);

		clone = posix_acl_clone(acl, GFP_KERNEL);
		if (!clone)
@@ -347,7 +309,7 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
			return rc;
		}
		if (rc > 0)
			jffs2_iset_acl(inode, &inode->i_acl, clone);
			set_cached_acl(inode, ACL_TYPE_ACCESS, clone);

		posix_acl_release(clone);
	}
Loading