Exemple #1
0
static int
zpl_ioctl_setflags(struct file *filp, void __user *arg)
{
	struct inode	*ip = file_inode(filp);
	uint64_t	zfs_flags = ITOZ(ip)->z_pflags;
	unsigned int	ioctl_flags;
	cred_t		*cr = CRED();
	xvattr_t	xva;
	xoptattr_t	*xoap;
	int		error;
	fstrans_cookie_t cookie;

	if (copy_from_user(&ioctl_flags, arg, sizeof (ioctl_flags)))
		return (-EFAULT);

	if ((ioctl_flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NODUMP_FL)))
		return (-EOPNOTSUPP);

	if ((ioctl_flags & ~(FS_FL_USER_MODIFIABLE)))
		return (-EACCES);

	if ((fchange(ioctl_flags, zfs_flags, FS_IMMUTABLE_FL, ZFS_IMMUTABLE) ||
	    fchange(ioctl_flags, zfs_flags, FS_APPEND_FL, ZFS_APPENDONLY)) &&
	    !capable(CAP_LINUX_IMMUTABLE))
		return (-EACCES);

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

	xva_init(&xva);
	xoap = xva_getxoptattr(&xva);

	XVA_SET_REQ(&xva, XAT_IMMUTABLE);
	if (ioctl_flags & FS_IMMUTABLE_FL)
		xoap->xoa_immutable = B_TRUE;

	XVA_SET_REQ(&xva, XAT_APPENDONLY);
	if (ioctl_flags & FS_APPEND_FL)
		xoap->xoa_appendonly = B_TRUE;

	XVA_SET_REQ(&xva, XAT_NODUMP);
	if (ioctl_flags & FS_NODUMP_FL)
		xoap->xoa_nodump = B_TRUE;

	crhold(cr);
	cookie = spl_fstrans_mark();
	error = -zfs_setattr(ip, (vattr_t *)&xva, 0, cr);
	spl_fstrans_unmark(cookie);
	crfree(cr);

	return (error);
}
Exemple #2
0
static int
__zpl_ioctl_setflags(struct inode *ip, uint32_t ioctl_flags, xvattr_t *xva)
{
	uint64_t zfs_flags = ITOZ(ip)->z_pflags;
	xoptattr_t *xoap;

	if (ioctl_flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NODUMP_FL |
	    ZFS_PROJINHERIT_FL))
		return (-EOPNOTSUPP);

	if (ioctl_flags & ~ZFS_FL_USER_MODIFIABLE)
		return (-EACCES);

	if ((fchange(ioctl_flags, zfs_flags, FS_IMMUTABLE_FL, ZFS_IMMUTABLE) ||
	    fchange(ioctl_flags, zfs_flags, FS_APPEND_FL, ZFS_APPENDONLY)) &&
	    !capable(CAP_LINUX_IMMUTABLE))
		return (-EACCES);

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

	xva_init(xva);
	xoap = xva_getxoptattr(xva);

	XVA_SET_REQ(xva, XAT_IMMUTABLE);
	if (ioctl_flags & FS_IMMUTABLE_FL)
		xoap->xoa_immutable = B_TRUE;

	XVA_SET_REQ(xva, XAT_APPENDONLY);
	if (ioctl_flags & FS_APPEND_FL)
		xoap->xoa_appendonly = B_TRUE;

	XVA_SET_REQ(xva, XAT_NODUMP);
	if (ioctl_flags & FS_NODUMP_FL)
		xoap->xoa_nodump = B_TRUE;

	XVA_SET_REQ(xva, XAT_PROJINHERIT);
	if (ioctl_flags & ZFS_PROJINHERIT_FL)
		xoap->xoa_projinherit = B_TRUE;

	return (0);
}