]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - quota/state.c
xfs_quota: state command should report ugp grace times
[thirdparty/xfsprogs-dev.git] / quota / state.c
CommitLineData
959ef981 1// SPDX-License-Identifier: GPL-2.0
5aead01d 2/*
da23017d
NS
3 * Copyright (c) 2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
5aead01d 5 */
29647c8d 6#include <stdbool.h>
6b803e5a 7#include "command.h"
5aead01d
NS
8#include "init.h"
9#include "quota.h"
10
11static cmdinfo_t off_cmd;
12static cmdinfo_t state_cmd;
13static cmdinfo_t enable_cmd;
14static cmdinfo_t disable_cmd;
15static cmdinfo_t remove_cmd;
16
17static void
18off_help(void)
19{
20 printf(_(
21"\n"
22" turn filesystem quota off, both accounting and enforcement\n"
23"\n"
24" Example:\n"
25" 'off -uv' (switch off user quota on the current filesystem)\n"
26" This command is the equivalent of the traditional quotaoff command,\n"
27" which disables quota completely on a mounted filesystem.\n"
28" Note that there is no 'on' command - for XFS filesystems (with the\n"
29" exception of the root filesystem on IRIX) quota can only be enabled\n"
30" at mount time, through the use of one of the quota mount options.\n"
31"\n"
32" The state command is useful for displaying the current state. Using\n"
33" the -v (verbose) option with the 'off' command will display the quota\n"
34" state for the affected filesystem once the operation is complete.\n"
35" The affected quota type is -g (groups), -p (projects) or -u (users)\n"
36" and defaults to user quota (multiple types can be specified).\n"
37"\n"));
38}
39
40static void
41state_help(void)
42{
43 printf(_(
44"\n"
45" query the state of quota on the current filesystem\n"
46"\n"
47" This is a verbose status command, reporting whether or not accounting\n"
48" and/or enforcement are enabled for a filesystem, which inodes are in\n"
49" use as the quota state inodes, and how many extents and blocks are\n"
50" presently being used to hold that information.\n"
51" The quota type is specified via -g (groups), -p (projects) or -u (users)\n"
52" and defaults to user quota (multiple types can be specified).\n"
53"\n"));
54}
55
56static void
57enable_help(void)
58{
59 printf(_(
60"\n"
61" enable quota enforcement on a filesystem\n"
62"\n"
63" If a filesystem is mounted and has quota accounting enabled, but not\n"
64" quota enforcement, enforcement can be enabled with this command.\n"
65" With the -v (verbose) option, the status of the filesystem will be\n"
66" reported after the operation is complete.\n"
67" The affected quota type is -g (groups), -p (projects) or -u (users)\n"
68" and defaults to user quota (multiple types can be specified).\n"
69"\n"));
70}
71
72static void
73disable_help(void)
74{
75 printf(_(
76"\n"
77" disable quota enforcement on a filesystem\n"
78"\n"
79" If a filesystem is mounted and is currently enforcing quota, this\n"
80" provides a mechanism to switch off the enforcement, but continue to\n"
81" perform used space (and used inodes) accounting.\n"
82" The affected quota type is -g (groups), -p (projects) or -u (users).\n"
83"\n"));
84}
85
86static void
87remove_help(void)
88{
89 printf(_(
90"\n"
91" remove any space being used by the quota subsystem\n"
92"\n"
93" Once quota has been switched 'off' on a filesystem, the space that\n"
94" was allocated to holding quota metadata can be freed via this command.\n"
95" The affected quota type is -g (groups), -p (projects) or -u (users)\n"
96" and defaults to user quota (multiple types can be specified).\n"
97"\n"));
98}
99
100static void
101state_qfilestat(
bb92709f
ES
102 FILE *fp,
103 struct fs_path *mount,
104 uint type,
105 struct fs_qfilestatv *qfs,
106 int accounting,
107 int enforcing)
5aead01d
NS
108{
109 fprintf(fp, _("%s quota state on %s (%s)\n"), type_to_string(type),
110 mount->fs_dir, mount->fs_name);
111 fprintf(fp, _(" Accounting: %s\n"), accounting ? _("ON") : _("OFF"));
112 fprintf(fp, _(" Enforcement: %s\n"), enforcing ? _("ON") : _("OFF"));
06065b12
AE
113 if (qfs->qfs_ino != (__u64) -1)
114 fprintf(fp, _(" Inode: #%llu (%llu blocks, %lu extents)\n"),
115 (unsigned long long)qfs->qfs_ino,
116 (unsigned long long)qfs->qfs_nblks,
117 (unsigned long)qfs->qfs_nextents);
118 else
119 fprintf(fp, _(" Inode: N/A\n"));
5aead01d
NS
120}
121
122static void
123state_timelimit(
124 FILE *fp,
125 uint form,
14f8b681 126 uint32_t timelimit)
5aead01d
NS
127{
128 fprintf(fp, _("%s grace time: %s\n"),
129 form_to_string(form),
130 time_to_string(timelimit, VERBOSE_FLAG | ABSOLUTE_FLAG));
131}
132
387a96e1
DW
133static void
134state_warnlimit(
135 FILE *fp,
136 uint form,
137 uint16_t warnlimit)
138{
139 fprintf(fp, _("%s max warnings: %u\n"),
140 form_to_string(form), warnlimit);
141}
142
bb92709f
ES
143/*
144 * fs_quota_stat holds a subset of fs_quota_statv; this copies
145 * the smaller into the larger, leaving any not-present fields
146 * empty. This is so the same reporting function can be used
147 * for both XFS_GETQSTAT and XFS_GETQSTATV results.
148 */
149static void
150state_stat_to_statv(
151 struct fs_quota_stat *s,
152 struct fs_quota_statv *sv)
153{
154 memset(sv, 0, sizeof(struct fs_quota_statv));
155
156 /* shared information */
157 sv->qs_version = s->qs_version;
158 sv->qs_flags = s->qs_flags;
159 sv->qs_incoredqs = s->qs_incoredqs;
160 sv->qs_btimelimit = s->qs_btimelimit;
161 sv->qs_itimelimit = s->qs_itimelimit;
162 sv->qs_rtbtimelimit = s->qs_rtbtimelimit;
163 sv->qs_bwarnlimit = s->qs_bwarnlimit;
164 sv->qs_iwarnlimit = s->qs_iwarnlimit;
165
166 /* Always room for uquota */
167 sv->qs_uquota.qfs_ino = s->qs_uquota.qfs_ino;
168 sv->qs_uquota.qfs_nblks = s->qs_uquota.qfs_nblks;
169 sv->qs_uquota.qfs_nextents = s->qs_uquota.qfs_nextents;
170
171 /*
172 * If we are here, XFS_GETQSTATV failed and XFS_GETQSTAT passed;
173 * that is a very strong hint that we're on a kernel which predates
174 * the on-disk pquota inode; both were added in v3.12. So, we do
175 * some tricksy determination here.
176 * gs_gquota may hold either group quota inode info, or project
177 * quota if that is used instead; which one it actually holds depends
178 * on the quota flags. (If neither is set, neither is used)
179 */
180 if (s->qs_flags & XFS_QUOTA_GDQ_ACCT) {
181 /* gs_gquota holds group quota info */
182 sv->qs_gquota.qfs_ino = s->qs_gquota.qfs_ino;
183 sv->qs_gquota.qfs_nblks = s->qs_gquota.qfs_nblks;
184 sv->qs_gquota.qfs_nextents = s->qs_gquota.qfs_nextents;
185 } else if (s->qs_flags & XFS_QUOTA_PDQ_ACCT) {
186 /* gs_gquota actually holds project quota info */
187 sv->qs_pquota.qfs_ino = s->qs_gquota.qfs_ino;
188 sv->qs_pquota.qfs_nblks = s->qs_gquota.qfs_nblks;
189 sv->qs_pquota.qfs_nextents = s->qs_gquota.qfs_nextents;
190 }
191}
192
5aead01d 193static void
d8a94546 194state_quotafile_stat(
bb92709f
ES
195 FILE *fp,
196 uint type,
d8a94546
BD
197 struct fs_path *mount,
198 struct fs_quota_statv *sv,
199 struct fs_quota_stat *s,
bb92709f 200 uint flags)
5aead01d 201{
d8a94546
BD
202 bool accounting, enforcing;
203 struct fs_qfilestatv *qsv;
bb92709f
ES
204 char *dev = mount->fs_name;
205
d8a94546
BD
206 if (xfsquotactl(XFS_GETQSTATV, dev, type, 0, (void *)sv) < 0) {
207 if (xfsquotactl(XFS_GETQSTAT, dev, type, 0, (void *)s) < 0) {
bb92709f
ES
208 if (flags & VERBOSE_FLAG)
209 fprintf(fp,
210 _("%s quota are not enabled on %s\n"),
211 type_to_string(type), dev);
212 return;
213 }
d8a94546
BD
214 state_stat_to_statv(s, sv);
215 }
216
217 switch(type) {
218 case XFS_USER_QUOTA:
219 qsv = &sv->qs_uquota;
220 accounting = sv->qs_flags & XFS_QUOTA_UDQ_ACCT;
221 enforcing = sv->qs_flags & XFS_QUOTA_UDQ_ENFD;
222 break;
223 case XFS_GROUP_QUOTA:
224 qsv = &sv->qs_gquota;
225 accounting = sv->qs_flags & XFS_QUOTA_GDQ_ACCT;
226 enforcing = sv->qs_flags & XFS_QUOTA_GDQ_ENFD;
227 break;
228 case XFS_PROJ_QUOTA:
229 qsv = &sv->qs_pquota;
230 accounting = sv->qs_flags & XFS_QUOTA_PDQ_ACCT;
231 enforcing = sv->qs_flags & XFS_QUOTA_PDQ_ENFD;
232 break;
233 default:
234 return;
235 }
236
237
238 state_qfilestat(fp, mount, type, qsv, accounting, enforcing);
239
240 state_timelimit(fp, XFS_BLOCK_QUOTA, sv->qs_btimelimit);
241 state_warnlimit(fp, XFS_BLOCK_QUOTA, sv->qs_bwarnlimit);
242
243 state_timelimit(fp, XFS_INODE_QUOTA, sv->qs_itimelimit);
244 state_warnlimit(fp, XFS_INODE_QUOTA, sv->qs_iwarnlimit);
245
246 state_timelimit(fp, XFS_RTBLOCK_QUOTA, sv->qs_rtbtimelimit);
247}
248
249static void
250state_quotafile_mount(
251 FILE *fp,
252 uint type,
253 struct fs_path *mount,
254 uint flags)
255{
256 struct fs_quota_stat s;
257 struct fs_quota_statv sv;
258
259 sv.qs_version = FS_QSTATV_VERSION1;
260
261 if (type & XFS_USER_QUOTA) {
262 state_quotafile_stat(fp, XFS_USER_QUOTA, mount,
263 &sv, &s, flags);
264 }
265
266 if (type & XFS_GROUP_QUOTA) {
267 state_quotafile_stat(fp, XFS_GROUP_QUOTA, mount,
268 &sv, &s, flags);
5aead01d
NS
269 }
270
d8a94546
BD
271 if (type & XFS_PROJ_QUOTA) {
272 state_quotafile_stat(fp, XFS_PROJ_QUOTA, mount,
273 &sv, &s, flags);
274 }
5aead01d
NS
275}
276
277static void
278state_quotafile(
279 FILE *fp,
280 uint type,
281 char *dir,
282 uint flags)
283{
284 fs_cursor_t cursor;
285 fs_path_t *mount;
286
287 fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor);
288 while ((mount = fs_cursor_next_entry(&cursor)))
289 state_quotafile_mount(fp, type, mount, flags);
290}
291
292static int
293state_f(
294 int argc,
295 char **argv)
296{
297 FILE *fp = NULL;
298 char *fname = NULL;
299 int c, flags = 0, type = 0;
300
301 while ((c = getopt(argc, argv, "af:gpuv")) != EOF) {
302 switch (c) {
303 case 'a':
304 flags |= ALL_MOUNTS_FLAG;
305 break;
306 case 'f':
307 fname = optarg;
308 break;
309 case 'g':
310 type |= XFS_GROUP_QUOTA;
311 break;
312 case 'p':
313 type |= XFS_PROJ_QUOTA;
314 break;
315 case 'u':
316 type |= XFS_USER_QUOTA;
317 break;
318 case 'v':
319 flags |= VERBOSE_FLAG;
320 break;
321 default:
322 return command_usage(&state_cmd);
323 }
324 }
325
326 if (argc != optind)
327 return command_usage(&state_cmd);
328
329 if ((fp = fopen_write_secure(fname)) == NULL)
330 return 0;
331
332 if (!type)
333 type = XFS_USER_QUOTA | XFS_GROUP_QUOTA | XFS_PROJ_QUOTA;
334
fa13a00f
NS
335 if (flags & ALL_MOUNTS_FLAG)
336 state_quotafile(fp, type, NULL, flags);
04418c59 337 else if (fs_path && fs_path->fs_flags & FS_MOUNT_POINT)
fa13a00f 338 state_quotafile(fp, type, fs_path->fs_dir, flags);
5aead01d
NS
339
340 if (fname)
341 fclose(fp);
342 return 0;
343}
344
345static void
346enable_enforcement(
347 char *dir,
348 uint type,
349 uint qflags,
350 uint flags)
351{
352 fs_path_t *mount;
5aead01d
NS
353
354 mount = fs_table_lookup(dir, FS_MOUNT_POINT);
355 if (!mount) {
e3210fd8 356 exitcode = 1;
5aead01d
NS
357 fprintf(stderr, "%s: unknown mount point %s\n", progname, dir);
358 return;
359 }
360 dir = mount->fs_name;
ca42fa70
BD
361 if (xfsquotactl(XFS_QUOTAON, dir, type, 0, (void *)&qflags) < 0) {
362 if (errno == EEXIST)
363 fprintf(stderr,
364 _("Quota enforcement already enabled.\n"));
365 else if (errno == EINVAL || errno == ENOSYS)
366 fprintf(stderr,
367 _("Can't enable enforcement when quota off.\n"));
368 else
369 perror("XFS_QUOTAON");
370 }
5aead01d
NS
371 else if (flags & VERBOSE_FLAG)
372 state_quotafile_mount(stdout, type, mount, flags);
373}
374
375static void
376disable_enforcement(
377 char *dir,
378 uint type,
379 uint qflags,
380 uint flags)
381{
382 fs_path_t *mount;
5aead01d
NS
383
384 mount = fs_table_lookup(dir, FS_MOUNT_POINT);
385 if (!mount) {
e3210fd8 386 exitcode = 1;
5aead01d
NS
387 fprintf(stderr, "%s: unknown mount point %s\n", progname, dir);
388 return;
389 }
390 dir = mount->fs_name;
ca42fa70
BD
391 if (xfsquotactl(XFS_QUOTAOFF, dir, type, 0, (void *)&qflags) < 0) {
392 if (errno == EEXIST)
393 fprintf(stderr,
394 _("Quota enforcement already disabled.\n"));
395 else if (errno == EINVAL || errno == ENOSYS)
396 fprintf(stderr,
397 _("Can't disable enforcement when quota off.\n"));
398 else
399 perror("XFS_QUOTAOFF");
400 }
5aead01d
NS
401 else if (flags & VERBOSE_FLAG)
402 state_quotafile_mount(stdout, type, mount, flags);
403}
404
405static void
406quotaoff(
407 char *dir,
408 uint type,
409 uint qflags,
410 uint flags)
411{
412 fs_path_t *mount;
5aead01d
NS
413
414 mount = fs_table_lookup(dir, FS_MOUNT_POINT);
415 if (!mount) {
e3210fd8 416 exitcode = 1;
5aead01d
NS
417 fprintf(stderr, "%s: unknown mount point %s\n", progname, dir);
418 return;
419 }
420 dir = mount->fs_name;
ca42fa70
BD
421 if (xfsquotactl(XFS_QUOTAOFF, dir, type, 0, (void *)&qflags) < 0) {
422 if (errno == EEXIST || errno == ENOSYS)
423 fprintf(stderr, _("Quota already off.\n"));
424 else
425 perror("XFS_QUOTAOFF");
426 }
5aead01d
NS
427 else if (flags & VERBOSE_FLAG)
428 state_quotafile_mount(stdout, type, mount, flags);
429}
430
79ac1ae4
DD
431static int
432remove_qtype_extents(
433 char *dir,
434 uint type)
435{
436 int error = 0;
437
438 if ((error = xfsquotactl(XFS_QUOTARM, dir, type, 0, (void *)&type)) < 0)
439 perror("XFS_QUOTARM");
440 return error;
441}
442
5aead01d
NS
443static void
444remove_extents(
445 char *dir,
446 uint type,
5aead01d
NS
447 uint flags)
448{
449 fs_path_t *mount;
5aead01d
NS
450
451 mount = fs_table_lookup(dir, FS_MOUNT_POINT);
452 if (!mount) {
e3210fd8 453 exitcode = 1;
5aead01d
NS
454 fprintf(stderr, "%s: unknown mount point %s\n", progname, dir);
455 return;
456 }
457 dir = mount->fs_name;
79ac1ae4 458 if (type & XFS_USER_QUOTA) {
f8149110 459 if (remove_qtype_extents(dir, XFS_USER_QUOTA) < 0)
79ac1ae4
DD
460 return;
461 }
462 if (type & XFS_GROUP_QUOTA) {
f8149110 463 if (remove_qtype_extents(dir, XFS_GROUP_QUOTA) < 0)
79ac1ae4
DD
464 return;
465 } else if (type & XFS_PROJ_QUOTA) {
f8149110 466 if (remove_qtype_extents(dir, XFS_PROJ_QUOTA) < 0)
79ac1ae4
DD
467 return;
468 }
469 if (flags & VERBOSE_FLAG)
5aead01d
NS
470 state_quotafile_mount(stdout, type, mount, flags);
471}
472
473static int
474enable_f(
475 int argc,
476 char **argv)
477{
478 int c, flags = 0, qflags = 0, type = 0;
479
480 while ((c = getopt(argc, argv, "gpuv")) != EOF) {
481 switch (c) {
482 case 'g':
483 type |= XFS_GROUP_QUOTA;
484 qflags |= XFS_QUOTA_GDQ_ACCT | XFS_QUOTA_GDQ_ENFD;
485 break;
486 case 'p':
487 type |= XFS_PROJ_QUOTA;
488 qflags |= XFS_QUOTA_PDQ_ACCT | XFS_QUOTA_PDQ_ENFD;
489 break;
490 case 'u':
491 type |= XFS_USER_QUOTA;
492 qflags |= XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_UDQ_ENFD;
493 break;
494 case 'v':
495 flags |= VERBOSE_FLAG;
496 break;
497 default:
498 return command_usage(&enable_cmd);
499 }
500 }
501
502 if (argc != optind)
503 return command_usage(&enable_cmd);
504
79ac1ae4 505 if (!type) {
5aead01d
NS
506 type |= XFS_USER_QUOTA;
507 qflags |= XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_UDQ_ENFD;
508 }
509
fa13a00f
NS
510 if (fs_path->fs_flags & FS_MOUNT_POINT)
511 enable_enforcement(fs_path->fs_dir, type, qflags, flags);
5aead01d
NS
512 return 0;
513}
514
515static int
516disable_f(
517 int argc,
518 char **argv)
519{
520 int c, flags = 0, qflags = 0, type = 0;
521
522 while ((c = getopt(argc, argv, "gpuv")) != EOF) {
523 switch (c) {
524 case 'g':
525 type |= XFS_GROUP_QUOTA;
79ac1ae4 526 qflags |= XFS_QUOTA_GDQ_ENFD;
5aead01d
NS
527 break;
528 case 'p':
529 type |= XFS_PROJ_QUOTA;
79ac1ae4 530 qflags |= XFS_QUOTA_PDQ_ENFD;
5aead01d
NS
531 break;
532 case 'u':
533 type |= XFS_USER_QUOTA;
79ac1ae4 534 qflags |= XFS_QUOTA_UDQ_ENFD;
5aead01d
NS
535 break;
536 case 'v':
537 flags |= VERBOSE_FLAG;
538 break;
539 default:
540 return command_usage(&disable_cmd);
541 }
542 }
543
544 if (argc != optind)
545 return command_usage(&disable_cmd);
546
79ac1ae4 547 if (!type) {
5aead01d 548 type |= XFS_USER_QUOTA;
79ac1ae4 549 qflags |= XFS_QUOTA_UDQ_ENFD;
5aead01d
NS
550 }
551
fa13a00f
NS
552 if (fs_path->fs_flags & FS_MOUNT_POINT)
553 disable_enforcement(fs_path->fs_dir, type, qflags, flags);
5aead01d
NS
554 return 0;
555}
556
557static int
558off_f(
559 int argc,
560 char **argv)
561{
562 int c, flags = 0, qflags = 0, type = 0;
563
564 while ((c = getopt(argc, argv, "gpuv")) != EOF) {
565 switch (c) {
566 case 'g':
567 type |= XFS_GROUP_QUOTA;
568 qflags |= XFS_QUOTA_GDQ_ACCT | XFS_QUOTA_GDQ_ENFD;
569 break;
570 case 'p':
571 type |= XFS_PROJ_QUOTA;
572 qflags |= XFS_QUOTA_PDQ_ACCT | XFS_QUOTA_PDQ_ENFD;
573 break;
574 case 'u':
575 type |= XFS_USER_QUOTA;
576 qflags |= XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_UDQ_ENFD;
577 break;
578 case 'v':
579 flags |= VERBOSE_FLAG;
580 break;
581 default:
582 return command_usage(&off_cmd);
583 }
584 }
585
586 if (argc != optind)
587 return command_usage(&off_cmd);
588
79ac1ae4 589 if (!type) {
5aead01d
NS
590 type |= XFS_USER_QUOTA;
591 qflags |= XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_UDQ_ENFD;
592 }
593
fa13a00f
NS
594 if (fs_path->fs_flags & FS_MOUNT_POINT)
595 quotaoff(fs_path->fs_dir, type, qflags, flags);
5aead01d
NS
596 return 0;
597}
598
599static int
600remove_f(
601 int argc,
602 char **argv)
603{
79ac1ae4 604 int c, flags = 0, type = 0;
5aead01d
NS
605
606 while ((c = getopt(argc, argv, "gpuv")) != EOF) {
607 switch (c) {
608 case 'g':
609 type |= XFS_GROUP_QUOTA;
5aead01d
NS
610 break;
611 case 'p':
612 type |= XFS_PROJ_QUOTA;
5aead01d
NS
613 break;
614 case 'u':
615 type |= XFS_USER_QUOTA;
5aead01d
NS
616 break;
617 case 'v':
618 flags |= VERBOSE_FLAG;
619 break;
620 default:
621 return command_usage(&remove_cmd);
622 }
623 }
624
625 if (argc != optind)
626 return command_usage(&remove_cmd);
627
79ac1ae4 628 if (!type) {
5aead01d 629 type |= XFS_USER_QUOTA;
5aead01d
NS
630 }
631
fa13a00f 632 if (fs_path->fs_flags & FS_MOUNT_POINT)
79ac1ae4 633 remove_extents(fs_path->fs_dir, type, flags);
5aead01d
NS
634 return 0;
635}
636
637void
638state_init(void)
639{
ad765595 640 off_cmd.name = "off";
5aead01d
NS
641 off_cmd.cfunc = off_f;
642 off_cmd.argmin = 0;
643 off_cmd.argmax = -1;
644 off_cmd.args = _("[-gpu] [-v]");
645 off_cmd.oneline = _("permanently switch quota off for a path");
646 off_cmd.help = off_help;
647
ad765595 648 state_cmd.name = "state";
5aead01d
NS
649 state_cmd.cfunc = state_f;
650 state_cmd.argmin = 0;
651 state_cmd.argmax = -1;
62790d19 652 state_cmd.args = _("[-gpu] [-a] [-v] [-f file]");
5aead01d
NS
653 state_cmd.oneline = _("get overall quota state information");
654 state_cmd.help = state_help;
29647c8d 655 state_cmd.flags = CMD_FLAG_FOREIGN_OK;
5aead01d 656
ad765595 657 enable_cmd.name = "enable";
5aead01d
NS
658 enable_cmd.cfunc = enable_f;
659 enable_cmd.argmin = 0;
660 enable_cmd.argmax = -1;
661 enable_cmd.args = _("[-gpu] [-v]");
662 enable_cmd.oneline = _("enable quota enforcement");
663 enable_cmd.help = enable_help;
664
ad765595 665 disable_cmd.name = "disable";
5aead01d
NS
666 disable_cmd.cfunc = disable_f;
667 disable_cmd.argmin = 0;
668 disable_cmd.argmax = -1;
669 disable_cmd.args = _("[-gpu] [-v]");
670 disable_cmd.oneline = _("disable quota enforcement");
671 disable_cmd.help = disable_help;
672
ad765595 673 remove_cmd.name = "remove";
5aead01d
NS
674 remove_cmd.cfunc = remove_f;
675 remove_cmd.argmin = 0;
676 remove_cmd.argmax = -1;
677 remove_cmd.args = _("[-gpu] [-v]");
678 remove_cmd.oneline = _("remove quota extents from a filesystem");
679 remove_cmd.help = remove_help;
680
681 if (expert) {
682 add_command(&off_cmd);
683 add_command(&state_cmd);
684 add_command(&enable_cmd);
685 add_command(&disable_cmd);
686 add_command(&remove_cmd);
687 }
688}