Esempio n. 1
0
static int quota_setxquota(struct super_block *sb, int type, qid_t id,
                           void __user *addr)
{
    struct fs_disk_quota fdq;
    struct qc_dqblk qdq;
    struct kqid qid;

    if (copy_from_user(&fdq, addr, sizeof(fdq)))
        return -EFAULT;
    if (!sb->s_qcop->set_dqblk)
        return -ENOSYS;
    qid = make_kqid(current_user_ns(), type, id);
    if (!qid_valid(qid))
        return -EINVAL;
    /* Are we actually setting timer / warning limits for all users? */
    if (from_kqid(&init_user_ns, qid) == 0 &&
            fdq.d_fieldmask & (FS_DQ_WARNS_MASK | FS_DQ_TIMER_MASK)) {
        struct qc_info qinfo;
        int ret;

        if (!sb->s_qcop->set_info)
            return -EINVAL;
        copy_qcinfo_from_xfs_dqblk(&qinfo, &fdq);
        ret = sb->s_qcop->set_info(sb, type, &qinfo);
        if (ret)
            return ret;
        /* These are already done */
        fdq.d_fieldmask &= ~(FS_DQ_WARNS_MASK | FS_DQ_TIMER_MASK);
    }
    copy_from_xfs_dqblk(&qdq, &fdq);
    return sb->s_qcop->set_dqblk(sb, qid, &qdq);
}
Esempio n. 2
0
static int v1_commit_dqblk(struct dquot *dquot)
{
	short type = dquot->dq_id.type;
	ssize_t ret;
	struct v1_disk_dqblk dqblk;

	v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb);
	if (((type == USRQUOTA) && uid_eq(dquot->dq_id.uid, GLOBAL_ROOT_UID)) ||
	    ((type == GRPQUOTA) && gid_eq(dquot->dq_id.gid, GLOBAL_ROOT_GID))) {
		dqblk.dqb_btime =
			sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace;
		dqblk.dqb_itime =
			sb_dqopt(dquot->dq_sb)->info[type].dqi_igrace;
	}
	ret = 0;
	if (sb_dqopt(dquot->dq_sb)->files[type])
		ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type,
			(char *)&dqblk, sizeof(struct v1_disk_dqblk),
			v1_dqoff(from_kqid(&init_user_ns, dquot->dq_id)));
	if (ret != sizeof(struct v1_disk_dqblk)) {
		quota_error(dquot->dq_sb, "dquota write failed");
		if (ret >= 0)
			ret = -EIO;
		goto out;
	}
	ret = 0;

out:
	dqstats_inc(DQST_WRITES);

	return ret;
}
Esempio n. 3
0
static int v1_read_dqblk(struct dquot *dquot)
{
	int type = dquot->dq_id.type;
	struct v1_disk_dqblk dqblk;
	struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);

	if (!dqopt->files[type])
		return -EINVAL;

	/* Set structure to 0s in case read fails/is after end of file */
	memset(&dqblk, 0, sizeof(struct v1_disk_dqblk));
	dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk,
			sizeof(struct v1_disk_dqblk),
			v1_dqoff(from_kqid(&init_user_ns, dquot->dq_id)));

	v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk);
	if (dquot->dq_dqb.dqb_bhardlimit == 0 &&
	    dquot->dq_dqb.dqb_bsoftlimit == 0 &&
	    dquot->dq_dqb.dqb_ihardlimit == 0 &&
	    dquot->dq_dqb.dqb_isoftlimit == 0)
		set_bit(DQ_FAKE_B, &dquot->dq_flags);
	dqstats_inc(DQST_READS);

	return 0;
}
Esempio n. 4
0
STATIC int
xfs_fs_get_dqblk(
	struct super_block	*sb,
	struct kqid		qid,
	struct qc_dqblk		*qdq)
{
	struct xfs_mount	*mp = XFS_M(sb);

	if (!XFS_IS_QUOTA_RUNNING(mp))
		return -ENOSYS;
	if (!XFS_IS_QUOTA_ON(mp))
		return -ESRCH;

