Ejemplo n.º 1
0
STATIC int
xfs_fs_set_xstate(
	struct super_block	*sb,
	unsigned int		uflags,
	int			op)
{
	struct xfs_mount	*mp = XFS_M(sb);
	unsigned int		flags = 0;

	if (sb->s_flags & MS_RDONLY)
		return -EROFS;
	if (!XFS_IS_QUOTA_RUNNING(mp))
		return -ENOSYS;
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	if (uflags & XFS_QUOTA_UDQ_ACCT)
		flags |= XFS_UQUOTA_ACCT;
	if (uflags & XFS_QUOTA_PDQ_ACCT)
		flags |= XFS_PQUOTA_ACCT;
	if (uflags & XFS_QUOTA_GDQ_ACCT)
		flags |= XFS_GQUOTA_ACCT;
	if (uflags & XFS_QUOTA_UDQ_ENFD)
		flags |= XFS_UQUOTA_ENFD;
	if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD))
		flags |= XFS_OQUOTA_ENFD;

	switch (op) {
	case Q_XQUOTAON:
		return -xfs_qm_scall_quotaon(mp, flags);
	case Q_XQUOTAOFF:
		if (!XFS_IS_QUOTA_ON(mp))
			return -EINVAL;
		return -xfs_qm_scall_quotaoff(mp, flags);
	case Q_XQUOTARM:
		if (XFS_IS_QUOTA_ON(mp))
			return -EINVAL;
		return -xfs_qm_scall_trunc_qfiles(mp, flags);
	}

	return -EINVAL;
}
Ejemplo n.º 2
0
STATIC int
xfs_fs_set_xstate(
	struct super_block	*sb,
	unsigned int		uflags,
	int			op)
{
	struct xfs_mount	*mp = XFS_M(sb);
	unsigned int		flags = 0;

	if (sb->s_flags & MS_RDONLY)
		return -EROFS;
	if (op != Q_XQUOTARM && !XFS_IS_QUOTA_RUNNING(mp))
		return -ENOSYS;

	if (uflags & FS_QUOTA_UDQ_ACCT)
		flags |= XFS_UQUOTA_ACCT;
	if (uflags & FS_QUOTA_PDQ_ACCT)
		flags |= XFS_PQUOTA_ACCT;
	if (uflags & FS_QUOTA_GDQ_ACCT)
		flags |= XFS_GQUOTA_ACCT;
	if (uflags & FS_QUOTA_UDQ_ENFD)
		flags |= XFS_UQUOTA_ENFD;
	if (uflags & FS_QUOTA_GDQ_ENFD)
		flags |= XFS_GQUOTA_ENFD;
	if (uflags & FS_QUOTA_PDQ_ENFD)
		flags |= XFS_PQUOTA_ENFD;

	switch (op) {
	case Q_XQUOTAON:
		return xfs_qm_scall_quotaon(mp, flags);
	case Q_XQUOTAOFF:
		if (!XFS_IS_QUOTA_ON(mp))
			return -EINVAL;
		return xfs_qm_scall_quotaoff(mp, flags);
	}

	return -EINVAL;
}
Ejemplo n.º 3
0
/*
 * The main distribution switch of all XFS quotactl system calls.
 */
