Пример #1
0
static int
__zpl_xattr_acl_get_default(struct inode *ip, const char *name,
    void *buffer, size_t size)
{
	struct posix_acl *acl;
	int type = ACL_TYPE_DEFAULT;
	int error;
	/* xattr_resolve_name will do this for us if this is defined */
#ifndef HAVE_XATTR_HANDLER_NAME
	if (strcmp(name, "") != 0)
		return (-EINVAL);
#endif
	if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
		return (-EOPNOTSUPP);

	acl = zpl_get_acl(ip, type);
	if (IS_ERR(acl))
		return (PTR_ERR(acl));
	if (acl == NULL)
		return (-ENODATA);

	error = zpl_acl_to_xattr(acl, buffer, size);
	zpl_posix_acl_release(acl);

	return (error);
}
Пример #2
0
static int
__zpl_xattr_acl_set_default(struct inode *ip, const char *name,
    const void *value, size_t size, int flags)
{
	struct posix_acl *acl;
	int type = ACL_TYPE_DEFAULT;
	int error = 0;
	/* xattr_resolve_name will do this for us if this is defined */
#ifndef HAVE_XATTR_HANDLER_NAME
	if (strcmp(name, "") != 0)
		return (-EINVAL);
#endif
	if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
		return (-EOPNOTSUPP);

	if (!zpl_inode_owner_or_capable(ip))
		return (-EPERM);

	if (value) {
		acl = zpl_acl_from_xattr(value, size);
		if (IS_ERR(acl))
			return (PTR_ERR(acl));
		else if (acl) {
			error = zpl_posix_acl_valid(ip, acl);
			if (error) {
				zpl_posix_acl_release(acl);
				return (error);
			}
		}
	} else {
		acl = NULL;
	}

	error = zpl_set_acl(ip, acl, type);
	zpl_posix_acl_release(acl);

	return (error);
}
Пример #3
0
int
zpl_init_acl(struct inode *ip, struct inode *dir)
{
	struct posix_acl *acl = NULL;
	int error = 0;

	if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
		return (0);

	if (!S_ISLNK(ip->i_mode)) {
		if (ITOZSB(ip)->z_acl_type == ZFS_ACLTYPE_POSIXACL) {
			acl = zpl_get_acl(dir, ACL_TYPE_DEFAULT);
			if (IS_ERR(acl))
				return (PTR_ERR(acl));
		}

		if (!acl) {
			ip->i_mode &= ~current_umask();
			ip->i_ctime = current_fs_time(ITOZSB(ip)->z_sb);
			mark_inode_dirty(ip);
			return (0);
		}
	}

	if ((ITOZSB(ip)->z_acl_type == ZFS_ACLTYPE_POSIXACL) && acl) {
		umode_t mode;

		if (S_ISDIR(ip->i_mode)) {
			error = zpl_set_acl(ip, ACL_TYPE_DEFAULT, acl);
			if (error)
				goto out;
		}

		mode = ip->i_mode;
		error = posix_acl_create(&acl,GFP_KERNEL, &mode);
		if (error >= 0) {
			ip->i_mode = mode;
			mark_inode_dirty(ip);
			if (error > 0)
				error = zpl_set_acl(ip, ACL_TYPE_ACCESS, acl);
		}
	}
out:
	zpl_posix_acl_release(acl);

	return (error);
}
Пример #4
0
static int
__zpl_check_acl(struct inode *ip, int mask)
{
	struct posix_acl *acl;
	int error;

	acl = zpl_get_acl(ip, ACL_TYPE_ACCESS);
	if (IS_ERR(acl))
		return (PTR_ERR(acl));

	if (acl) {
		error = posix_acl_permission(ip, acl, mask);
		zpl_posix_acl_release(acl);
		return (error);
	}

	return (-EAGAIN);
}
Пример #5
0
int
zpl_chmod_acl(struct inode *ip)
{
	struct posix_acl *acl;
	int error;

	if (ITOZSB(ip)->z_acl_type != ZFS_ACLTYPE_POSIXACL)
		return (0);

	if (S_ISLNK(ip->i_mode))
		return (-EOPNOTSUPP);

	acl = zpl_get_acl(ip, ACL_TYPE_ACCESS);
	if (IS_ERR(acl) || !acl)
		return (PTR_ERR(acl));

	error = posix_acl_chmod(&acl,GFP_KERNEL, ip->i_mode);
	if (!error)
		error = zpl_set_acl(ip,ACL_TYPE_ACCESS, acl);

	zpl_posix_acl_release(acl);

	return (error);
}