[quota] Allow to set limits using multiplicative units

Petr Pisar ppisar at fedoraproject.org
Wed Jun 12 14:07:23 UTC 2013


commit f989b93d55c374f3ab112f83380c7cda3ca8ca18
Author: Petr Písař <ppisar at redhat.com>
Date:   Wed Jun 12 16:00:40 2013 +0200

    Allow to set limits using multiplicative units

 ...cognize-units-at-block-limits-by-setquota.patch |  151 +++++++++++++++++
 ...lock-limit-units-on-setquota-standard-inp.patch |   74 ++++++++
 ...ecognize-units-at-block-limits-by-edquota.patch |   89 ++++++++++
 ...ecognize-units-at-inode-limits-by-edquota.patch |  105 ++++++++++++
 ...cognize-units-at-inode-limits-by-setquota.patch |  177 ++++++++++++++++++++
 quota.spec                                         |   20 ++-
 6 files changed, 615 insertions(+), 1 deletions(-)
---
diff --git a/quota-4.00-Recognize-units-at-block-limits-by-setquota.patch b/quota-4.00-Recognize-units-at-block-limits-by-setquota.patch
new file mode 100644
index 0000000..4c88120
--- /dev/null
+++ b/quota-4.00-Recognize-units-at-block-limits-by-setquota.patch
@@ -0,0 +1,151 @@
+From 0ada9c13f9b8299ff607b66c37022ce2a3c4444b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar at redhat.com>
+Date: Wed, 9 Jan 2013 17:00:44 +0100
+Subject: [PATCH 1/5] Recognize units at block limits by setquota
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch allows to specify suffixes at block limits on setquota
+command line. Binary units K, M, G, T are implemented. Numeric value
+without suffix is equivatent to kibibytes as before. This is
+complementary functionality to `quota -s'.
+
+Signed-off-by: Petr Písař <ppisar at redhat.com>
+Signed-off-by: Jan Kara <jack at suse.cz>
+---
+ quota.h    |  2 ++
+ quotasys.c | 31 +++++++++++++++++++++++++++++++
+ quotasys.h |  3 +++
+ setquota.8 |  7 +++++++
+ setquota.c | 17 +++++++++++++++--
+ 5 files changed, 58 insertions(+), 2 deletions(-)
+
+diff --git a/quota.h b/quota.h
+index ac034d0..6787eab 100644
+--- a/quota.h
++++ b/quota.h
+@@ -2,9 +2,11 @@
+ #define GUARD_QUOTA_H
+ 
+ #include <sys/types.h>
++#include <stdint.h>
+ 
+ typedef u_int32_t qid_t;	/* Type in which we store ids in memory */
+ typedef int64_t qsize_t;	/* Type in which we store size limitations */
++#define QSIZE_MAX INT64_MAX /* Maximum value storable in qsize_t */
+ 
+ #define MAXQUOTAS 2
+ #define USRQUOTA  0		/* element used for user quotas */
+diff --git a/quotasys.c b/quotasys.c
+index 03f678a..5c1464f 100644
+--- a/quotasys.c
++++ b/quotasys.c
+@@ -367,6 +367,37 @@ void space2str(qsize_t space, char *buf, int format)
+ }
+ 
+ /*
++ * Convert block number with unit from string to quota blocks.
++ * Return NULL on success, static error message otherwise.
++ */
++const char *str2space(const char *string, qsize_t *space)
++{
++	char *unit;
++	unsigned long long int number;
++	int unit_shift;
++       
++	number = strtoull(string, &unit, 0);
++	if (ULLONG_MAX == number)
++		return _("Integer overflow while parsing space number.");
++
++	if (!unit || unit[0] == '\0' || !strcmp(unit, _("K")))
++		unit_shift = 0;
++	else if (!strcmp(unit, _("M")))
++		unit_shift = 10;
++	else if (!strcmp(unit, _("G")))
++		unit_shift = 20;
++	else if (!strcmp(unit, _("T")))
++		unit_shift = 30;
++	else
++		return _("Unknown space binary unit. "
++			"Valid units are K, M, G, T.");
++	if (number > (QSIZE_MAX >> unit_shift))
++		return _("Integer overflow while interpreting space unit.");
++	*space = number << unit_shift;
++	return NULL;
++}
++
++/*
+  *  Convert number to some nice short form for printing
+  */
+ void number2str(unsigned long long num, char *buf, int format)
+diff --git a/quotasys.h b/quotasys.h
+index 1cebf7e..0cc2c4c 100644
+--- a/quotasys.h
++++ b/quotasys.h
+@@ -103,6 +103,9 @@ int str2timeunits(time_t, char *, time_t *);
+ /* Convert number in quota blocks to short printable form */
+ void space2str(qsize_t, char *, int);
+ 
++/* Convert block number with unit from string to quota blocks */
++const char *str2space(const char *string, qsize_t *space);
++
+ /* Convert number to short printable form */
+ void number2str(unsigned long long, char *, int);
+ 
+diff --git a/setquota.8 b/setquota.8
+index db9d054..e4511c4 100644
+--- a/setquota.8
++++ b/setquota.8
+@@ -182,6 +182,13 @@ Go through all filesystems with quota in
+ .B /etc/mtab
+ and perform setting.
+ .PP
++.I block-softlimit
++and
++.I block-hardlimit
++are interpreted as multiples of kibibyte (1024 bytes) blocks by default.
++Symbols K, M, G, and T can be appended to numeric value to express kibibytes,
++mebibytes, gibibytes, and tebibytes.
++.PP
+ To disable a quota, set the corresponding parameter to 0. To change quotas
+ for several filesystems, invoke once for each filesystem.
+ .PP
+diff --git a/setquota.c b/setquota.c
+index f609dc7..ccac7f7 100644
+--- a/setquota.c
++++ b/setquota.c
+@@ -93,6 +93,19 @@ static qsize_t parse_unum(char *str, char *msg)
+ 	return ret;
+ }
+ 
++/* Convert block size to number - print errstr message in case of failure */
++static qsize_t parse_blocksize(const char *str, const char *msg)
++{
++	qsize_t ret;
++	const char *error = str2space(str, &ret);
++
++	if (error) {
++		errstr(_("%s: %s: %s\n"), msg, str, error);
++		usage();
++	}
++	return ret;
++}
++
+ /* Convert our flags to quota type */
+ static inline int flag2type(int flags)
+ {
+@@ -226,8 +239,8 @@ static void parse_options(int argcnt, char **argstr)
+ 	if (!(flags & (FL_GRACE | FL_BATCH))) {
+ 		id = name2id(argstr[optind++], flag2type(flags), !!(flags & FL_NUMNAMES), NULL);
+ 		if (!(flags & (FL_GRACE | FL_INDIVIDUAL_GRACE | FL_PROTO))) {
+-			toset.dqb_bsoftlimit = parse_unum(argstr[optind++], _("Bad block softlimit"));
+-			toset.dqb_bhardlimit = parse_unum(argstr[optind++], _("Bad block hardlimit"));
++			toset.dqb_bsoftlimit = parse_blocksize(argstr[optind++], _("Bad block softlimit"));
++			toset.dqb_bhardlimit = parse_blocksize(argstr[optind++], _("Bad block hardlimit"));
+ 			toset.dqb_isoftlimit = parse_unum(argstr[optind++], _("Bad inode softlimit"));
+ 			toset.dqb_ihardlimit = parse_unum(argstr[optind++], _("Bad inode hardlimit"));
+ 		}
+-- 
+1.8.1.4
+
diff --git a/quota-4.01-Recognize-block-limit-units-on-setquota-standard-inp.patch b/quota-4.01-Recognize-block-limit-units-on-setquota-standard-inp.patch
new file mode 100644
index 0000000..d017cd8
--- /dev/null
+++ b/quota-4.01-Recognize-block-limit-units-on-setquota-standard-inp.patch
@@ -0,0 +1,74 @@
+From 2d851a9726b799078f8c2279d8dd9ce39b7b4055 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar at redhat.com>
+Date: Wed, 9 Jan 2013 17:27:11 +0100
+Subject: [PATCH 2/5] Recognize block limit units on setquota standard input
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch adds support for binary suffixes on `setquota -b' input.
+
+Signed-off-by: Petr Písař <ppisar at redhat.com>
+Signed-off-by: Jan Kara <jack at suse.cz>
+---
+ setquota.c | 26 ++++++++++++++++++++++----
+ 1 file changed, 22 insertions(+), 4 deletions(-)
+
+diff --git a/setquota.c b/setquota.c
+index ccac7f7..e55b79d 100644
+--- a/setquota.c
++++ b/setquota.c
+@@ -319,7 +319,9 @@ static int read_entry(qid_t *id, qsize_t *isoftlimit, qsize_t *ihardlimit, qsize
+ 	static int line = 0;
+ 	char name[MAXNAMELEN+1];
+ 	char linebuf[MAXLINELEN], *chptr;
+-	unsigned long is, ih, bs, bh;
++	unsigned long is, ih;
++	char bs[MAXNAMELEN+1], bh[MAXNAMELEN+1];
++	const char *error;
+ 	int ret;
+ 
+ 	while (1) {
+@@ -337,7 +339,7 @@ static int read_entry(qid_t *id, qsize_t *isoftlimit, qsize_t *ihardlimit, qsize
+ 			chptr++;
+ 		if (*chptr == '\n')
+ 			continue;
+-		ret = sscanf(chptr, "%s %lu %lu %lu %lu", name, &bs, &bh, &is, &ih);
++		ret = sscanf(chptr, "%s %s %s %lu %lu", name, bs, bh, &is, &ih);
+ 		if (ret != 5) {
+ 			errstr(_("Cannot parse input line %d.\n"), line);
+ 			if (!(flags & FL_CONTINUE_BATCH))
+@@ -353,12 +355,28 @@ static int read_entry(qid_t *id, qsize_t *isoftlimit, qsize_t *ihardlimit, qsize
+ 			errstr(_("Skipping line.\n"));
+ 			continue;
+ 		}
++		error = str2space(bs, bsoftlimit);
++		if (error) {
++			errstr(_("Unable to parse block soft limit '%s' "
++				    "on line %d: %s\n"), bs, line, error);
++			if (!(flags & FL_CONTINUE_BATCH))
++				die(1, _("Exitting.\n"));
++			errstr(_("Skipping line.\n"));
++			continue;
++		}
++		error = str2space(bh, bhardlimit);
++		if (error) {
++			errstr(_("Unable to parse block hard limit '%s' "
++				    "on line %d: %s\n"), bh, line, error);
++			if (!(flags & FL_CONTINUE_BATCH))
++				die(1, _("Exitting.\n"));
++			errstr(_("Skipping line.\n"));
++			continue;
++		}
+ 		break;
+ 	}
+ 	*isoftlimit = is;
+ 	*ihardlimit = ih;
+-	*bsoftlimit = bs;
+-	*bhardlimit = bh;
+ 	return 0;
+ }
+ 
+-- 
+1.8.1.4
+
diff --git a/quota-4.01-Recognize-units-at-block-limits-by-edquota.patch b/quota-4.01-Recognize-units-at-block-limits-by-edquota.patch
new file mode 100644
index 0000000..ce0f1d6
--- /dev/null
+++ b/quota-4.01-Recognize-units-at-block-limits-by-edquota.patch
@@ -0,0 +1,89 @@
+From f61d6442cc92a2b2935db6995b8d901235dbd076 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar at redhat.com>
+Date: Wed, 9 Jan 2013 18:16:14 +0100
+Subject: [PATCH 3/5] Recognize units at block limits by edquota
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+With this patch, it's possible to specify block values including
+binary units in the editor run by edquota.
+
+Signed-off-by: Petr Písař <ppisar at redhat.com>
+Signed-off-by: Jan Kara <jack at suse.cz>
+---
+ edquota.8  |  4 ++++
+ quotaops.c | 28 +++++++++++++++++++++++++---
+ 2 files changed, 29 insertions(+), 3 deletions(-)
+
+diff --git a/edquota.8 b/edquota.8
+index 4b1406b..2617068 100644
+--- a/edquota.8
++++ b/edquota.8
+@@ -64,6 +64,10 @@ is then invoked on the file.  The quotas may then be modified, new
+ quotas added, etc.
+ Setting a quota to zero indicates that no quota should be imposed.
+ .PP
++Block usage and limits are reported and interpereted as multiples of kibibyte
++(1024 bytes) blocks by default. Symbols K, M, G, and T can be appended to
++numeric value to express kibibytes, mebibytes, gibibytes, and tebibytes.
++.PP
+ Users are permitted to exceed their soft limits for a grace period that
+ may be specified per filesystem.  Once the grace period has expired, the
+ soft limit is enforced as a hard limit.
+diff --git a/quotaops.c b/quotaops.c
+index 1416015..32e21da 100644
+--- a/quotaops.c
++++ b/quotaops.c
+@@ -310,9 +310,12 @@ int readprivs(struct dquot *qlist, int infd)
+ {
+ 	FILE *fd;
+ 	int cnt;
+-	long long blocks, bsoft, bhard, inodes, isoft, ihard;
++	qsize_t blocks, bsoft, bhard;
++	long long inodes, isoft, ihard;
+ 	struct dquot *q;
+ 	char fsp[BUFSIZ], line[BUFSIZ];
++	char blocksstring[BUFSIZ], bsoftstring[BUFSIZ], bhardstring[BUFSIZ];
++	const char *error;
+ 
+ 	lseek(infd, 0, SEEK_SET);
+ 	if (!(fd = fdopen(dup(infd), "r")))
+@@ -325,13 +328,32 @@ int readprivs(struct dquot *qlist, int infd)
+ 	fgets(line, sizeof(line), fd);
+ 
+ 	while (fgets(line, sizeof(line), fd)) {
+-		cnt = sscanf(line, "%s %llu %llu %llu %llu %llu %llu",
+-			     fsp, &blocks, &bsoft, &bhard, &inodes, &isoft, &ihard);
++		cnt = sscanf(line, "%s %s %s %s %llu %llu %llu",
++			     fsp, blocksstring, bsoftstring, bhardstring,
++			     &inodes, &isoft, &ihard);
+ 
+ 		if (cnt != 7) {
+ 			errstr(_("Bad format:\n%s\n"), line);
+ 			return -1;
+ 		}
++		error = str2space(blocksstring, &blocks);
++		if (error) {
++			errstr(_("Bad block usage: %s: %s\n"),
++				blocksstring, error);
++			return -1;
++		}
++		error = str2space(bsoftstring, &bsoft);
++		if (error) {
++			errstr(_("Bad block soft limit: %s: %s\n"),
++				bsoftstring, error);
++			return -1;
++		}
++		error = str2space(bhardstring, &bhard);
++		if (error) {
++			errstr(_("Bad block hard limit: %s: %s\n"),
++				bhardstring, error);
++			return -1;
++		}
+ 
+ 		merge_limits_to_list(qlist, fsp, blocks, bsoft, bhard, inodes, isoft, ihard);
+ 	}
+-- 
+1.8.1.4
+
diff --git a/quota-4.01-Recognize-units-at-inode-limits-by-edquota.patch b/quota-4.01-Recognize-units-at-inode-limits-by-edquota.patch
new file mode 100644
index 0000000..628dc54
--- /dev/null
+++ b/quota-4.01-Recognize-units-at-inode-limits-by-edquota.patch
@@ -0,0 +1,105 @@
+From 73316c7746e89896c63fc49f24cafe32335df288 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar at redhat.com>
+Date: Wed, 9 Jan 2013 18:16:14 +0100
+Subject: [PATCH 5/5] Recognize units at inode limits by edquota
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+With this patch, it's possible to specify inode values including
+decimal units in the editor run by edquota.
+
+Signed-off-by: Petr Písař <ppisar at redhat.com>
+Signed-off-by: Jan Kara <jack at suse.cz>
+---
+ edquota.8  |  4 ++++
+ quotaops.c | 26 ++++++++++++++++++++++----
+ setquota.c |  2 --
+ 3 files changed, 26 insertions(+), 6 deletions(-)
+
+diff --git a/edquota.8 b/edquota.8
+index 2617068..fefb5d4 100644
+--- a/edquota.8
++++ b/edquota.8
+@@ -68,6 +68,10 @@ Block usage and limits are reported and interpereted as multiples of kibibyte
+ (1024 bytes) blocks by default. Symbols K, M, G, and T can be appended to
+ numeric value to express kibibytes, mebibytes, gibibytes, and tebibytes.
+ .PP
++Inode usage and limits are interpreted literally. Symbols k, m, g, and t can
++be appended to numeric value to express multiples of 10^3, 10^6, 10^9, and
++10^12 inodes.
++.PP
+ Users are permitted to exceed their soft limits for a grace period that
+ may be specified per filesystem.  Once the grace period has expired, the
+ soft limit is enforced as a hard limit.
+diff --git a/quotaops.c b/quotaops.c
+index 32e21da..175a945 100644
+--- a/quotaops.c
++++ b/quotaops.c
+@@ -310,11 +310,11 @@ int readprivs(struct dquot *qlist, int infd)
+ {
+ 	FILE *fd;
+ 	int cnt;
+-	qsize_t blocks, bsoft, bhard;
+-	long long inodes, isoft, ihard;
++	qsize_t blocks, bsoft, bhard, inodes, isoft, ihard;
+ 	struct dquot *q;
+ 	char fsp[BUFSIZ], line[BUFSIZ];
+ 	char blocksstring[BUFSIZ], bsoftstring[BUFSIZ], bhardstring[BUFSIZ];
++	char inodesstring[BUFSIZ], isoftstring[BUFSIZ], ihardstring[BUFSIZ];
+ 	const char *error;
+ 
+ 	lseek(infd, 0, SEEK_SET);
+@@ -328,9 +328,9 @@ int readprivs(struct dquot *qlist, int infd)
+ 	fgets(line, sizeof(line), fd);
+ 
+ 	while (fgets(line, sizeof(line), fd)) {
+-		cnt = sscanf(line, "%s %s %s %s %llu %llu %llu",
++		cnt = sscanf(line, "%s %s %s %s %s %s %s",
+ 			     fsp, blocksstring, bsoftstring, bhardstring,
+-			     &inodes, &isoft, &ihard);
++			     inodesstring, isoftstring, ihardstring);
+ 
+ 		if (cnt != 7) {
+ 			errstr(_("Bad format:\n%s\n"), line);
+@@ -354,6 +354,24 @@ int readprivs(struct dquot *qlist, int infd)
+ 				bhardstring, error);
+ 			return -1;
+ 		}
++		error = str2number(inodesstring, &inodes);
++		if (error) {
++			errstr(_("Bad inode usage: %s: %s\n"),
++				inodesstring, error);
++			return -1;
++		}
++		error = str2number(isoftstring, &isoft);
++		if (error) {
++			errstr(_("Bad inode soft limit: %s: %s\n"),
++				isoftstring, error);
++			return -1;
++		}
++		error = str2number(ihardstring, &ihard);
++		if (error) {
++			errstr(_("Bad inode hard limit: %s: %s\n"),
++				ihardstring, error);
++			return -1;
++		}
+ 
+ 		merge_limits_to_list(qlist, fsp, blocks, bsoft, bhard, inodes, isoft, ihard);
+ 	}
+diff --git a/setquota.c b/setquota.c
+index 19449ad..cc5fee8 100644
+--- a/setquota.c
++++ b/setquota.c
+@@ -406,8 +406,6 @@ static int read_entry(qid_t *id, qsize_t *isoftlimit, qsize_t *ihardlimit, qsize
+ 		}
+ 		break;
+ 	}
+-	*isoftlimit = is;
+-	*ihardlimit = ih;
+ 	return 0;
+ }
+ 
+-- 
+1.8.1.4
+
diff --git a/quota-4.01-Recognize-units-at-inode-limits-by-setquota.patch b/quota-4.01-Recognize-units-at-inode-limits-by-setquota.patch
new file mode 100644
index 0000000..3221f2f
--- /dev/null
+++ b/quota-4.01-Recognize-units-at-inode-limits-by-setquota.patch
@@ -0,0 +1,177 @@
+From fdcf21db852bc8d6c1d0b41f2812ba614851e2b4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar at redhat.com>
+Date: Wed, 9 Jan 2013 17:00:44 +0100
+Subject: [PATCH 4/5] Recognize units at inode limits by setquota
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch allows to specify suffixes at inode limits on setquota
+command line and standard input. Decimal Units k, m, g, t are
+implemented.  Numeric value without suffix is equivatent to single
+inodes as before.  This is complementary functionality to `quota -s'.
+
+Signed-off-by: Petr Písař <ppisar at redhat.com>
+Signed-off-by: Jan Kara <jack at suse.cz>
+---
+ quotasys.c | 32 ++++++++++++++++++++++++++++++++
+ quotasys.h |  3 +++
+ setquota.8 |  6 ++++++
+ setquota.c | 39 +++++++++++++++++++++++++++++++++++----
+ 4 files changed, 76 insertions(+), 4 deletions(-)
+
+diff --git a/quotasys.c b/quotasys.c
+index 5c1464f..e583437 100644
+--- a/quotasys.c
++++ b/quotasys.c
+@@ -416,6 +416,38 @@ void number2str(unsigned long long num, char *buf, int format)
+ }
+ 
+ /*
++ * Convert inode number with unit from string to quota inodes.
++ * Return NULL on success, static error message otherwise.
++ */
++const char *str2number(const char *string, qsize_t *inodes)
++{
++	char *unit;
++	unsigned long long int number, multiple;
++       
++	number = strtoull(string, &unit, 0);
++	if (ULLONG_MAX == number)
++		return _("Integer overflow while parsing number.");
++
++	if (!unit || unit[0] == '\0')
++		multiple = 1;
++	else if (!strcmp(unit, _("k")))
++		multiple = 1000;
++	else if (!strcmp(unit, _("m")))
++		multiple = 1000000;
++	else if (!strcmp(unit, _("g")))
++		multiple = 1000000000;
++	else if (!strcmp(unit, _("t")))
++		multiple = 1000000000000ULL;
++	else
++		return _("Unknown decimal unit. "
++			"Valid units are k, m, g, t.");
++	if (number > QSIZE_MAX / multiple)
++		return _("Integer overflow while interpreting decimal unit.");
++	*inodes = number * multiple;
++	return NULL;
++}
++
++/*
+  *	Wrappers for mount options processing functions
+  */
+ 
+diff --git a/quotasys.h b/quotasys.h
+index 0cc2c4c..505ea77 100644
+--- a/quotasys.h
++++ b/quotasys.h
+@@ -109,6 +109,9 @@ const char *str2space(const char *string, qsize_t *space);
+ /* Convert number to short printable form */
+ void number2str(unsigned long long, char *, int);
+ 
++/* Convert inode number with unit from string to quota inodes. */
++const char *str2number(const char *string, qsize_t *inodes);
++
+ /* Return pointer to given mount option in mount option string */
+ char *str_hasmntopt(const char *optstring, const char *opt);
+ 
+diff --git a/setquota.8 b/setquota.8
+index e4511c4..508309e 100644
+--- a/setquota.8
++++ b/setquota.8
+@@ -189,6 +189,12 @@ are interpreted as multiples of kibibyte (1024 bytes) blocks by default.
+ Symbols K, M, G, and T can be appended to numeric value to express kibibytes,
+ mebibytes, gibibytes, and tebibytes.
+ .PP
++.I inode-softlimit
++and
++.I inode-hardlimit
++are interpreted literally. Symbols k, m, g, and t can be appended to numeric
++value to express multiples of 10^3, 10^6, 10^9, and 10^12 inodes.
++.PP
+ To disable a quota, set the corresponding parameter to 0. To change quotas
+ for several filesystems, invoke once for each filesystem.
+ .PP
+diff --git a/setquota.c b/setquota.c
+index e55b79d..19449ad 100644
+--- a/setquota.c
++++ b/setquota.c
+@@ -106,6 +106,19 @@ static qsize_t parse_blocksize(const char *str, const char *msg)
+ 	return ret;
+ }
+ 
++/* Convert inode count to number - print errstr message in case of failure */
++static qsize_t parse_inodecount(const char *str, const char *msg)
++{
++	qsize_t ret;
++	const char *error = str2number(str, &ret);
++
++	if (error) {
++		errstr(_("%s: %s: %s\n"), msg, str, error);
++		usage();
++	}
++	return ret;
++}
++
+ /* Convert our flags to quota type */
+ static inline int flag2type(int flags)
+ {
+@@ -241,8 +254,8 @@ static void parse_options(int argcnt, char **argstr)
+ 		if (!(flags & (FL_GRACE | FL_INDIVIDUAL_GRACE | FL_PROTO))) {
+ 			toset.dqb_bsoftlimit = parse_blocksize(argstr[optind++], _("Bad block softlimit"));
+ 			toset.dqb_bhardlimit = parse_blocksize(argstr[optind++], _("Bad block hardlimit"));
+-			toset.dqb_isoftlimit = parse_unum(argstr[optind++], _("Bad inode softlimit"));
+-			toset.dqb_ihardlimit = parse_unum(argstr[optind++], _("Bad inode hardlimit"));
++			toset.dqb_isoftlimit = parse_inodecount(argstr[optind++], _("Bad inode softlimit"));
++			toset.dqb_ihardlimit = parse_inodecount(argstr[optind++], _("Bad inode hardlimit"));
+ 		}
+ 		else if (flags & FL_PROTO)
+ 			protoid = name2id(protoname, flag2type(flags), !!(flags & FL_NUMNAMES), NULL);
+@@ -319,7 +332,7 @@ static int read_entry(qid_t *id, qsize_t *isoftlimit, qsize_t *ihardlimit, qsize
+ 	static int line = 0;
+ 	char name[MAXNAMELEN+1];
+ 	char linebuf[MAXLINELEN], *chptr;
+-	unsigned long is, ih;
++	char is[MAXNAMELEN+1], ih[MAXNAMELEN+1];
+ 	char bs[MAXNAMELEN+1], bh[MAXNAMELEN+1];
+ 	const char *error;
+ 	int ret;
+@@ -339,7 +352,7 @@ static int read_entry(qid_t *id, qsize_t *isoftlimit, qsize_t *ihardlimit, qsize
+ 			chptr++;
+ 		if (*chptr == '\n')
+ 			continue;
+-		ret = sscanf(chptr, "%s %s %s %lu %lu", name, bs, bh, &is, &ih);
++		ret = sscanf(chptr, "%s %s %s %s %s", name, bs, bh, is, ih);
+ 		if (ret != 5) {
+ 			errstr(_("Cannot parse input line %d.\n"), line);
+ 			if (!(flags & FL_CONTINUE_BATCH))
+@@ -373,6 +386,24 @@ static int read_entry(qid_t *id, qsize_t *isoftlimit, qsize_t *ihardlimit, qsize
+ 			errstr(_("Skipping line.\n"));
+ 			continue;
+ 		}
++		error = str2number(is, isoftlimit);
++		if (error) {
++			errstr(_("Unable to parse inode soft limit '%s' "
++				    "on line %d: %s\n"), is, line, error);
++			if (!(flags & FL_CONTINUE_BATCH))
++				die(1, _("Exitting.\n"));
++			errstr(_("Skipping line.\n"));
++			continue;
++		}
++		error = str2number(ih, ihardlimit);
++		if (error) {
++			errstr(_("Unable to parse inode hard limit '%s' "
++				    "on line %d: %s\n"), ih, line, error);
++			if (!(flags & FL_CONTINUE_BATCH))
++				die(1, _("Exitting.\n"));
++			errstr(_("Skipping line.\n"));
++			continue;
++		}
+ 		break;
+ 	}
+ 	*isoftlimit = is;
+-- 
+1.8.1.4
+
diff --git a/quota.spec b/quota.spec
index 711c618..43e0f9f 100644
--- a/quota.spec
+++ b/quota.spec
@@ -5,7 +5,7 @@ Name: quota
 Summary: System administration tools for monitoring users' disk usage
 Epoch: 1
 Version: 4.01
-Release: 7%{?dist}
+Release: 8%{?dist}
 # quota_nld.c, quotaio_xfs.h:       GPLv2
 # bylabel.c copied from util-linux: GPLv2+
 # svc_socket.c copied from glibc:   LGPLv2+
@@ -45,6 +45,16 @@ Patch9: quota-4.01-Complete-quotasync-usage.patch
 Patch10: quota-4.01-Correct-quotasync-exit-code.patch
 # In upstream after 4.01, SF#3607038
 Patch11: quota-4.01-Fix-various-usage-mistakes.patch
+# In upstream after 4.01, SF#3600120
+Patch12: quota-4.00-Recognize-units-at-block-limits-by-setquota.patch
+# In upstream after 4.01, SF#3600120
+Patch13: quota-4.01-Recognize-block-limit-units-on-setquota-standard-inp.patch
+# In upstream after 4.01, SF#3600120
+Patch14: quota-4.01-Recognize-units-at-block-limits-by-edquota.patch
+# In upstream after 4.01, SF#3600120
+Patch15: quota-4.01-Recognize-units-at-inode-limits-by-setquota.patch
+# In upstream after 4.01, SF#3600120
+Patch16: quota-4.01-Recognize-units-at-inode-limits-by-edquota.patch
 
 
 %description
@@ -129,6 +139,11 @@ Linux/UNIX environment.
 %patch9 -p1 -b .quotasync_usage
 %patch10 -p1 -b .quotasync_exit
 %patch11 -p1 -b .usage
+%patch12 -p1 -b .setquota_block_units
+%patch13 -p1 -b .setquota_block_units_stdin
+%patch14 -p1 -b .edquota_block_units
+%patch15 -p1 -b .setquota_inode_units
+%patch16 -p1 -b .edquota_inode_units
 
 #fix typos/mistakes in localized documentation
 for pofile in $(find ./po/*.p*)
@@ -227,6 +242,9 @@ install -p -m644 -D %{SOURCE2} \
 
 
 %changelog
+* Wed Jun 12 2013 Petr Pisar <ppisar at redhat.com> - 1:4.01-8
+- Allow to set limits using multiplicative units
+
 * Mon May 27 2013 Petr Pisar <ppisar at redhat.com> - 1:4.01-7
 - Add LGPLv2+ and GPLv2 to license declaration
 - Correct changelog dates


More information about the scm-commits mailing list