int
xfs_qm_quotactl(
	struct bhv_desc *bdp,
	int		cmd,
	int		id,
	xfs_caddr_t	addr)
{
	xfs_mount_t	*mp;
	bhv_vfs_t	*vfsp;
	int		error;

	vfsp = bhvtovfs(bdp);
	mp = XFS_VFSTOM(vfsp);

	ASSERT(addr != NULL || cmd == Q_XQUOTASYNC);

	/*
	 * The following commands are valid even when quotaoff.
	 */
	switch (cmd) {
	case Q_XQUOTARM:
		/*
		 * Truncate quota files. quota must be off.
		 */
		if (XFS_IS_QUOTA_ON(mp))
			return XFS_ERROR(EINVAL);
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		return (xfs_qm_scall_trunc_qfiles(mp,
			       xfs_qm_import_qtype_flags(*(uint *)addr)));

	case Q_XGETQSTAT:
		/*
		 * Get quota status information.
		 */
		return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr));

	case Q_XQUOTAON:
		/*
		 * QUOTAON - enabling quota enforcement.
		 * Quota accounting must be turned on at mount time.
		 */
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		return (xfs_qm_scall_quotaon(mp,
					  xfs_qm_import_flags(*(uint *)addr)));

	case Q_XQUOTAOFF:
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		break;

	case Q_XQUOTASYNC:
		return (xfs_sync_inodes(mp, SYNC_DELWRI, NULL));

	default:
		break;
	}

	if (! XFS_IS_QUOTA_ON(mp))
		return XFS_ERROR(ESRCH);

	switch (cmd) {
	case Q_XQUOTAOFF:
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		error = xfs_qm_scall_quotaoff(mp,
					    xfs_qm_import_flags(*(uint *)addr),
					    B_FALSE);
		break;

	case Q_XGETQUOTA:
		error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER,
					(fs_disk_quota_t *)addr);
		break;
	case Q_XGETGQUOTA:
		error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
					(fs_disk_quota_t *)addr);
		break;
	case Q_XGETPQUOTA:
		error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
					(fs_disk_quota_t *)addr);
		break;

	case Q_XSETQLIM:
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER,
					     (fs_disk_quota_t *)addr);
		break;
	case Q_XSETGQLIM:
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
					     (fs_disk_quota_t *)addr);
		break;
	case Q_XSETPQLIM:
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_PROJ,
					     (fs_disk_quota_t *)addr);
		break;

	default:
		error = XFS_ERROR(EINVAL);
		break;
	}

	return (error);
}
Ejemplo n.º 4
0
/*
 * The main distribution switch of all XFS quotactl system calls.
 */
int
xfs_qm_quotactl(
	struct bhv_desc *bdp,
	int		cmd,
	int		id,
	xfs_caddr_t	addr)
{
	xfs_mount_t	*mp;
	int		error;
	struct vfs	*vfsp;

	vfsp = bhvtovfs(bdp);
	mp = XFS_VFSTOM(vfsp);

	if (addr == NULL && cmd != Q_SYNC)
		return XFS_ERROR(EINVAL);
	if (id < 0 && cmd != Q_SYNC)
		return XFS_ERROR(EINVAL);

	/*
	 * The following commands are valid even when quotaoff.
	 */
	switch (cmd) {
		/*
		 * truncate quota files. quota must be off.
		 */
	      case Q_XQUOTARM:
		if (XFS_IS_QUOTA_ON(mp) || addr == NULL)
			return XFS_ERROR(EINVAL);
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		return (xfs_qm_scall_trunc_qfiles(mp,
			       xfs_qm_import_qtype_flags(*(uint *)addr)));
		/*
		 * Get quota status information.
		 */
	      case Q_XGETQSTAT:
		return (xfs_qm_scall_getqstat(mp, (fs_quota_stat_t *)addr));

		/*
		 * QUOTAON for root f/s and quota enforcement on others..
		 * Quota accounting for non-root f/s's must be turned on
		 * at mount time.
		 */
	      case Q_XQUOTAON:
		if (addr == NULL)
			return XFS_ERROR(EINVAL);
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		return (xfs_qm_scall_quotaon(mp,
					  xfs_qm_import_flags(*(uint *)addr)));
	      case Q_XQUOTAOFF:
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		break;

	      default:
		break;
	}

	if (! XFS_IS_QUOTA_ON(mp))
		return XFS_ERROR(ESRCH);

	switch (cmd) {
	      case Q_XQUOTAOFF:
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		error = xfs_qm_scall_quotaoff(mp,
					    xfs_qm_import_flags(*(uint *)addr),
					    B_FALSE);
		break;

		/*
		 * Defaults to XFS_GETUQUOTA.
		 */
	      case Q_XGETQUOTA:
		error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_USER,
					(fs_disk_quota_t *)addr);
		break;
		/*
		 * Set limits, both hard and soft. Defaults to Q_SETUQLIM.
		 */
	      case Q_XSETQLIM:
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_USER,
					     (fs_disk_quota_t *)addr);
		break;

	       case Q_XSETGQLIM:
		if (vfsp->vfs_flag & VFS_RDONLY)
			return XFS_ERROR(EROFS);
		error = xfs_qm_scall_setqlim(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
					     (fs_disk_quota_t *)addr);
		break;


	      case Q_XGETGQUOTA:
		error = xfs_qm_scall_getquota(mp, (xfs_dqid_t)id, XFS_DQ_GROUP,
					(fs_disk_quota_t *)addr);
		break;

		/*
		 * Quotas are entirely undefined after quotaoff in XFS quotas.
		 * For instance, there's no way to set limits when quotaoff.
		 */

	      default:
		error = XFS_ERROR(EINVAL);
		break;
	}

	return (error);
}