Esempio n. 1
0
int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
{
	struct posix_acl *acl, *clone;
	int rc;

	cache_no_acl(inode);

	if (S_ISLNK(*i_mode))
		return 0;	/* Symlink always has no-ACL */

	acl = jffs2_get_acl(dir_i, ACL_TYPE_DEFAULT);
	if (IS_ERR(acl))
		return PTR_ERR(acl);

	if (!acl) {
		*i_mode &= ~current_umask();
	} else {
		if (S_ISDIR(*i_mode))
			set_cached_acl(inode, ACL_TYPE_DEFAULT, acl);

		clone = posix_acl_clone(acl, GFP_KERNEL);
		if (!clone)
			return -ENOMEM;
		rc = posix_acl_create_masq(clone, (mode_t *)i_mode);
		if (rc < 0) {
			posix_acl_release(clone);
			return rc;
		}
		if (rc > 0)
			set_cached_acl(inode, ACL_TYPE_ACCESS, clone);

		posix_acl_release(clone);
	}
	return 0;
}
Esempio n. 2
0
int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, umode_t *i_mode)
{
	struct posix_acl *acl;
	int rc;

	cache_no_acl(inode);

	if (S_ISLNK(*i_mode))
		return 0;	/* Symlink always has no-ACL */

	acl = jffs2_get_acl(dir_i, ACL_TYPE_DEFAULT);
	if (IS_ERR(acl))
		return PTR_ERR(acl);

	if (!acl) {
		*i_mode &= ~current_umask();
	} else {
		if (S_ISDIR(*i_mode))
			set_cached_acl(inode, ACL_TYPE_DEFAULT, acl);

		rc = posix_acl_create(&acl, GFP_KERNEL, i_mode);
		if (rc < 0)
			return rc;
		if (rc > 0)
			set_cached_acl(inode, ACL_TYPE_ACCESS, acl);

		posix_acl_release(acl);
	}
	return 0;
}
Esempio n. 3
0
static int jffs2_acl_getxattr(struct inode *inode, int type, void *buffer, size_t size)
{
	struct posix_acl *acl;
	int rc;

	acl = jffs2_get_acl(inode, type);
	if (IS_ERR(acl))
		return PTR_ERR(acl);
	if (!acl)
		return -ENODATA;
	rc = posix_acl_to_xattr(acl, buffer, size);
	posix_acl_release(acl);

	return rc;
}
Esempio n. 4
0
static int jffs2_check_acl(struct inode *inode, int mask)
{
	struct posix_acl *acl;
	int rc;

	acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS);
	if (IS_ERR(acl))
		return PTR_ERR(acl);
	if (acl) {
		rc = posix_acl_permission(inode, acl, mask);
		posix_acl_release(acl);
		return rc;
	}
	return -EAGAIN;
}
Esempio n. 5
0
int jffs2_acl_chmod(struct inode *inode)
{
	struct posix_acl *acl;
	int rc;

	if (S_ISLNK(inode->i_mode))
		return -EOPNOTSUPP;
	acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS);
	if (IS_ERR(acl) || !acl)
		return PTR_ERR(acl);
	rc = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
	if (rc)
		return rc;
	rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, acl);
	posix_acl_release(acl);
	return rc;
}
Esempio n. 6
0
int jffs2_check_acl(struct inode *inode, int mask, unsigned int flags)
{
	struct posix_acl *acl;
	int rc;

	if (flags & IPERM_FLAG_RCU)
		return -ECHILD;

	acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS);
	if (IS_ERR(acl))
		return PTR_ERR(acl);
	if (acl) {
		rc = posix_acl_permission(inode, acl, mask);
		posix_acl_release(acl);
		return rc;
	}
	return -EAGAIN;
}
Esempio n. 7
0
static int jffs2_acl_getxattr(struct dentry *dentry, const char *name,
		void *buffer, size_t size, int type)
{
	struct posix_acl *acl;
	int rc;

	if (name[0] != '\0')
		return -EINVAL;

	acl = jffs2_get_acl(dentry->d_inode, type);
	if (IS_ERR(acl))
		return PTR_ERR(acl);
	if (!acl)
		return -ENODATA;
	rc = posix_acl_to_xattr(acl, buffer, size);
	posix_acl_release(acl);

	return rc;
}
Esempio n. 8
0
int jffs2_acl_chmod(struct inode *inode)
{
	struct posix_acl *acl, *clone;
	int rc;

	if (S_ISLNK(inode->i_mode))
		return -EOPNOTSUPP;
	acl = jffs2_get_acl(inode, ACL_TYPE_ACCESS);
	if (IS_ERR(acl) || !acl)
		return PTR_ERR(acl);
	clone = posix_acl_clone(acl, GFP_KERNEL);
	posix_acl_release(acl);
	if (!clone)
		return -ENOMEM;
	rc = posix_acl_chmod_masq(clone, inode->i_mode);
	if (!rc)
		rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, clone);
	posix_acl_release(clone);
	return rc;
}
Esempio n. 9
0
int jffs2_init_acl(struct inode *inode, struct inode *dir)
{
	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
	struct posix_acl *acl = NULL, *clone;
	mode_t mode;
	int rc = 0;

	f->i_acl_access = JFFS2_ACL_NOT_CACHED;
	f->i_acl_default = JFFS2_ACL_NOT_CACHED;
	if (!S_ISLNK(inode->i_mode)) {
		acl = jffs2_get_acl(dir, ACL_TYPE_DEFAULT);
		if (IS_ERR(acl))
			return PTR_ERR(acl);
		if (!acl)
			inode->i_mode &= ~current->fs->umask;
	}
	if (acl) {
		if (S_ISDIR(inode->i_mode)) {
			rc = jffs2_set_acl(inode, ACL_TYPE_DEFAULT, acl);
			if (rc)
				goto cleanup;
		}
		clone = posix_acl_clone(acl, GFP_KERNEL);
		rc = -ENOMEM;
		if (!clone)
			goto cleanup;
		mode = inode->i_mode;
		rc = posix_acl_create_masq(clone, &mode);
		if (rc >= 0) {
			inode->i_mode = mode;
			if (rc > 0)
				rc = jffs2_set_acl(inode, ACL_TYPE_ACCESS, clone);
		}
		posix_acl_release(clone);
	}
 cleanup:
	posix_acl_release(acl);
	return rc;
}
Esempio n. 10
0
int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode)
{
	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
	struct posix_acl *acl, *clone;
	int rc;

	f->i_acl_default = NULL;
	f->i_acl_access = NULL;

	if (S_ISLNK(*i_mode))
		return 0;	/* Symlink always has no-ACL */

	acl = jffs2_get_acl(dir_i, ACL_TYPE_DEFAULT);
	if (IS_ERR(acl))
		return PTR_ERR(acl);

	if (!acl) {
		*i_mode &= ~current->fs->umask;
	} else {
		if (S_ISDIR(*i_mode))
			jffs2_iset_acl(inode, &f->i_acl_default, acl);

		clone = posix_acl_clone(acl, GFP_KERNEL);
		if (!clone)
			return -ENOMEM;
		rc = posix_acl_create_masq(clone, (mode_t *)i_mode);
		if (rc < 0) {
			posix_acl_release(clone);
			return rc;
		}
		if (rc > 0)
			jffs2_iset_acl(inode, &f->i_acl_access, clone);

		posix_acl_release(clone);
	}
	return 0;
}