[LTP] [PATCH v4 1/5] syscalls/quotactl01: Add Q_GETNEXTQUOTA test
Yang Xu
xuyang2018.jy@cn.fujitsu.com
Thu Nov 21 03:29:35 CET 2019
on 2019/11/20 23:12, Petr Vorel wrote:
> Hi Jan, Cyril, Xu,
>
>> Q_GETNEXTQUOTA was introduced since linux 4.6, this operation is the
>> same as Q_GETQUOTA, but it returns quota information for the next ID
>> greater than or equal to id that has a quota set.
>> Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com>
> Reviewed-by: Petr Vorel <pvorel@suse.cz>
>
> LGTM, with 2 questions.
>
>> #ifndef LAPI_QUOTACTL_H__
>> # define LAPI_QUOTACTL_H__
>> +#include <sys/quota.h>
>> +
>> +#ifdef HAVE_STRUCT_IF_NEXTDQBLK
>> +# include <linux/quota.h>
>> +#else
>> +# ifdef HAVE_LINUX_TYPES_H
>> +# include <linux/types.h>
> @Jan, @Cyril: Do we want to generally avoid loading <linux/types.h> if not really needed?
> __u64 can be uint64_t etc (as it's also visible in struct dqblk in <sys/quota.h>
> in various libc headers).
> We used this approach for /usr/include/linux/bpf.h and for fanotify fixes for
> musl (testcases/kernel/syscalls/fanotify/fanotify.h).
>
> So unless you're against this approach here I'll change it before merge
> (and add this info to next version of library API writing guidelines patch
> https://patchwork.ozlabs.org/patch/1166786/).
I have no objection about using uint64_t becuase Q_GETNEXTQUOTA man-pages also uses it.
I used struct if_nextdqblk as same as <linux/quota.h> defined. But I don't know why we can't use
<linux/type.h> in lapi/quotactl.h and I also use it in lapi/seccomp.h. IMHO, they affected nothing.
Or, they have some redefined errors or not having this headers files in special linux distribution.
>> +struct if_nextdqblk {
>> + __u64 dqb_bhardlimit;
>> + __u64 dqb_bsoftlimit;
>> + __u64 dqb_curspace;
>> + __u64 dqb_ihardlimit;
>> + __u64 dqb_isoftlimit;
>> + __u64 dqb_curinodes;
>> + __u64 dqb_btime;
>> + __u64 dqb_itime;
>> + __u32 dqb_valid;
>> + __u32 dqb_id;
>> +};
> ...
>> +++ b/testcases/kernel/syscalls/quotactl/quotactl01.c
>> @@ -1,7 +1,7 @@
>> // SPDX-License-Identifier: GPL-2.0-or-later
>> /*
>> * Copyright (c) Crackerjack Project., 2007
>> -* Copyright (c) 2016 Fujitsu Ltd.
>> +* Copyright (c) 2016-2019 FUJITSU LIMITED. All rights reserved
> BTW correct formatting is
> /*
> *
> */
> Not
> /*
> *
> */
> I'll change it during merge (nit, the code is what matters, not formatting, of course).
>
> ...
>> +static int getnextquota_nsup;
> ...
>> static void setup(void)
>> {
>> const char *const cmd[] = {"quotacheck", "-ugF", "vfsv0", MNTPOINT, NULL};
>> int ret;
>> + getnextquota_nsup = 0;
> This is not needed (getnextquota_nsup is static and it's called just once, I'll
> remove it before merge).
Yes.
>
>> ret = tst_run_cmd(cmd, NULL, NULL, 1);
>> switch (ret) {
>> @@ -146,6 +183,11 @@ static void setup(void)
>> if (access(GRPPATH, F_OK) == -1)
>> tst_brk(TFAIL | TERRNO, "group quotafile didn't exist");
>> +
>> + TEST(quotactl(QCMD(Q_GETNEXTQUOTA, USRQUOTA), tst_device->dev,
>> + test_id, (void *) &res_ndq));
>> + if (TST_ERR == EINVAL || TST_ERR == ENOSYS)
> Does EINVAL really mans not supported? Shouldn't be just for ENOSYS.
EINVAL can mean non-supported by using correct argument.
>> + getnextquota_nsup = 1;
>> }
> Looking at kernel sources - this does not look as not supported, but rather a
> failure (we might want to add some test for EINVAL):
> if (!qid_has_mapping(sb->s_user_ns, qid))
> return -EINVAL;
>
> kernel fs/quota/quota.c
> /*
> * 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_has_mapping(sb->s_user_ns, 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;
> }
Hi Petr
look do_quotactl function in fs/quota/quota.c.
static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
void __user *addr, const struct path *path)
{
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:
......
default:
return -EINVAL;
}
}
So if it doesn't have Q_GETNEXTQUOTA cmd, it should report EINVAL(we use correct argument and correct environment, so there is no failure).
> Kind regards,
> Petr
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linux.it/pipermail/ltp/attachments/20191121/a085db33/attachment-0001.htm>
More information about the ltp
mailing list