Beispiel #1
0
/* Copy parameters and call proper function */
static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
		       void __user *addr, struct path *path)
{
	int ret;

	if (type >= (XQM_COMMAND(cmd) ? XQM_MAXQUOTAS : MAXQUOTAS))
		return -EINVAL;
	if (!sb->s_qcop)
		return -ENOSYS;

	ret = check_quotactl_permission(sb, type, cmd, id);
	if (ret < 0)
		return ret;

	switch (cmd) {
	case Q_QUOTAON:
		return quota_quotaon(sb, type, cmd, id, path);
	case Q_QUOTAOFF:
		if (!sb->s_qcop->quota_off)
			return -ENOSYS;
		return sb->s_qcop->quota_off(sb, type);
	case Q_GETFMT:
		return quota_getfmt(sb, type, addr);
	case Q_GETINFO:
		return quota_getinfo(sb, type, addr);
	case Q_SETINFO:
		return quota_setinfo(sb, type, addr);
	case Q_GETQUOTA:
		return quota_getquota(sb, type, id, addr);
	case Q_SETQUOTA:
		return quota_setquota(sb, type, id, addr);
	case Q_SYNC:
		if (!sb->s_qcop->quota_sync)
			return -ENOSYS;
		return sb->s_qcop->quota_sync(sb, type);
	case Q_XQUOTAON:
	case Q_XQUOTAOFF:
		return quota_setxstate(sb, cmd, addr);
	case Q_XQUOTARM:
		return quota_rmxquota(sb, addr);
	case Q_XGETQSTAT:
		return quota_getxstate(sb, addr);
	case Q_XGETQSTATV:
		return quota_getxstatev(sb, addr);
	case Q_XSETQLIM:
		return quota_setxquota(sb, type, id, addr);
	case Q_XGETQUOTA:
		return quota_getxquota(sb, type, id, addr);
	case Q_XQUOTASYNC:
		if (sb->s_flags & MS_RDONLY)
			return -EROFS;
		/* XFS quotas are fully coherent now, making this call a noop */
		return 0;
	default:
		return -EINVAL;
	}
}
Beispiel #2
0
/* Copy parameters and call proper function */
static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
		       void __user *addr, struct path *path)
{
	int ret;

	if (type >= (XQM_COMMAND(cmd) ? XQM_MAXQUOTAS : MAXQUOTAS))
		return -EINVAL;
	if (!sb->s_qcop)
		return -ENOSYS;

	ret = check_quotactl_permission(sb, type, cmd, id);
	if (ret < 0)
		return ret;

	switch (cmd) {
	case Q_QUOTAON:
		return quota_quotaon(sb, type, cmd, id, path);
	case Q_QUOTAOFF:
		if (!sb->s_qcop->quota_off)
			return -ENOSYS;
		return sb->s_qcop->quota_off(sb, type);
	case Q_GETFMT:
		return quota_getfmt(sb, type, addr);
	case Q_GETINFO:
		return quota_getinfo(sb, type, addr);
	case Q_SETINFO:
		return quota_setinfo(sb, type, addr);
	case Q_GETQUOTA:
		return quota_getquota(sb, type, id, addr);
	case Q_SETQUOTA:
		return quota_setquota(sb, type, id, addr);
	case Q_SYNC:
		if (!sb->s_qcop->quota_sync)
			return -ENOSYS;
		return sb->s_qcop->quota_sync(sb, type, 1);
	case Q_XQUOTAON:
	case Q_XQUOTAOFF:
	case Q_XQUOTARM:
		return quota_setxstate(sb, cmd, addr);
	case Q_XGETQSTAT:
		return quota_getxstate(sb, addr);
	case Q_XSETQLIM:
		return quota_setxquota(sb, type, id, addr);
	case Q_XGETQUOTA:
		return quota_getxquota(sb, type, id, addr);
	case Q_XQUOTASYNC:
		/* caller already holds s_umount */
		if (sb->s_flags & MS_RDONLY)
			return -EROFS;
		writeback_inodes_sb(sb, WB_REASON_SYNC);
		return 0;
	default:
		return -EINVAL;
	}
}
Beispiel #3
0
/*
 * This is the system call interface. This communicates with
 * the user-level programs. Currently this only supports diskquota
 * calls. Maybe we need to add the process quotas etc. in the future,
 * but we probably should use rlimits for that.
 */
