diff options
author | jkar8572 <jkar8572> | 2002-11-21 18:37:57 +0000 |
---|---|---|
committer | jkar8572 <jkar8572> | 2002-11-21 18:37:57 +0000 |
commit | ad868a7b3e1c2cdaeddcf93b8ccf55434b0d1c21 (patch) | |
tree | e4df55fd3aa0496bee0fa3f9f1265eeae38cac2c | |
parent | 9bdd6236879ea379758f82ad5cec7033f0a751ac (diff) | |
download | linuxquota-ad868a7b3e1c2cdaeddcf93b8ccf55434b0d1c21.tar.gz |
Updated edquota(8) and setquota(8) to allow setting of individual grace time (Jan Kara)
-rw-r--r-- | Changelog | 1 | ||||
-rw-r--r-- | edquota.8 | 23 | ||||
-rw-r--r-- | edquota.c | 39 | ||||
-rw-r--r-- | quotaio.h | 3 | ||||
-rw-r--r-- | quotaio_v1.c | 6 | ||||
-rw-r--r-- | quotaio_v2.c | 4 | ||||
-rw-r--r-- | quotaops.c | 163 | ||||
-rw-r--r-- | quotaops.h | 4 | ||||
-rw-r--r-- | quotasys.c | 18 | ||||
-rw-r--r-- | quotasys.h | 3 | ||||
-rw-r--r-- | setquota.8 | 31 | ||||
-rw-r--r-- | setquota.c | 59 |
12 files changed, 299 insertions, 55 deletions
@@ -1,4 +1,5 @@ Changes in quota-tools from 3.07 to 3.08 +* Updated edquota(8) and setquota(8) to allow setting of individual grace time (Jan Kara) * Fixed bug in convertquota(8) when quota was turned on during converting (Jan Kara) * Add support for XFS filesystems without root special casing (Christoph Hellwig) * XFS documentation updates (Nathan Scott) @@ -32,6 +32,21 @@ edquota \- edit user quotas .I filesystem ] .B \-t +.LP +.B edquota +[ +.BR \-u \ | +.B \-g +] [ +.B \-F +.I format-name +] [ +.B \-f +.I filesystem +] +.B \-T +.IR username \ | +.IR groupname .\|.\|. .SH DESCRIPTION .IX "edquota command" "" "\fLedquota\fP \(em edit user quotas" .IX edit "user quotas \(em \fLedquota\fP" @@ -109,9 +124,15 @@ Edit the soft time limits for each filesystem. In old quota format if the time limits are zero, the default time limits in .B <linux/quota.h> are used. In new quota format time limits must be specified (there is no default -value set in kernel). Time units of seconds, minutes, hours, days, weeks, and months +value set in kernel). Time units of 'seconds', 'minutes', 'hours', 'days', 'weeks', and 'months' are understood. Time limits are printed in the greatest possible time unit such that the value is greater than or equal to one. +.TP +.B \-T +Edit time for the user/group when softlimit is enforced. Possible values +are 'unset' or number and unit. Units are same as used in +.B \-t +option. .SH FILES .PD 0 .TP 20 @@ -34,7 +34,7 @@ #ident "$Copyright: (c) 1980, 1990 Regents of the University of California. $" #ident "$Copyright: All rights reserved. $" -#ident "$Id: edquota.c,v 1.9 2002/07/23 15:59:27 jkar8572 Exp $" +#ident "$Id: edquota.c,v 1.10 2002/11/21 18:37:58 jkar8572 Exp $" /* * Disk quota editor. @@ -67,12 +67,14 @@ void usage(void) errstr("%s%s%s", _("Usage:\tedquota [-r] [-u] [-F formatname] [-p username] [-f filesystem] username ...\n"), _("\tedquota [-r] -g [-F formatname] [-p groupname] [-f filesystem] groupname ...\n"), - _("\tedquota [-r] [-u|g] [-F formatname] [-f filesystem] -t\n")); + _("\tedquota [-r] [-u|g] [-F formatname] [-f filesystem] -t\n"), + _("\tedquota [-r] [-u|g] [-F formatname] [-f filesystem] -T username|groupname ...\n")); #else errstr("%s%s%s", _("Usage:\tedquota [-u] [-F formatname] [-p username] [-f filesystem] username ...\n"), _("\tedquota -g [-F formatname] [-p groupname] [-f filesystem] groupname ...\n"), - _("\tedquota [-u|g] [-F formatname] [-f filesystem] -t\n")); + _("\tedquota [-u|g] [-F formatname] [-f filesystem] -t\n"), + _("\tedquota [-u|g] [-F formatname] [-f filesystem] -T username|groupname ...\n")); #endif fprintf(stderr, _("Bugs to: %s\n"), MY_EMAIL); exit(1); @@ -84,7 +86,7 @@ int main(int argc, char **argv) long id, protoid; int quotatype, tmpfd, ret; char *protoname = NULL; - int tflag = 0, pflag = 0, rflag = 0, fmt = -1; + int tflag = 0, Tflag = 0, pflag = 0, rflag = 0, fmt = -1; struct quota_handle **handles; char *tmpfil, *tmpdir = NULL; @@ -97,9 +99,9 @@ int main(int argc, char **argv) dirname = NULL; quotatype = USRQUOTA; #if defined(RPC_SETQUOTA) - while ((ret = getopt(argc, argv, "ugrntVp:F:f:")) != -1) { + while ((ret = getopt(argc, argv, "ugrntTVp:F:f:")) != -1) { #else - while ((ret = getopt(argc, argv, "ugtVp:F:f:")) != -1) { + while ((ret = getopt(argc, argv, "ugtTVp:F:f:")) != -1) { #endif switch (ret) { case 'p': @@ -121,6 +123,9 @@ int main(int argc, char **argv) case 't': tflag++; break; + case 'T': + Tflag++; + break; case 'F': if ((fmt = name2fmt(optarg)) == QF_ERROR) /* Error? */ exit(1); @@ -138,7 +143,7 @@ int main(int argc, char **argv) argc -= optind; argv += optind; - if (tflag && argc != 0) + if ((tflag && argc != 0) || (Tflag && argc < 1)) usage(); init_kernel_interface(); @@ -203,6 +208,26 @@ int main(int argc, char **argv) die(1, _("Failed to parse grace times file.\n")); } } + else if (Tflag) { + for (; argc > 0; argc--, argv++) { + id = name2id(*argv, quotatype); + curprivs = getprivs(id, handles, 0); + if (writeindividualtimes(curprivs, tmpfd, *argv, quotatype) < 0) { + errstr(_("Can't write individual grace times to file.\n")); + continue; + } + if (editprivs(tmpfil) < 0) { + errstr(_("Error while editting individual grace times.\n")); + continue; + } + if (readindividualtimes(curprivs, tmpfd) < 0) { + errstr(_("Can't read individual grace times from file.\n")); + continue; + } + putprivs(curprivs, COMMIT_TIMES); + freeprivs(curprivs); + } + } else { for (; argc > 0; argc--, argv++) { id = name2id(*argv, quotatype); @@ -132,7 +132,8 @@ struct dquot { /* Flags for commit function (have effect only when quota in kernel is turned on) */ #define COMMIT_USAGE QIF_USAGE #define COMMIT_LIMITS QIF_LIMITS -#define COMMIT_ALL (COMMIT_USAGE | COMMIT_LIMITS) +#define COMMIT_TIMES QIF_TIMES +#define COMMIT_ALL (COMMIT_USAGE | COMMIT_LIMITS | COMMIT_TIMES) /* Structure of quotafile operations */ struct quotafile_ops { diff --git a/quotaio_v1.c b/quotaio_v1.c index d565e01..40b2ad0 100644 --- a/quotaio_v1.c +++ b/quotaio_v1.c @@ -34,7 +34,7 @@ #ident "$Copyright: (c) 1980, 1990 Regents of the University of California. $" #ident "$Copyright: All rights reserved. $" -#ident "$Id: quotaio_v1.c,v 1.12 2002/03/27 16:21:26 jkar8572 Exp $" +#ident "$Id: quotaio_v1.c,v 1.13 2002/11/21 18:37:58 jkar8572 Exp $" #include <unistd.h> #include <errno.h> @@ -316,6 +316,10 @@ static int v1_commit_dquot(struct dquot *dquot, int flags) cmd = Q_V1_SETUSE; else if (flags == COMMIT_LIMITS) cmd = Q_V1_SETQLIM; + else if (flags & COMMIT_TIMES) { + errno = EINVAL; + return -1; + } else cmd = Q_V1_SETQUOTA; v1_util2kerndqblk(&kdqblk, &dquot->dq_dqb); diff --git a/quotaio_v2.c b/quotaio_v2.c index 9fc7e43..095c39c 100644 --- a/quotaio_v2.c +++ b/quotaio_v2.c @@ -692,6 +692,10 @@ static int v2_commit_dquot(struct dquot *dquot, int flags) cmd = Q_V2_SETUSE; else if (flags == COMMIT_LIMITS) cmd = Q_V2_SETQLIM; + else if (flags & COMMIT_TIMES) { + errno = EINVAL; + return -1; + } else cmd = Q_V2_SETQUOTA; v2_util2kerndqblk(&kdqblk, &dquot->dq_dqb); @@ -34,7 +34,7 @@ #ident "$Copyright: (c) 1980, 1990 Regents of the University of California. $" #ident "$Copyright: All rights reserved. $" -#ident "$Id: quotaops.c,v 1.8 2002/07/23 15:59:27 jkar8572 Exp $" +#ident "$Id: quotaops.c,v 1.9 2002/11/21 18:37:58 jkar8572 Exp $" #include <rpc/rpc.h> #include <sys/types.h> @@ -50,6 +50,7 @@ #include <paths.h> #include <unistd.h> #include <time.h> +#include <ctype.h> #if defined(RPC) #include "rquota.h" @@ -64,27 +65,6 @@ #include "quotaio.h" /* - * Convert ASCII input times to seconds. - */ -static int cvtatos(time_t time, char *units, time_t * seconds) -{ - if (memcmp(units, "second", 6) == 0) - *seconds = time; - else if (memcmp(units, "minute", 6) == 0) - *seconds = time * 60; - else if (memcmp(units, "hour", 4) == 0) - *seconds = time * 60 * 60; - else if (memcmp(units, "day", 3) == 0) - *seconds = time * 24 * 60 * 60; - else { - errstr(_("bad units, specify:\n %s, %s, %s, or %s"), units, - "days", "hours", "minutes", "seconds"); - return -1; - } - return 0; -} - -/* * Set grace time if needed */ void update_grace_times(struct dquot *q) @@ -173,18 +153,20 @@ struct dquot *getprivs(qid_t id, struct quota_handle **handles, int quiet) /* * Store the requested quota information. */ -int putprivs(struct dquot *qlist) +int putprivs(struct dquot *qlist, int flags) { struct dquot *q; + int ret = 0; for (q = qlist; q; q = q->dq_next) { - if (q->dq_h->qh_ops->commit_dquot(q, COMMIT_LIMITS) == -1) { + if (q->dq_h->qh_ops->commit_dquot(q, flags) == -1) { errstr(_("Can't write quota for %u on %s: %s\n"), q->dq_id, q->dq_h->qh_quotadev, strerror(errno)); + ret = -1; continue; } } - return 0; + return ret; } /* @@ -241,8 +223,7 @@ int writeprivs(struct dquot *qlist, int outfd, char *name, int quotatype) type2name(quotatype), name, *type2name(quotatype), name2id(name, quotatype)); fprintf(fd, - _ - (" Filesystem blocks soft hard inodes soft hard\n")); + _(" Filesystem blocks soft hard inodes soft hard\n")); for (q = qlist; q; q = q->dq_next) { fprintf(fd, " %-24s %10Lu %10Lu %10Lu %10Lu %8Lu %8Lu\n", @@ -270,7 +251,7 @@ int writeprivs(struct dquot *qlist, int outfd, char *name, int quotatype) } /* Merge changes on one dev to proper structure in the list */ -static void merge_to_list(struct dquot *qlist, char *dev, u_int64_t blocks, u_int64_t bsoft, +static void merge_limits_to_list(struct dquot *qlist, char *dev, u_int64_t blocks, u_int64_t bsoft, u_int64_t bhard, u_int64_t inodes, u_int64_t isoft, u_int64_t ihard) { struct dquot *q; @@ -331,7 +312,7 @@ int readprivs(struct dquot *qlist, int infd) return -1; } - merge_to_list(qlist, fsp, blocks, bsoft, bhard, inodes, isoft, ihard); + merge_limits_to_list(qlist, fsp, blocks, bsoft, bhard, inodes, isoft, ihard); } #else /* @@ -371,7 +352,7 @@ int readprivs(struct dquot *qlist, int infd) return -1; } - merge_to_list(qlist, fsp, blocks, bsoft, bhard, inodes, isoft, ihard); + merge_limits_to_list(qlist, fsp, blocks, bsoft, bhard, inodes, isoft, ihard); } #endif fclose(fd); @@ -392,6 +373,121 @@ int readprivs(struct dquot *qlist, int infd) return 0; } +/* Merge changes on one dev to proper structure in the list */ +static void merge_times_to_list(struct dquot *qlist, char *dev, time_t btime, time_t itime) +{ + struct dquot *q; + + for (q = qlist; q; q = q->dq_next) { + if (!devcmp_handle(dev, q->dq_h)) + continue; + + q->dq_dqb.dqb_btime = btime; + q->dq_dqb.dqb_itime = itime; + q->dq_flags |= DQ_FOUND; + } +} + +/* + * Write grace times of user to file + */ +int writeindividualtimes(struct dquot *qlist, int outfd, char *name, int quotatype) +{ + struct dquot *q; + FILE *fd; + time_t now; + char btimestr[MAXTIMELEN], itimestr[MAXTIMELEN]; + + ftruncate(outfd, 0); + lseek(outfd, 0, SEEK_SET); + if (!(fd = fdopen(dup(outfd), "w"))) + die(1, _("Can't duplicate descriptor of file to write to: %s\n"), strerror(errno)); + + fprintf(fd, _("Times to enforce softlimit for %s %s (%cid %d):\n"), + type2name(quotatype), name, *type2name(quotatype), name2id(name, quotatype)); + fprintf(fd, _("Time units may be: days, hours, minutes, or seconds\n")); + fprintf(fd, + _(" Filesystem block grace inode grace\n")); + + time(&now); + for (q = qlist; q; q = q->dq_next) { + if (!q->dq_dqb.dqb_btime) + strcpy(btimestr, _("unset")); + else if (q->dq_dqb.dqb_btime <= now) + strcpy(btimestr, _("0seconds")); + else + sprintf(btimestr, "%useconds", (unsigned)(q->dq_dqb.dqb_btime - now)); + if (!q->dq_dqb.dqb_itime) + strcpy(itimestr, _("unset")); + else if (q->dq_dqb.dqb_itime <= now) + strcpy(itimestr, _("0seconds")); + else + sprintf(itimestr, _("%useconds"), (unsigned)(q->dq_dqb.dqb_itime - now)); + + fprintf(fd, " %-24s %22s %22s\n", q->dq_h->qh_quotadev, btimestr, itimestr); + } + fclose(fd); + return 0; +} + +/* + * Read list of grace times for a user and convert it + */ +int readindividualtimes(struct dquot *qlist, int infd) +{ + FILE *fd; + int cnt, btime, itime; + char line[BUFSIZ], fsp[BUFSIZ], btimestr[BUFSIZ], itimestr[BUFSIZ]; + char iunits[BUFSIZ], bunits[BUFSIZ]; + time_t now, bseconds, iseconds; + + lseek(infd, 0, SEEK_SET); + if (!(fd = fdopen(dup(infd), "r"))) + die(1, _("Can't duplicate descriptor of temp file: %s\n"), strerror(errno)); + + /* + * Discard title lines, then read lines to process. + */ + fgets(line, sizeof(line), fd); + fgets(line, sizeof(line), fd); + fgets(line, sizeof(line), fd); + + time(&now); + while (fgets(line, sizeof(line), fd)) { + cnt = sscanf(line, "%s %s %s", fsp, btimestr, itimestr); + if (cnt != 3) { +format_err: + errstr(_("bad format:\n%s\n"), line); + return -1; + } + if (!strcmp(btimestr, _("unset"))) + bseconds = 0; + else { + if (sscanf(btimestr, "%d%s", &btime, bunits) != 2) + goto format_err; + if (str2timeunits(btime, bunits, &bseconds) < 0) { +units_err: + errstr(_("Bad time units. Units are 'second', 'minute', 'hour' and 'day'.\n")); + return -1; + } + bseconds += now; + } + if (!strcmp(itimestr, _("unset"))) + iseconds = 0; + else { + if (sscanf(itimestr, "%d%s", &itime, iunits) != 2) + goto format_err; + if (str2timeunits(itime, iunits, &iseconds) < 0) + goto units_err; + iseconds += now; + } + merge_times_to_list(qlist, fsp, bseconds, iseconds); + } + fclose(fd); + + return 0; +} + /* * Convert a dquot list to an ASCII file of grace times. */ @@ -505,10 +601,11 @@ int readtimes(struct quota_handle **handles, int infd) return -1; } #endif - if (cvtatos(btime, bunits, &bseconds) < 0) - return -1; - if (cvtatos(itime, iunits, &iseconds) < 0) + if (str2timeunits(btime, bunits, &bseconds) < 0 || + str2timeunits(itime, iunits, &iseconds) < 0) { + errstr(_("Bad time units. Units are 'second', 'minute', 'hour' and 'day'.\n")); return -1; + } for (i = 0; handles[i]; i++) { if (!devcmp_handle(fsp, handles[i])) continue; @@ -4,10 +4,12 @@ #include "quotaio.h" struct dquot *getprivs(qid_t id, struct quota_handle ** handles, int quiet); -int putprivs(struct dquot * qlist); +int putprivs(struct dquot * qlist, int flags); int editprivs(char *tmpfile); int writeprivs(struct dquot * qlist, int outfd, char *name, int quotatype); int readprivs(struct dquot * qlist, int infd); +int writeindividualtimes(struct dquot * qlist, int outfd, char *name, int quotatype); +int readindividualtimes(struct dquot * qlist, int infd); int writetimes(struct quota_handle ** handles, int outfd); int readtimes(struct quota_handle ** handles, int infd); void freeprivs(struct dquot * qlist); @@ -285,6 +285,24 @@ void time2str(time_t seconds, char *buf, int flags) } /* + * Convert number with unit to time in seconds + */ +int str2timeunits(time_t num, char *unit, time_t *res) +{ + if (memcmp(unit, "second", 6) == 0) + *res = num; + else if (memcmp(unit, "minute", 6) == 0) + *res = num * 60; + else if (memcmp(unit, "hour", 4) == 0) + *res = num * 60 * 60; + else if (memcmp(unit, "day", 3) == 0) + *res = num * 24 * 60 * 60; + else + return -1; + return 0; +} + +/* * Convert number in quota blocks to some nice short form for printing */ void space2str(qsize_t space, char *buf, int format) @@ -82,6 +82,9 @@ void difftime2str(time_t, char *); /* Convert time to printable form */ void time2str(time_t, char *, int); +/* Convert number and units to time in seconds */ +int str2timeunits(time_t, char *, time_t *); + /* Convert number in quota blocks to short printable form */ void space2str(qsize_t, char *, int); @@ -2,7 +2,7 @@ .SH NAME setquota \- set disk quotas .SH SYNOPSIS -.B /usr/sbin/setquota +.B setquota [ .B \-r ] @@ -24,7 +24,7 @@ setquota \- set disk quotas | .I filesystem... .LP -.B /usr/sbin/setquota +.B setquota [ .B \-r ] @@ -46,7 +46,7 @@ setquota \- set disk quotas | .I filesystem... .LP -.B /usr/sbin/setquota +.B setquota .B \-t [ .B \-u @@ -62,6 +62,24 @@ setquota \- set disk quotas .B \-a | .I filesystem... +.LP +.B setquota +.B \-T +[ +.B \-u +| +.B \-g +] +[ +.B \-F +.I quotaformat +] +.I name +.I block-grace +.I inode-grace +.B \-a +| +.I filesystem... .SH DESCRIPTION .IX "setquota command" "" "\fLsetquota\fP \(em set disk quotas" .IX set "disk quotas \(em \fLsetquota\fP" @@ -107,6 +125,13 @@ and .B inode-grace are specified in seconds. .TP +.B -T +Alter times for individual user/group when softlimit is enforced. Times +.B block-grace +and +.B inode-grace +are specified in seconds or can be string 'unset'. +.TP .B -a Go through all filesystems with quota in .B /etc/mtab @@ -10,6 +10,7 @@ #include <stdio.h> #include <string.h> #include <getopt.h> +#include <time.h> #if defined(RPC) #include "rquota.h" @@ -26,6 +27,7 @@ #define FL_ALL 8 #define FL_PROTO 16 #define FL_GRACE 32 +#define FL_INDIVIDUAL_GRACE 64 int flags, fmt = -1; char **mnt; @@ -42,13 +44,15 @@ static void usage(void) " setquota [-u|-g] [-r] [-F quotaformat] <user|group>\n" "\t<block-softlimit> <block-hardlimit> <inode-softlimit> <inode-hardlimit> -a|<filesystem>...\n" " setquota [-u|-g] [-r] [-F quotaformat] <-p protouser|protogroup> <user|group> -a|<filesystem>...\n" - " setquota [-u|-g] [-F quotaformat] -t <blockgrace> <inodegrace> -a|<filesystem>...\n")); + " setquota [-u|-g] [-F quotaformat] -t <blockgrace> <inodegrace> -a|<filesystem>...\n" + " setquota [-u|-g] [-F quotaformat] <user|group> -T <blockgrace> <inodegrace> -a|<filesystem>...\n")); #else errstr(_("Usage:\n" " setquota [-u|-g] [-F quotaformat] <user|group>\n" "\t<block-softlimit> <block-hardlimit> <inode-softlimit> <inode-hardlimit> -a|<filesystem>...\n" " setquota [-u|-g] [-F quotaformat] <-p protouser|protogroup> <user|group> -a|<filesystem>...\n" - " setquota [-u|-g] [-F quotaformat] -t <blockgrace> <inodegrace> -a|<filesystem>...\n")); + " setquota [-u|-g] [-F quotaformat] -t <blockgrace> <inodegrace> -a|<filesystem>...\n" + " setquota [-u|-g] [-F quotaformat] <user|group> -T <blockgrace> <inodegrace> -a|<filesystem>...\n")); #endif fprintf(stderr, _("Bugs to: %s\n"), MY_EMAIL); exit(1); @@ -84,9 +88,9 @@ static void parse_options(int argcnt, char **argstr) char *protoname = NULL; #ifdef RPC_SETQUOTA - char *opts = "igp:urVF:ta"; + char *opts = "igp:urVF:taT"; #else - char *opts = "igp:uVF:ta"; + char *opts = "igp:uVF:taT"; #endif while ((ret = getopt(argcnt, argstr, opts)) != -1) { @@ -113,6 +117,9 @@ static void parse_options(int argcnt, char **argstr) case 't': flags |= FL_GRACE; break; + case 'T': + flags |= FL_INDIVIDUAL_GRACE; + break; case 'F': if ((fmt = name2fmt(optarg)) == QF_ERROR) exit(1); @@ -132,6 +139,8 @@ static void parse_options(int argcnt, char **argstr) } if (flags & FL_GRACE) otherargs = 2; + else if (flags & FL_INDIVIDUAL_GRACE) + otherargs = 3; else { otherargs = 1; if (!(flags & FL_PROTO)) @@ -145,19 +154,36 @@ static void parse_options(int argcnt, char **argstr) flags |= FL_USER; if (!(flags & FL_GRACE)) { id = name2id(argstr[optind++], flag2type(flags)); - if (!(flags & FL_PROTO)) { + if (!(flags & (FL_GRACE | FL_INDIVIDUAL_GRACE | FL_PROTO))) { toset.dqb_bsoftlimit = parse_num(argstr[optind++], _("block softlimit")); toset.dqb_bhardlimit = parse_num(argstr[optind++], _("block hardlimit")); toset.dqb_isoftlimit = parse_num(argstr[optind++], _("inode softlimit")); toset.dqb_ihardlimit = parse_num(argstr[optind++], _("inode hardlimit")); } - else + else if (flags & FL_PROTO) protoid = name2id(protoname, flag2type(flags)); } - else { + if (flags & FL_GRACE) { toset.dqb_btime = parse_num(argstr[optind++], _("block grace time")); toset.dqb_itime = parse_num(argstr[optind++], _("inode grace time")); } + else if (flags & FL_INDIVIDUAL_GRACE) { + time_t now; + + time(&now); + if (!strcmp(argstr[optind], _("unset"))) { + toset.dqb_btime = 0; + optind++; + } + else + toset.dqb_btime = now + parse_num(argstr[optind++], _("block grace time")); + if (!strcmp(argstr[optind], _("unset"))) { + toset.dqb_itime = 0; + optind++; + } + else + toset.dqb_itime = now + parse_num(argstr[optind++], _("inode grace time")); + } if (!(flags & FL_ALL)) { mntcnt = argcnt - optind; mnt = argstr + optind; @@ -194,7 +220,7 @@ static void setlimits(struct quota_handle **handles) update_grace_times(q); } } - putprivs(curprivs); + putprivs(curprivs, COMMIT_LIMITS); freeprivs(curprivs); } @@ -210,6 +236,21 @@ static void setgraces(struct quota_handle **handles) } } +/* Set grace times for individual user */ +static void setindivgraces(struct quota_handle **handles) +{ + struct dquot *q, *curprivs; + + curprivs = getprivs(id, handles, 0); + for (q = curprivs; q; q = q->dq_next) { + q->dq_dqb.dqb_btime = toset.dqb_btime; + q->dq_dqb.dqb_itime = toset.dqb_itime; + } + if (putprivs(curprivs, COMMIT_TIMES) == -1) + errstr(_("Can't write times for %s. Maybe kernel doesn't support such operation?\n"), type2name(flags & FL_USER ? USRQUOTA : GRPQUOTA)); + freeprivs(curprivs); +} + int main(int argc, char **argv) { struct quota_handle **handles; @@ -227,6 +268,8 @@ int main(int argc, char **argv) if (flags & FL_GRACE) setgraces(handles); + else if (flags & FL_INDIVIDUAL_GRACE) + setindivgraces(handles); else setlimits(handles); |