]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - quota/state.c
2 * Copyright (c) 2005 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 static cmdinfo_t off_cmd
;
24 static cmdinfo_t state_cmd
;
25 static cmdinfo_t enable_cmd
;
26 static cmdinfo_t disable_cmd
;
27 static cmdinfo_t remove_cmd
;
34 " turn filesystem quota off, both accounting and enforcement\n"
37 " 'off -uv' (switch off user quota on the current filesystem)\n"
38 " This command is the equivalent of the traditional quotaoff command,\n"
39 " which disables quota completely on a mounted filesystem.\n"
40 " Note that there is no 'on' command - for XFS filesystems (with the\n"
41 " exception of the root filesystem on IRIX) quota can only be enabled\n"
42 " at mount time, through the use of one of the quota mount options.\n"
44 " The state command is useful for displaying the current state. Using\n"
45 " the -v (verbose) option with the 'off' command will display the quota\n"
46 " state for the affected filesystem once the operation is complete.\n"
47 " The affected quota type is -g (groups), -p (projects) or -u (users)\n"
48 " and defaults to user quota (multiple types can be specified).\n"
57 " query the state of quota on the current filesystem\n"
59 " This is a verbose status command, reporting whether or not accounting\n"
60 " and/or enforcement are enabled for a filesystem, which inodes are in\n"
61 " use as the quota state inodes, and how many extents and blocks are\n"
62 " presently being used to hold that information.\n"
63 " The quota type is specified via -g (groups), -p (projects) or -u (users)\n"
64 " and defaults to user quota (multiple types can be specified).\n"
73 " enable quota enforcement on a filesystem\n"
75 " If a filesystem is mounted and has quota accounting enabled, but not\n"
76 " quota enforcement, enforcement can be enabled with this command.\n"
77 " With the -v (verbose) option, the status of the filesystem will be\n"
78 " reported after the operation is complete.\n"
79 " The affected quota type is -g (groups), -p (projects) or -u (users)\n"
80 " and defaults to user quota (multiple types can be specified).\n"
89 " disable quota enforcement on a filesystem\n"
91 " If a filesystem is mounted and is currently enforcing quota, this\n"
92 " provides a mechanism to switch off the enforcement, but continue to\n"
93 " perform used space (and used inodes) accounting.\n"
94 " The affected quota type is -g (groups), -p (projects) or -u (users).\n"
103 " remove any space being used by the quota subsystem\n"
105 " Once quota has been switched 'off' on a filesystem, the space that\n"
106 " was allocated to holding quota metadata can be freed via this command.\n"
107 " The affected quota type is -g (groups), -p (projects) or -u (users)\n"
108 " and defaults to user quota (multiple types can be specified).\n"
115 struct fs_path
*mount
,
117 struct fs_qfilestatv
*qfs
,
121 fprintf(fp
, _("%s quota state on %s (%s)\n"), type_to_string(type
),
122 mount
->fs_dir
, mount
->fs_name
);
123 fprintf(fp
, _(" Accounting: %s\n"), accounting
? _("ON") : _("OFF"));
124 fprintf(fp
, _(" Enforcement: %s\n"), enforcing
? _("ON") : _("OFF"));
125 if (qfs
->qfs_ino
!= (__u64
) -1)
126 fprintf(fp
, _(" Inode: #%llu (%llu blocks, %lu extents)\n"),
127 (unsigned long long)qfs
->qfs_ino
,
128 (unsigned long long)qfs
->qfs_nblks
,
129 (unsigned long)qfs
->qfs_nextents
);
131 fprintf(fp
, _(" Inode: N/A\n"));
138 __uint32_t timelimit
)
140 fprintf(fp
, _("%s grace time: %s\n"),
141 form_to_string(form
),
142 time_to_string(timelimit
, VERBOSE_FLAG
| ABSOLUTE_FLAG
));
146 * fs_quota_stat holds a subset of fs_quota_statv; this copies
147 * the smaller into the larger, leaving any not-present fields
148 * empty. This is so the same reporting function can be used
149 * for both XFS_GETQSTAT and XFS_GETQSTATV results.
153 struct fs_quota_stat
*s
,
154 struct fs_quota_statv
*sv
)
156 memset(sv
, 0, sizeof(struct fs_quota_statv
));
158 /* shared information */
159 sv
->qs_version
= s
->qs_version
;
160 sv
->qs_flags
= s
->qs_flags
;
161 sv
->qs_incoredqs
= s
->qs_incoredqs
;
162 sv
->qs_btimelimit
= s
->qs_btimelimit
;
163 sv
->qs_itimelimit
= s
->qs_itimelimit
;
164 sv
->qs_rtbtimelimit
= s
->qs_rtbtimelimit
;
165 sv
->qs_bwarnlimit
= s
->qs_bwarnlimit
;
166 sv
->qs_iwarnlimit
= s
->qs_iwarnlimit
;
168 /* Always room for uquota */
169 sv
->qs_uquota
.qfs_ino
= s
->qs_uquota
.qfs_ino
;
170 sv
->qs_uquota
.qfs_nblks
= s
->qs_uquota
.qfs_nblks
;
171 sv
->qs_uquota
.qfs_nextents
= s
->qs_uquota
.qfs_nextents
;
174 * If we are here, XFS_GETQSTATV failed and XFS_GETQSTAT passed;
175 * that is a very strong hint that we're on a kernel which predates
176 * the on-disk pquota inode; both were added in v3.12. So, we do
177 * some tricksy determination here.
178 * gs_gquota may hold either group quota inode info, or project
179 * quota if that is used instead; which one it actually holds depends
180 * on the quota flags. (If neither is set, neither is used)
182 if (s
->qs_flags
& XFS_QUOTA_GDQ_ACCT
) {
183 /* gs_gquota holds group quota info */
184 sv
->qs_gquota
.qfs_ino
= s
->qs_gquota
.qfs_ino
;
185 sv
->qs_gquota
.qfs_nblks
= s
->qs_gquota
.qfs_nblks
;
186 sv
->qs_gquota
.qfs_nextents
= s
->qs_gquota
.qfs_nextents
;
187 } else if (s
->qs_flags
& XFS_QUOTA_PDQ_ACCT
) {
188 /* gs_gquota actually holds project quota info */
189 sv
->qs_pquota
.qfs_ino
= s
->qs_gquota
.qfs_ino
;
190 sv
->qs_pquota
.qfs_nblks
= s
->qs_gquota
.qfs_nblks
;
191 sv
->qs_pquota
.qfs_nextents
= s
->qs_gquota
.qfs_nextents
;
196 state_quotafile_mount(
199 struct fs_path
*mount
,
202 struct fs_quota_stat s
;
203 struct fs_quota_statv sv
;
204 char *dev
= mount
->fs_name
;
206 sv
.qs_version
= FS_QSTATV_VERSION1
;
208 if (xfsquotactl(XFS_GETQSTATV
, dev
, type
, 0, (void *)&sv
) < 0) {
209 if (xfsquotactl(XFS_GETQSTAT
, dev
, type
, 0, (void *)&s
) < 0) {
210 if (flags
& VERBOSE_FLAG
)
212 _("%s quota are not enabled on %s\n"),
213 type_to_string(type
), dev
);
216 state_stat_to_statv(&s
, &sv
);
219 if (type
& XFS_USER_QUOTA
)
220 state_qfilestat(fp
, mount
, XFS_USER_QUOTA
, &sv
.qs_uquota
,
221 sv
.qs_flags
& XFS_QUOTA_UDQ_ACCT
,
222 sv
.qs_flags
& XFS_QUOTA_UDQ_ENFD
);
223 if (type
& XFS_GROUP_QUOTA
)
224 state_qfilestat(fp
, mount
, XFS_GROUP_QUOTA
, &sv
.qs_gquota
,
225 sv
.qs_flags
& XFS_QUOTA_GDQ_ACCT
,
226 sv
.qs_flags
& XFS_QUOTA_GDQ_ENFD
);
227 if (type
& XFS_PROJ_QUOTA
)
228 state_qfilestat(fp
, mount
, XFS_PROJ_QUOTA
, &sv
.qs_pquota
,
229 sv
.qs_flags
& XFS_QUOTA_PDQ_ACCT
,
230 sv
.qs_flags
& XFS_QUOTA_PDQ_ENFD
);
232 state_timelimit(fp
, XFS_BLOCK_QUOTA
, sv
.qs_btimelimit
);
233 state_timelimit(fp
, XFS_INODE_QUOTA
, sv
.qs_itimelimit
);
234 state_timelimit(fp
, XFS_RTBLOCK_QUOTA
, sv
.qs_rtbtimelimit
);
247 fs_cursor_initialise(dir
, FS_MOUNT_POINT
, &cursor
);
248 while ((mount
= fs_cursor_next_entry(&cursor
)))
249 state_quotafile_mount(fp
, type
, mount
, flags
);
259 int c
, flags
= 0, type
= 0;
261 while ((c
= getopt(argc
, argv
, "af:gpuv")) != EOF
) {
264 flags
|= ALL_MOUNTS_FLAG
;
270 type
|= XFS_GROUP_QUOTA
;
273 type
|= XFS_PROJ_QUOTA
;
276 type
|= XFS_USER_QUOTA
;
279 flags
|= VERBOSE_FLAG
;
282 return command_usage(&state_cmd
);
287 return command_usage(&state_cmd
);
289 if ((fp
= fopen_write_secure(fname
)) == NULL
)
293 type
= XFS_USER_QUOTA
| XFS_GROUP_QUOTA
| XFS_PROJ_QUOTA
;
295 if (flags
& ALL_MOUNTS_FLAG
)
296 state_quotafile(fp
, type
, NULL
, flags
);
297 else if (fs_path
&& fs_path
->fs_flags
& FS_MOUNT_POINT
)
298 state_quotafile(fp
, type
, fs_path
->fs_dir
, flags
);
314 mount
= fs_table_lookup(dir
, FS_MOUNT_POINT
);
317 fprintf(stderr
, "%s: unknown mount point %s\n", progname
, dir
);
320 dir
= mount
->fs_name
;
321 if (xfsquotactl(XFS_QUOTAON
, dir
, type
, 0, (void *)&qflags
) < 0)
322 perror("XFS_QUOTAON");
323 else if (flags
& VERBOSE_FLAG
)
324 state_quotafile_mount(stdout
, type
, mount
, flags
);
336 mount
= fs_table_lookup(dir
, FS_MOUNT_POINT
);
339 fprintf(stderr
, "%s: unknown mount point %s\n", progname
, dir
);
342 dir
= mount
->fs_name
;
343 if (xfsquotactl(XFS_QUOTAOFF
, dir
, type
, 0, (void *)&qflags
) < 0)
344 perror("XFS_QUOTAOFF");
345 else if (flags
& VERBOSE_FLAG
)
346 state_quotafile_mount(stdout
, type
, mount
, flags
);
358 mount
= fs_table_lookup(dir
, FS_MOUNT_POINT
);
361 fprintf(stderr
, "%s: unknown mount point %s\n", progname
, dir
);
364 dir
= mount
->fs_name
;
365 if (xfsquotactl(XFS_QUOTAOFF
, dir
, type
, 0, (void *)&qflags
) < 0)
366 perror("XFS_QUOTAOFF");
367 else if (flags
& VERBOSE_FLAG
)
368 state_quotafile_mount(stdout
, type
, mount
, flags
);
372 remove_qtype_extents(
378 if ((error
= xfsquotactl(XFS_QUOTARM
, dir
, type
, 0, (void *)&type
)) < 0)
379 perror("XFS_QUOTARM");
391 mount
= fs_table_lookup(dir
, FS_MOUNT_POINT
);
394 fprintf(stderr
, "%s: unknown mount point %s\n", progname
, dir
);
397 dir
= mount
->fs_name
;
398 if (type
& XFS_USER_QUOTA
) {
399 if (remove_qtype_extents(dir
, XFS_USER_QUOTA
) < 0)
402 if (type
& XFS_GROUP_QUOTA
) {
403 if (remove_qtype_extents(dir
, XFS_GROUP_QUOTA
) < 0)
405 } else if (type
& XFS_PROJ_QUOTA
) {
406 if (remove_qtype_extents(dir
, XFS_PROJ_QUOTA
) < 0)
409 if (flags
& VERBOSE_FLAG
)
410 state_quotafile_mount(stdout
, type
, mount
, flags
);
418 int c
, flags
= 0, qflags
= 0, type
= 0;
420 while ((c
= getopt(argc
, argv
, "gpuv")) != EOF
) {
423 type
|= XFS_GROUP_QUOTA
;
424 qflags
|= XFS_QUOTA_GDQ_ACCT
| XFS_QUOTA_GDQ_ENFD
;
427 type
|= XFS_PROJ_QUOTA
;
428 qflags
|= XFS_QUOTA_PDQ_ACCT
| XFS_QUOTA_PDQ_ENFD
;
431 type
|= XFS_USER_QUOTA
;
432 qflags
|= XFS_QUOTA_UDQ_ACCT
| XFS_QUOTA_UDQ_ENFD
;
435 flags
|= VERBOSE_FLAG
;
438 return command_usage(&enable_cmd
);
443 return command_usage(&enable_cmd
);
446 type
|= XFS_USER_QUOTA
;
447 qflags
|= XFS_QUOTA_UDQ_ACCT
| XFS_QUOTA_UDQ_ENFD
;
450 if (fs_path
->fs_flags
& FS_MOUNT_POINT
)
451 enable_enforcement(fs_path
->fs_dir
, type
, qflags
, flags
);
460 int c
, flags
= 0, qflags
= 0, type
= 0;
462 while ((c
= getopt(argc
, argv
, "gpuv")) != EOF
) {
465 type
|= XFS_GROUP_QUOTA
;
466 qflags
|= XFS_QUOTA_GDQ_ENFD
;
469 type
|= XFS_PROJ_QUOTA
;
470 qflags
|= XFS_QUOTA_PDQ_ENFD
;
473 type
|= XFS_USER_QUOTA
;
474 qflags
|= XFS_QUOTA_UDQ_ENFD
;
477 flags
|= VERBOSE_FLAG
;
480 return command_usage(&disable_cmd
);
485 return command_usage(&disable_cmd
);
488 type
|= XFS_USER_QUOTA
;
489 qflags
|= XFS_QUOTA_UDQ_ENFD
;
492 if (fs_path
->fs_flags
& FS_MOUNT_POINT
)
493 disable_enforcement(fs_path
->fs_dir
, type
, qflags
, flags
);
502 int c
, flags
= 0, qflags
= 0, type
= 0;
504 while ((c
= getopt(argc
, argv
, "gpuv")) != EOF
) {
507 type
|= XFS_GROUP_QUOTA
;
508 qflags
|= XFS_QUOTA_GDQ_ACCT
| XFS_QUOTA_GDQ_ENFD
;
511 type
|= XFS_PROJ_QUOTA
;
512 qflags
|= XFS_QUOTA_PDQ_ACCT
| XFS_QUOTA_PDQ_ENFD
;
515 type
|= XFS_USER_QUOTA
;
516 qflags
|= XFS_QUOTA_UDQ_ACCT
| XFS_QUOTA_UDQ_ENFD
;
519 flags
|= VERBOSE_FLAG
;
522 return command_usage(&off_cmd
);
527 return command_usage(&off_cmd
);
530 type
|= XFS_USER_QUOTA
;
531 qflags
|= XFS_QUOTA_UDQ_ACCT
| XFS_QUOTA_UDQ_ENFD
;
534 if (fs_path
->fs_flags
& FS_MOUNT_POINT
)
535 quotaoff(fs_path
->fs_dir
, type
, qflags
, flags
);
544 int c
, flags
= 0, type
= 0;
546 while ((c
= getopt(argc
, argv
, "gpuv")) != EOF
) {
549 type
|= XFS_GROUP_QUOTA
;
552 type
|= XFS_PROJ_QUOTA
;
555 type
|= XFS_USER_QUOTA
;
558 flags
|= VERBOSE_FLAG
;
561 return command_usage(&remove_cmd
);
566 return command_usage(&remove_cmd
);
569 type
|= XFS_USER_QUOTA
;
572 if (fs_path
->fs_flags
& FS_MOUNT_POINT
)
573 remove_extents(fs_path
->fs_dir
, type
, flags
);
580 off_cmd
.name
= "off";
581 off_cmd
.cfunc
= off_f
;
584 off_cmd
.args
= _("[-gpu] [-v]");
585 off_cmd
.oneline
= _("permanently switch quota off for a path");
586 off_cmd
.help
= off_help
;
588 state_cmd
.name
= "state";
589 state_cmd
.cfunc
= state_f
;
590 state_cmd
.argmin
= 0;
591 state_cmd
.argmax
= -1;
592 state_cmd
.args
= _("[-gpu] [-a] [-v] [-f file]");
593 state_cmd
.oneline
= _("get overall quota state information");
594 state_cmd
.help
= state_help
;
596 enable_cmd
.name
= "enable";
597 enable_cmd
.cfunc
= enable_f
;
598 enable_cmd
.argmin
= 0;
599 enable_cmd
.argmax
= -1;
600 enable_cmd
.args
= _("[-gpu] [-v]");
601 enable_cmd
.oneline
= _("enable quota enforcement");
602 enable_cmd
.help
= enable_help
;
604 disable_cmd
.name
= "disable";
605 disable_cmd
.cfunc
= disable_f
;
606 disable_cmd
.argmin
= 0;
607 disable_cmd
.argmax
= -1;
608 disable_cmd
.args
= _("[-gpu] [-v]");
609 disable_cmd
.oneline
= _("disable quota enforcement");
610 disable_cmd
.help
= disable_help
;
612 remove_cmd
.name
= "remove";
613 remove_cmd
.cfunc
= remove_f
;
614 remove_cmd
.argmin
= 0;
615 remove_cmd
.argmax
= -1;
616 remove_cmd
.args
= _("[-gpu] [-v]");
617 remove_cmd
.oneline
= _("remove quota extents from a filesystem");
618 remove_cmd
.help
= remove_help
;
621 add_command(&off_cmd
);
622 add_command(&state_cmd
);
623 add_command(&enable_cmd
);
624 add_command(&disable_cmd
);
625 add_command(&remove_cmd
);