asmlinkage long sys_quotactl(unsigned int cmd, const char *special, qid_t id, caddr_t addr)
{
    uint cmds, type;
    struct super_block *sb = NULL;
    int ret = -EINVAL;

    lock_kernel();
    cmds = cmd >> SUBCMDSHIFT;
    type = cmd & SUBCMDMASK;

#ifdef CONFIG_QIFACE_COMPAT
    if (cmds != Q_V1_GETSTATS && cmds != Q_V2_GETSTATS && IS_ERR(sb = resolve_dev(special))) {
        ret = PTR_ERR(sb);
        sb = NULL;
        goto out;
    }
    if (!NEW_COMMAND(cmds) && !XQM_COMMAND(cmds)) {
        if ((ret = check_compat_quotactl_valid(sb, type, cmds, id)) < 0)
            goto out;
        ret = do_compat_quotactl(sb, type, cmds, id, addr);
        goto out;
    }
#else
    if (IS_ERR(sb = resolve_dev(special))) {
        ret = PTR_ERR(sb);
        sb = NULL;
        goto out;
    }
#endif
    if ((ret = check_quotactl_valid(sb, type, cmds, id)) < 0)
        goto out;
    ret = do_quotactl(sb, type, cmds, id, addr);
out:
    if (sb)
        drop_super(sb);
    unlock_kernel();
    return ret;
}
Beispiel #4
0
/* Copy parameters and call proper function */
static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
                       void __user *addr, struct path *path)
{
    int ret;

    if (type >= (XQM_COMMAND(cmd) ? XQM_MAXQUOTAS : MAXQUOTAS))
        return -EINVAL;
    /*
     * Quota not supported on this fs? Check this before s_quota_types
     * since they needn't be set if quota is not supported at all.
     */
    if (!sb->s_qcop)
        return -ENOSYS;
    if (!(sb->s_quota_types & (1 << type)))
        return -EINVAL;

    ret = check_quotactl_permission(sb, type, cmd, id);
    if (ret < 0)
        return ret;

    switch (cmd) {
    case Q_QUOTAON:
        return quota_quotaon(sb, type, id, path);
    case Q_QUOTAOFF:
        return quota_quotaoff(sb, type);
    case Q_GETFMT:
        return quota_getfmt(sb, type, addr);
    case Q_GETINFO:
        return quota_getinfo(sb, type, addr);
    case Q_SETINFO:
        return quota_setinfo(sb, type, addr);
    case Q_GETQUOTA:
        return quota_getquota(sb, type, id, addr);
    case Q_GETNEXTQUOTA:
        return quota_getnextquota(sb, type, id, addr);
    case Q_SETQUOTA:
        return quota_setquota(sb, type, id, addr);
    case Q_SYNC:
        if (!sb->s_qcop->quota_sync)
            return -ENOSYS;
        return sb->s_qcop->quota_sync(sb, type);
    case Q_XQUOTAON:
        return quota_enable(sb, addr);
    case Q_XQUOTAOFF:
        return quota_disable(sb, addr);
    case Q_XQUOTARM:
        return quota_rmxquota(sb, addr);
    case Q_XGETQSTAT:
        return quota_getxstate(sb, addr);
    case Q_XGETQSTATV:
        return quota_getxstatev(sb, addr);
    case Q_XSETQLIM:
        return quota_setxquota(sb, type, id, addr);
    case Q_XGETQUOTA:
        return quota_getxquota(sb, type, id, addr);
    case Q_XGETNEXTQUOTA:
        return quota_getnextxquota(sb, type, id, addr);
    case Q_XQUOTASYNC:
        if (sb->s_flags & MS_RDONLY)
            return -EROFS;
        /* XFS quotas are fully coherent now, making this call a noop */
        return 0;
    default:
        return -EINVAL;
    }
}