1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2016 Red Hat, Inc.
10 #include <sys/types.h>
14 * Exercise the Q_GETNEXTQUOTA and Q_XGETNEXTQUOTA quotactls.
15 * Really only returns a bare minimum of quota information,
16 * just enough to be sure we got a sane answer back.
18 * These quotactls take a quota ID as input, and return the
19 * next active quota >= that ID.
22 * test-nextquota [-v] -[u|g|p] -i id -d device
29 #ifndef Q_GETNEXTQUOTA
30 #define Q_GETNEXTQUOTA 0x800009 /* get disk limits and usage >= ID */
33 /* glibc 2.24 defines Q_GETNEXTQUOTA but not struct nextdqblk. */
36 u_int64_t dqb_bhardlimit; /* absolute limit on disk quota blocks alloc */
37 u_int64_t dqb_bsoftlimit; /* preferred limit on disk quota blocks */
38 u_int64_t dqb_curspace; /* current quota block count */
39 u_int64_t dqb_ihardlimit; /* maximum # allocated inodes */
40 u_int64_t dqb_isoftlimit; /* preferred inode limit */
41 u_int64_t dqb_curinodes; /* current # allocated inodes */
42 u_int64_t dqb_btime; /* time limit for excessive disk use */
43 u_int64_t dqb_itime; /* time limit for excessive files */
44 u_int32_t dqb_valid; /* bitmask of QIF_* constants */
45 u_int32_t dqb_id; /* id for this quota info*/
48 #ifndef Q_XGETNEXTQUOTA
49 #define Q_XGETNEXTQUOTA XQM_CMD(9)
52 void usage(char *progname)
54 printf("usage: %s [-v] -[u|g|p] -i id -d device\n", progname);
58 int main(int argc, char *argv[])
62 int type = -1, typeflag = 0;
65 uint id = 0, idflag = 0;
68 struct test_nextdqblk dqb;
69 struct fs_disk_quota xqb;
71 while ((c = getopt(argc,argv,"ugpi:d:v")) != EOF) {
86 id = (uint) strtoul(optarg, &tmp, 0);
88 fprintf(stderr, "Bad id: %s\n", optarg);
105 printf("No id specified\n");
109 printf("No type specified\n");
113 printf("Multiple types specified\n");
116 if (device == NULL) {
117 printf("No device specified\n");
122 printf("asking for quota type %d for id %u on %s\n", type, id, device);
124 memset(&dqb, 0, sizeof(struct test_nextdqblk));
125 memset(&xqb, 0, sizeof(struct fs_disk_quota));
128 printf("====Q_GETNEXTQUOTA====\n");
129 cmd = QCMD(Q_GETNEXTQUOTA, type);
130 if (quotactl(cmd, device, id, (void *)&dqb) < 0) {
131 perror("Q_GETNEXTQUOTA");
135 * We only print id and inode limits because
136 * block count varies depending on fs block size, etc;
137 * this is just a sanity test that we can retrieve the quota,
138 * and inode limits have the same units across both calls.
140 printf("id %u\n", dqb.dqb_id);
141 printf("ihard %llu\n",
142 (unsigned long long)dqb.dqb_ihardlimit);
143 printf("isoft %llu\n",
144 (unsigned long long)dqb.dqb_isoftlimit);
148 printf("====Q_XGETNEXTQUOTA====\n");
149 cmd = QCMD(Q_XGETNEXTQUOTA, USRQUOTA);
150 if (quotactl(cmd, device, id, (void *)&xqb) < 0) {
151 perror("Q_XGETNEXTQUOTA");
154 printf("id %u\n", xqb.d_id);
155 printf("ihard %llu\n", xqb.d_ino_hardlimit);
156 printf("isoft %llu\n", xqb.d_ino_softlimit);