|
|
dba0f0 |
From fdcf21db852bc8d6c1d0b41f2812ba614851e2b4 Mon Sep 17 00:00:00 2001
|
|
|
dba0f0 |
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
|
|
|
dba0f0 |
Date: Wed, 9 Jan 2013 17:00:44 +0100
|
|
|
dba0f0 |
Subject: [PATCH 4/5] Recognize units at inode limits by setquota
|
|
|
dba0f0 |
MIME-Version: 1.0
|
|
|
dba0f0 |
Content-Type: text/plain; charset=UTF-8
|
|
|
dba0f0 |
Content-Transfer-Encoding: 8bit
|
|
|
dba0f0 |
|
|
|
dba0f0 |
This patch allows to specify suffixes at inode limits on setquota
|
|
|
dba0f0 |
command line and standard input. Decimal Units k, m, g, t are
|
|
|
dba0f0 |
implemented. Numeric value without suffix is equivatent to single
|
|
|
dba0f0 |
inodes as before. This is complementary functionality to `quota -s'.
|
|
|
dba0f0 |
|
|
|
dba0f0 |
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
|
|
dba0f0 |
Signed-off-by: Jan Kara <jack@suse.cz>
|
|
|
dba0f0 |
---
|
|
|
dba0f0 |
quotasys.c | 32 ++++++++++++++++++++++++++++++++
|
|
|
dba0f0 |
quotasys.h | 3 +++
|
|
|
dba0f0 |
setquota.8 | 6 ++++++
|
|
|
dba0f0 |
setquota.c | 39 +++++++++++++++++++++++++++++++++++----
|
|
|
dba0f0 |
4 files changed, 76 insertions(+), 4 deletions(-)
|
|
|
dba0f0 |
|
|
|
dba0f0 |
diff --git a/quotasys.c b/quotasys.c
|
|
|
dba0f0 |
index 5c1464f..e583437 100644
|
|
|
dba0f0 |
--- a/quotasys.c
|
|
|
dba0f0 |
+++ b/quotasys.c
|
|
|
dba0f0 |
@@ -416,6 +416,38 @@ void number2str(unsigned long long num, char *buf, int format)
|
|
|
dba0f0 |
}
|
|
|
dba0f0 |
|
|
|
dba0f0 |
/*
|
|
|
dba0f0 |
+ * Convert inode number with unit from string to quota inodes.
|
|
|
dba0f0 |
+ * Return NULL on success, static error message otherwise.
|
|
|
dba0f0 |
+ */
|
|
|
dba0f0 |
+const char *str2number(const char *string, qsize_t *inodes)
|
|
|
dba0f0 |
+{
|
|
|
dba0f0 |
+ char *unit;
|
|
|
dba0f0 |
+ unsigned long long int number, multiple;
|
|
|
dba0f0 |
+
|
|
|
dba0f0 |
+ number = strtoull(string, &unit, 0);
|
|
|
dba0f0 |
+ if (ULLONG_MAX == number)
|
|
|
dba0f0 |
+ return _("Integer overflow while parsing number.");
|
|
|
dba0f0 |
+
|
|
|
dba0f0 |
+ if (!unit || unit[0] == '\0')
|
|
|
dba0f0 |
+ multiple = 1;
|
|
|
dba0f0 |
+ else if (!strcmp(unit, _("k")))
|
|
|
dba0f0 |
+ multiple = 1000;
|
|
|
dba0f0 |
+ else if (!strcmp(unit, _("m")))
|
|
|
dba0f0 |
+ multiple = 1000000;
|
|
|
dba0f0 |
+ else if (!strcmp(unit, _("g")))
|
|
|
dba0f0 |
+ multiple = 1000000000;
|
|
|
dba0f0 |
+ else if (!strcmp(unit, _("t")))
|
|
|
dba0f0 |
+ multiple = 1000000000000ULL;
|
|
|
dba0f0 |
+ else
|
|
|
dba0f0 |
+ return _("Unknown decimal unit. "
|
|
|
dba0f0 |
+ "Valid units are k, m, g, t.");
|
|
|
dba0f0 |
+ if (number > QSIZE_MAX / multiple)
|
|
|
dba0f0 |
+ return _("Integer overflow while interpreting decimal unit.");
|
|
|
dba0f0 |
+ *inodes = number * multiple;
|
|
|
dba0f0 |
+ return NULL;
|
|
|
dba0f0 |
+}
|
|
|
dba0f0 |
+
|
|
|
dba0f0 |
+/*
|
|
|
dba0f0 |
* Wrappers for mount options processing functions
|
|
|
dba0f0 |
*/
|
|
|
dba0f0 |
|
|
|
dba0f0 |
diff --git a/quotasys.h b/quotasys.h
|
|
|
dba0f0 |
index 0cc2c4c..505ea77 100644
|
|
|
dba0f0 |
--- a/quotasys.h
|
|
|
dba0f0 |
+++ b/quotasys.h
|
|
|
dba0f0 |
@@ -109,6 +109,9 @@ const char *str2space(const char *string, qsize_t *space);
|
|
|
dba0f0 |
/* Convert number to short printable form */
|
|
|
dba0f0 |
void number2str(unsigned long long, char *, int);
|
|
|
dba0f0 |
|
|
|
dba0f0 |
+/* Convert inode number with unit from string to quota inodes. */
|
|
|
dba0f0 |
+const char *str2number(const char *string, qsize_t *inodes);
|
|
|
dba0f0 |
+
|
|
|
dba0f0 |
/* Return pointer to given mount option in mount option string */
|
|
|
dba0f0 |
char *str_hasmntopt(const char *optstring, const char *opt);
|
|
|
dba0f0 |
|
|
|
dba0f0 |
diff --git a/setquota.8 b/setquota.8
|
|
|
dba0f0 |
index e4511c4..508309e 100644
|
|
|
dba0f0 |
--- a/setquota.8
|
|
|
dba0f0 |
+++ b/setquota.8
|
|
|
dba0f0 |
@@ -189,6 +189,12 @@ are interpreted as multiples of kibibyte (1024 bytes) blocks by default.
|
|
|
dba0f0 |
Symbols K, M, G, and T can be appended to numeric value to express kibibytes,
|
|
|
dba0f0 |
mebibytes, gibibytes, and tebibytes.
|
|
|
dba0f0 |
.PP
|
|
|
dba0f0 |
+.I inode-softlimit
|
|
|
dba0f0 |
+and
|
|
|
dba0f0 |
+.I inode-hardlimit
|
|
|
dba0f0 |
+are interpreted literally. Symbols k, m, g, and t can be appended to numeric
|
|
|
dba0f0 |
+value to express multiples of 10^3, 10^6, 10^9, and 10^12 inodes.
|
|
|
dba0f0 |
+.PP
|
|
|
dba0f0 |
To disable a quota, set the corresponding parameter to 0. To change quotas
|
|
|
dba0f0 |
for several filesystems, invoke once for each filesystem.
|
|
|
dba0f0 |
.PP
|
|
|
dba0f0 |
diff --git a/setquota.c b/setquota.c
|
|
|
dba0f0 |
index e55b79d..19449ad 100644
|
|
|
dba0f0 |
--- a/setquota.c
|
|
|
dba0f0 |
+++ b/setquota.c
|
|
|
dba0f0 |
@@ -106,6 +106,19 @@ static qsize_t parse_blocksize(const char *str, const char *msg)
|
|
|
dba0f0 |
return ret;
|
|
|
dba0f0 |
}
|
|
|
dba0f0 |
|
|
|
dba0f0 |
+/* Convert inode count to number - print errstr message in case of failure */
|
|
|
dba0f0 |
+static qsize_t parse_inodecount(const char *str, const char *msg)
|
|
|
dba0f0 |
+{
|
|
|
dba0f0 |
+ qsize_t ret;
|
|
|
dba0f0 |
+ const char *error = str2number(str, &ret;;
|
|
|
dba0f0 |
+
|
|
|
dba0f0 |
+ if (error) {
|
|
|
dba0f0 |
+ errstr(_("%s: %s: %s\n"), msg, str, error);
|
|
|
dba0f0 |
+ usage();
|
|
|
dba0f0 |
+ }
|
|
|
dba0f0 |
+ return ret;
|
|
|
dba0f0 |
+}
|
|
|
dba0f0 |
+
|
|
|
dba0f0 |
/* Convert our flags to quota type */
|
|
|
dba0f0 |
static inline int flag2type(int flags)
|
|
|
dba0f0 |
{
|
|
|
dba0f0 |
@@ -241,8 +254,8 @@ static void parse_options(int argcnt, char **argstr)
|
|
|
dba0f0 |
if (!(flags & (FL_GRACE | FL_INDIVIDUAL_GRACE | FL_PROTO))) {
|
|
|
dba0f0 |
toset.dqb_bsoftlimit = parse_blocksize(argstr[optind++], _("Bad block softlimit"));
|
|
|
dba0f0 |
toset.dqb_bhardlimit = parse_blocksize(argstr[optind++], _("Bad block hardlimit"));
|
|
|
dba0f0 |
- toset.dqb_isoftlimit = parse_unum(argstr[optind++], _("Bad inode softlimit"));
|
|
|
dba0f0 |
- toset.dqb_ihardlimit = parse_unum(argstr[optind++], _("Bad inode hardlimit"));
|
|
|
dba0f0 |
+ toset.dqb_isoftlimit = parse_inodecount(argstr[optind++], _("Bad inode softlimit"));
|
|
|
dba0f0 |
+ toset.dqb_ihardlimit = parse_inodecount(argstr[optind++], _("Bad inode hardlimit"));
|
|
|
dba0f0 |
}
|
|
|
dba0f0 |
else if (flags & FL_PROTO)
|
|
|
dba0f0 |
protoid = name2id(protoname, flag2type(flags), !!(flags & FL_NUMNAMES), NULL);
|
|
|
dba0f0 |
@@ -319,7 +332,7 @@ static int read_entry(qid_t *id, qsize_t *isoftlimit, qsize_t *ihardlimit, qsize
|
|
|
dba0f0 |
static int line = 0;
|
|
|
dba0f0 |
char name[MAXNAMELEN+1];
|
|
|
dba0f0 |
char linebuf[MAXLINELEN], *chptr;
|
|
|
dba0f0 |
- unsigned long is, ih;
|
|
|
dba0f0 |
+ char is[MAXNAMELEN+1], ih[MAXNAMELEN+1];
|
|
|
dba0f0 |
char bs[MAXNAMELEN+1], bh[MAXNAMELEN+1];
|
|
|
dba0f0 |
const char *error;
|
|
|
dba0f0 |
int ret;
|
|
|
dba0f0 |
@@ -339,7 +352,7 @@ static int read_entry(qid_t *id, qsize_t *isoftlimit, qsize_t *ihardlimit, qsize
|
|
|
dba0f0 |
chptr++;
|
|
|
dba0f0 |
if (*chptr == '\n')
|
|
|
dba0f0 |
continue;
|
|
|
dba0f0 |
- ret = sscanf(chptr, "%s %s %s %lu %lu", name, bs, bh, &is, &ih;;
|
|
|
dba0f0 |
+ ret = sscanf(chptr, "%s %s %s %s %s", name, bs, bh, is, ih);
|
|
|
dba0f0 |
if (ret != 5) {
|
|
|
dba0f0 |
errstr(_("Cannot parse input line %d.\n"), line);
|
|
|
dba0f0 |
if (!(flags & FL_CONTINUE_BATCH))
|
|
|
dba0f0 |
@@ -373,6 +386,24 @@ static int read_entry(qid_t *id, qsize_t *isoftlimit, qsize_t *ihardlimit, qsize
|
|
|
dba0f0 |
errstr(_("Skipping line.\n"));
|
|
|
dba0f0 |
continue;
|
|
|
dba0f0 |
}
|
|
|
dba0f0 |
+ error = str2number(is, isoftlimit);
|
|
|
dba0f0 |
+ if (error) {
|
|
|
dba0f0 |
+ errstr(_("Unable to parse inode soft limit '%s' "
|
|
|
dba0f0 |
+ "on line %d: %s\n"), is, line, error);
|
|
|
dba0f0 |
+ if (!(flags & FL_CONTINUE_BATCH))
|
|
|
dba0f0 |
+ die(1, _("Exitting.\n"));
|
|
|
dba0f0 |
+ errstr(_("Skipping line.\n"));
|
|
|
dba0f0 |
+ continue;
|
|
|
dba0f0 |
+ }
|
|
|
dba0f0 |
+ error = str2number(ih, ihardlimit);
|
|
|
dba0f0 |
+ if (error) {
|
|
|
dba0f0 |
+ errstr(_("Unable to parse inode hard limit '%s' "
|
|
|
dba0f0 |
+ "on line %d: %s\n"), ih, line, error);
|
|
|
dba0f0 |
+ if (!(flags & FL_CONTINUE_BATCH))
|
|
|
dba0f0 |
+ die(1, _("Exitting.\n"));
|
|
|
dba0f0 |
+ errstr(_("Skipping line.\n"));
|
|
|
dba0f0 |
+ continue;
|
|
|
dba0f0 |
+ }
|
|
|
dba0f0 |
break;
|
|
|
dba0f0 |
}
|
|
|
dba0f0 |
*isoftlimit = is;
|
|
|
dba0f0 |
--
|
|
|
dba0f0 |
1.8.1.4
|
|
|
dba0f0 |
|