	return xfs_qm_scall_getquota(mp, from_kqid(&init_user_ns, qid),
				      xfs_quota_type(qid.type), qdq);
}
Esempio n. 5
0
STATIC int
xfs_fs_set_dqblk(
	struct super_block	*sb,
	struct kqid		qid,
	struct fs_disk_quota	*fdq)
{
	struct xfs_mount	*mp = XFS_M(sb);

	if (sb->s_flags & MS_RDONLY)
		return -EROFS;
	if (!XFS_IS_QUOTA_RUNNING(mp))
		return -ENOSYS;
	if (!XFS_IS_QUOTA_ON(mp))
		return -ESRCH;

	return -xfs_qm_scall_setqlim(mp, from_kqid(&init_user_ns, qid),
				     xfs_quota_type(qid.type), fdq);
}
Esempio n. 6
0
static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot)
{
	struct v2r1_disk_dqblk *d = dp;
	struct mem_dqblk *m = &dquot->dq_dqb;
	struct qtree_mem_dqinfo *info =
			sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv;

	d->dqb_ihardlimit = cpu_to_le64(m->dqb_ihardlimit);
	d->dqb_isoftlimit = cpu_to_le64(m->dqb_isoftlimit);
	d->dqb_curinodes = cpu_to_le64(m->dqb_curinodes);
	d->dqb_itime = cpu_to_le64(m->dqb_itime);
	d->dqb_bhardlimit = cpu_to_le64(v2_stoqb(m->dqb_bhardlimit));
	d->dqb_bsoftlimit = cpu_to_le64(v2_stoqb(m->dqb_bsoftlimit));
	d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
	d->dqb_btime = cpu_to_le64(m->dqb_btime);
	d->dqb_id = cpu_to_le32(from_kqid(&init_user_ns, dquot->dq_id));
	if (qtree_entry_unused(info, dp))
		d->dqb_itime = cpu_to_le64(1);
}
Esempio n. 7
0
/*
 * Return quota for next active quota >= this id, if any exists,
 * otherwise return -ENOENT via ->get_nextdqblk.
 */
static int quota_getnextxquota(struct super_block *sb, int type, qid_t id,
                               void __user *addr)
{
    struct fs_disk_quota fdq;
    struct qc_dqblk qdq;
    struct kqid qid;
    qid_t id_out;
    int ret;

    if (!sb->s_qcop->get_nextdqblk)
        return -ENOSYS;
    qid = make_kqid(current_user_ns(), type, id);
    if (!qid_valid(qid))
        return -EINVAL;
    ret = sb->s_qcop->get_nextdqblk(sb, &qid, &qdq);
    if (ret)
        return ret;
    id_out = from_kqid(current_user_ns(), qid);
    copy_to_xfs_dqblk(&fdq, &qdq, type, id_out);
    if (copy_to_user(addr, &fdq, sizeof(fdq)))
        return -EFAULT;
    return ret;
}
Esempio n. 8
0
/*
 * Return quota for next active quota >= this id, if any exists,
 * otherwise return -ENOENT via ->get_nextdqblk
 */
static int quota_getnextquota(struct super_block *sb, int type, qid_t id,
                              void __user *addr)
{
    struct kqid qid;
    struct qc_dqblk fdq;
    struct if_nextdqblk idq;
    int ret;

    if (!sb->s_qcop->get_nextdqblk)
        return -ENOSYS;
    qid = make_kqid(current_user_ns(), type, id);
    if (!qid_valid(qid))
        return -EINVAL;
    ret = sb->s_qcop->get_nextdqblk(sb, &qid, &fdq);
    if (ret)
        return ret;
    /* struct if_nextdqblk is a superset of struct if_dqblk */
    copy_to_if_dqblk((struct if_dqblk *)&idq, &fdq);
    idq.dqb_id = from_kqid(current_user_ns(), qid);
    if (copy_to_user(addr, &idq, sizeof(idq)))
        return -EFAULT;
    return 0;
}