summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjkar8572 <jkar8572>2001-11-08 23:56:11 +0000
committerjkar8572 <jkar8572>2001-11-08 23:56:11 +0000
commitaa77462747260f3a79cab65d2e75f33129caae2d (patch)
tree6baada38136b55a099c175e07f4d732d40be0435
parente3cd20e7ae77e71cd859b09849c1f68e57f9f580 (diff)
Added support for conversion of files with wrong endianity (due to SuSE RPM bug)
Added check to format detection routine to detect bad file endianity edquota and setquota now set just grace times and flags => avoid races on live filesystem
-rw-r--r--Changelog6
-rw-r--r--convertquota.810
-rw-r--r--convertquota.c242
-rw-r--r--dqblk_v2.h2
-rw-r--r--quotaio.c16
-rw-r--r--quotaio_v1.c7
-rw-r--r--quotaio_v2.c27
-rw-r--r--quotaio_v2.h2
-rw-r--r--quotastats.c7
-rw-r--r--quotasys.c25
10 files changed, 301 insertions, 43 deletions
diff --git a/Changelog b/Changelog
index 7cf524a..461deff 100644
--- a/Changelog
+++ b/Changelog
@@ -1,6 +1,12 @@
Changes in quota-tools from 3.01 to ????
* added -n option (don't resolve names) to repquota (Jan Kara)
+* quota tools now correctly handle zero grace times in old format (Jan Kara)
+* edquota, setquota commit just grace times and flags - fixed possible races
+ when used on live filesystem (Jan Kara)
+* another fix to quotastats (Jan Kara)
+* added check to format detection for bad endianity (Jan Kara)
+* implemented conversion of files with bad endianity (Jan Kara)
Changes in quota-tools from 3.01-final to 3.01
diff --git a/convertquota.8 b/convertquota.8
index 34db1b5..ea5b803 100644
--- a/convertquota.8
+++ b/convertquota.8
@@ -6,6 +6,10 @@ convertquota \- convert quota from old file format to new one
.B convertquota
[
.B -ug
+] [
+.B -e
+|
+.B -f
]
.I filesystem
.SH DESCRIPTION
@@ -33,6 +37,12 @@ convert user quota file. This is the default.
.B -g
convert group quota file.
.TP
+.B -f
+convert from old file format to new one. This is the default.
+.TP
+.B -e
+convert new file format from big endian to little endian.
+.TP
.B -V
print version information.
.SH FILES
diff --git a/convertquota.c b/convertquota.c
index f82a6b8..69a14cf 100644
--- a/convertquota.c
+++ b/convertquota.c
@@ -20,15 +20,21 @@
#include "quotasys.h"
#include "quota.h"
#include "bylabel.h"
+#include "quotaio_v2.h"
+#include "dqblk_v2.h"
+
+#define ACT_FORMAT 1 /* Convert format from old to new */
+#define ACT_ENDIAN 2 /* Convert endianity */
char *mntpoint;
char *progname;
int ucv, gcv;
struct quota_handle *qn; /* Handle of new file */
+int action; /* Action to be performed */
static void usage(void)
{
- errstr(_("Utility for converting quota files.\nUsage:\n\t%s [-u] [-g] mountpoint\n"), progname);
+ errstr(_("Utility for converting quota files.\nUsage:\n\t%s [-u] [-g] [-e|-f] mountpoint\n"), progname);
errstr(_("Bugs to %s\n"), MY_EMAIL);
exit(1);
}
@@ -43,8 +49,9 @@ static void parse_options(int argcnt, char **argstr)
else
slash++;
+ action = ACT_FORMAT;
sstrncpy(cmdname, slash, sizeof(cmdname));
- while ((ret = getopt(argcnt, argstr, "Vugh:")) != -1) {
+ while ((ret = getopt(argcnt, argstr, "Vugefh:")) != -1) {
switch (ret) {
case '?':
case 'h':
@@ -58,6 +65,12 @@ static void parse_options(int argcnt, char **argstr)
case 'g':
gcv = 1;
break;
+ case 'e':
+ action = ACT_ENDIAN;
+ break;
+ case 'f':
+ action = ACT_FORMAT;
+ break;
}
}
@@ -72,6 +85,146 @@ static void parse_options(int argcnt, char **argstr)
mntpoint = argstr[optind];
}
+/*
+ * Implementation of endian conversion
+ */
+
+typedef char *dqbuf_t;
+
+#define set_bit(bmp, ind) ((bmp)[(ind) >> 3] |= (1 << ((ind) & 7)))
+#define get_bit(bmp, ind) ((bmp)[(ind) >> 3] & (1 << ((ind) & 7)))
+
+#define getdqbuf() smalloc(V2_DQBLKSIZE)
+#define freedqbuf(buf) free(buf)
+
+static inline void endian_disk2memdqblk(struct util_dqblk *m, struct v2_disk_dqblk *d)
+{
+ m->dqb_ihardlimit = __be32_to_cpu(d->dqb_ihardlimit);
+ m->dqb_isoftlimit = __be32_to_cpu(d->dqb_isoftlimit);
+ m->dqb_bhardlimit = __be32_to_cpu(d->dqb_bhardlimit);
+ m->dqb_bsoftlimit = __be32_to_cpu(d->dqb_bsoftlimit);
+ m->dqb_curinodes = __be32_to_cpu(d->dqb_curinodes);
+ m->dqb_curspace = __be64_to_cpu(d->dqb_curspace);
+ m->dqb_itime = __be64_to_cpu(d->dqb_itime);
+ m->dqb_btime = __be64_to_cpu(d->dqb_btime);
+}
+
+/* Is given dquot empty? */
+static int endian_empty_dquot(struct v2_disk_dqblk *d)
+{
+ static struct v2_disk_dqblk fakedquot;
+
+ return !memcmp(d, &fakedquot, sizeof(fakedquot));
+}
+
+/* Read given block */
+static void read_blk(int fd, uint blk, dqbuf_t buf)
+{
+ int err;
+
+ lseek(fd, blk << V2_DQBLKSIZE_BITS, SEEK_SET);
+ err = read(fd, buf, V2_DQBLKSIZE);
+ if (err < 0)
+ die(2, _("Can't read block %u: %s\n"), blk, strerror(errno));
+ else if (err != V2_DQBLKSIZE)
+ memset(buf + err, 0, V2_DQBLKSIZE - err);
+}
+
+static void endian_report_block(int fd, uint blk, char *bitmap)
+{
+ dqbuf_t buf = getdqbuf();
+ struct v2_disk_dqdbheader *dh;
+ struct v2_disk_dqblk *ddata;
+ struct dquot dquot;
+ int i;
+
+ set_bit(bitmap, blk);
+ read_blk(fd, blk, buf);
+ dh = (struct v2_disk_dqdbheader *)buf;
+ ddata = V2_GETENTRIES(buf);
+ for (i = 0; i < V2_DQSTRINBLK; i++)
+ if (!endian_empty_dquot(ddata + i)) {
+ memset(&dquot, 0, sizeof(dquot));
+ dquot.dq_h = qn;
+ endian_disk2memdqblk(&dquot.dq_dqb, ddata + i);
+ dquot.dq_id = __be32_to_cpu(ddata[i].dqb_id);
+ if (qn->qh_ops->commit_dquot(&dquot, COMMIT_ALL) < 0)
+ errstr(_("Can't commit dquot for id %u: %s\n"),
+ (uint)dquot.dq_id, strerror(errno));
+ }
+ freedqbuf(buf);
+}
+
+static void endian_report_tree(int fd, uint blk, int depth, char *bitmap)
+{
+ int i;
+ dqbuf_t buf = getdqbuf();
+ u_int32_t *ref = (u_int32_t *) buf;
+
+ read_blk(fd, blk, buf);
+ if (depth == V2_DQTREEDEPTH - 1) {
+ for (i = 0; i < V2_DQBLKSIZE >> 2; i++) {
+ blk = __be32_to_cpu(ref[i]);
+ if (blk && !get_bit(bitmap, blk))
+ endian_report_block(fd, blk, bitmap);
+ }
+ }
+ else {
+ for (i = 0; i < V2_DQBLKSIZE >> 2; i++)
+ if ((blk = __be32_to_cpu(ref[i])))
+ endian_report_tree(fd, blk, depth + 1, bitmap);
+ }
+ freedqbuf(buf);
+}
+
+static int endian_scan_structures(int fd, int type)
+{
+ char *bitmap;
+ loff_t blocks = (lseek(fd, 0, SEEK_END) + V2_DQBLKSIZE - 1) >> V2_DQBLKSIZE_BITS;
+
+ bitmap = smalloc((blocks + 7) >> 3);
+ memset(bitmap, 0, (blocks + 7) >> 3);
+ endian_report_tree(fd, V2_DQTREEOFF, 0, bitmap);
+ free(bitmap);
+ return 0;
+}
+
+static int endian_check_header(int fd, int type)
+{
+ struct v2_disk_dqheader head;
+ u_int32_t file_magics[] = INITQMAGICS;
+ u_int32_t known_versions[] = INIT_V2_VERSIONS;
+
+ lseek(fd, 0, SEEK_SET);
+ if (read(fd, &head, sizeof(head)) != sizeof(head)) {
+ errstr(_("Can't read header of old quotafile.\n"));
+ return -1;
+ }
+ if (__be32_to_cpu(head.dqh_magic) != file_magics[type] || __be32_to_cpu(head.dqh_version) > known_versions[type]) {
+ errstr(_("Bad file magic or version (probably not quotafile with bad endianity).\n"));
+ return -1;
+ }
+ return 0;
+}
+
+static int endian_load_info(int fd, int type)
+{
+ struct v2_disk_dqinfo dinfo;
+
+ if (read(fd, &dinfo, sizeof(dinfo)) != sizeof(dinfo)) {
+ errstr(_("Can't read information about old quotafile.\n"));
+ return -1;
+ }
+ qn->qh_info.u.v2_mdqi.dqi_flags = __be32_to_cpu(dinfo.dqi_flags);
+ qn->qh_info.dqi_bgrace = __be32_to_cpu(dinfo.dqi_bgrace);
+ qn->qh_info.dqi_igrace = __be32_to_cpu(dinfo.dqi_igrace);
+ return 0;
+}
+
+/*
+ * End of endian conversion
+ */
+
static int convert_dquot(struct dquot *dquot, char *name)
{
struct dquot newdquot;
@@ -88,18 +241,34 @@ static int convert_dquot(struct dquot *dquot, char *name)
newdquot.dq_dqb.dqb_btime = dquot->dq_dqb.dqb_btime;
newdquot.dq_dqb.dqb_itime = dquot->dq_dqb.dqb_itime;
if (qn->qh_ops->commit_dquot(&newdquot, COMMIT_ALL) < 0) {
- errstr(_("Can't commit dquot for id %u (%s): %s\n"),
- (uint)dquot->dq_id, name, strerror(errno));
+ errstr(_("Can't commit dquot for id %u: %s\n"),
+ (uint)dquot->dq_id, strerror(errno));
return -1;
}
return 0;
}
-static int convert_file(int type, struct mntent *mnt)
+static int rename_file(int type, struct mntent *mnt)
{
- struct quota_handle *qo;
char *qfname, namebuf[PATH_MAX];
int ret = 0;
+
+ qfname = get_qf_name(mnt, type, QF_VFSV0);
+ strcpy(namebuf, qfname);
+ sstrncat(namebuf, ".new", sizeof(namebuf));
+ if (rename(namebuf, qfname) < 0) {
+ errstr(_("Can't rename new quotafile %s to name %s: %s\n"),
+ namebuf, qfname, strerror(errno));
+ ret = -1;
+ }
+ free(qfname);
+ return ret;
+}
+
+static int convert_format(int type, struct mntent *mnt)
+{
+ struct quota_handle *qo;
+ int ret = 0;
if (!(qo = init_io(mnt, type, QF_VFSOLD, 1))) {
errstr(_("Can't open old format file for %ss on %s\n"),
@@ -112,21 +281,64 @@ static int convert_file(int type, struct mntent *mnt)
end_io(qo);
return -1;
}
- if (qo->qh_ops->scan_dquots(qo, convert_dquot) >= 0) { /* Conversion succeeded? */
- qfname = get_qf_name(mnt, type, QF_VFSV0);
- strcpy(namebuf, qfname);
- sstrncat(namebuf, ".new", sizeof(namebuf));
- if (rename(namebuf, qfname) < 0)
- errstr(_("Can't rename new quotafile %s to name %s: %s\n"),
- namebuf, qfname, strerror(errno));
- free(qfname);
+ if (qo->qh_ops->scan_dquots(qo, convert_dquot) >= 0) /* Conversion succeeded? */
+ ret = rename_file(type, mnt);
+ else
ret = -1;
- }
end_io(qo);
end_io(qn);
return ret;
}
+static int convert_endian(int type, struct mntent *mnt)
+{
+ int ret = 0;
+ int ofd;
+ char *qfname;
+
+ if (!(qfname = get_qf_name(mnt, type, QF_VFSV0)))
+ return -1;
+ if ((ofd = open(qfname, O_RDONLY)) < 0) {
+ errstr(_("Can't open old quota file on %s: %s\n"), mnt->mnt_dir, strerror(errno));
+ free(qfname);
+ return -1;
+ }
+ free(qfname);
+ if (endian_check_header(ofd, type) < 0) {
+ close(ofd);
+ return -1;
+ }
+ if (!(qn = new_io(mnt, type, QF_VFSV0))) {
+ errstr(_("Can't create file for %ss for new format on %s: %s\n"),
+ type2name(type), mnt->mnt_dir, strerror(errno));
+ close(ofd);
+ return -1;
+ }
+ if (endian_load_info(ofd, type) < 0) {
+ end_io(qn);
+ close(ofd);
+ return -1;
+ }
+ ret = endian_scan_structures(ofd, type);
+ end_io(qn);
+ if (ret < 0)
+ return ret;
+
+ return rename_file(type, mnt);
+}
+
+static int convert_file(int type, struct mntent *mnt)
+{
+ switch (action) {
+ case ACT_FORMAT:
+ return convert_format(type, mnt);
+ case ACT_ENDIAN:
+ return convert_endian(type, mnt);
+ }
+ errstr(_("Unknown action should be performed.\n"));
+ return -1;
+}
+
int main(int argc, char **argv)
{
struct mntent *mnt;
diff --git a/dqblk_v2.h b/dqblk_v2.h
index 2172c17..c5932b3 100644
--- a/dqblk_v2.h
+++ b/dqblk_v2.h
@@ -15,6 +15,8 @@
#define Q_V2_SETQLIM 0x0700 /* Set only limits */
#define Q_V2_GETINFO 0x0900 /* Get information about quota */
#define Q_V2_SETINFO 0x0A00 /* Set information about quota */
+#define Q_V2_SETGRACE 0x0B00 /* Set just grace times in quotafile information */
+#define Q_V2_SETFLAGS 0x0C00 /* Set just flags in quotafile information */
#define Q_V2_GETSTATS 0x1100 /* get collected stats (before proc was used) */
/* Structure for format specific information */
diff --git a/quotaio.c b/quotaio.c
index bbcbf32..6478ad9 100644
--- a/quotaio.c
+++ b/quotaio.c
@@ -13,6 +13,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
+#include <asm/byteorder.h>
#include "pot.h"
#include "bylabel.h"
@@ -44,9 +45,14 @@ int detect_qf_format(int fd, int type)
if ((ret = read(fd, &head, sizeof(head))) < 0)
die(2, _("Error while reading from quotafile: %s\n"), strerror(errno));
- if (ret != sizeof(head) || head.dqh_magic != file_magics[type]) /* Short file? Probably old format */
+ if (ret != sizeof(head)) /* Short file? Probably old format */
return QF_VFSOLD;
- if (head.dqh_version > known_versions[type]) /* Too new format? */
+ if (__le32_to_cpu(head.dqh_magic) != file_magics[type])
+ if (__be32_to_cpu(head.dqh_magic) == file_magics[type])
+ die(3, _("Your quota file is stored in wrong endianity. Please use convertquota to convert it.\n"));
+ else
+ return QF_VFSOLD;
+ if (__le32_to_cpu(head.dqh_version) > known_versions[type]) /* Too new format? */
return QF_TOONEW;
return QF_VFSV0;
}
@@ -227,8 +233,10 @@ int end_io(struct quota_handle *h)
}
if (h->qh_ops->end_io && h->qh_ops->end_io(h) < 0)
return -1;
- flock(h->qh_fd, LOCK_UN);
- close(h->qh_fd);
+ if (h->qh_fd != -1) {
+ flock(h->qh_fd, LOCK_UN);
+ close(h->qh_fd);
+ }
free(h);
return 0;
}
diff --git a/quotaio_v1.c b/quotaio_v1.c
index 948d244..195534c 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.10 2001/09/27 21:34:58 jkar8572 Exp $"
+#ident "$Id: quotaio_v1.c,v 1.11 2001/11/08 23:56:11 jkar8572 Exp $"
#include <unistd.h>
#include <errno.h>
@@ -149,6 +149,11 @@ static int v1_init_io(struct quota_handle *h)
h->qh_info.dqi_bgrace = ddqblk.dqb_btime;
h->qh_info.dqi_igrace = ddqblk.dqb_itime;
}
+ if (!h->qh_info.dqi_bgrace)
+ h->qh_info.dqi_bgrace = MAX_DQ_TIME;
+ if (!h->qh_info.dqi_igrace)
+ h->qh_info.dqi_igrace = MAX_IQ_TIME;
+
return 0;
}
diff --git a/quotaio_v2.c b/quotaio_v2.c
index 449c751..2bbf699 100644
--- a/quotaio_v2.c
+++ b/quotaio_v2.c
@@ -42,6 +42,12 @@ report: v2_report
#define getdqbuf() smalloc(V2_DQBLKSIZE)
#define freedqbuf(buf) free(buf)
+extern inline void mark_quotafile_metainfo_dirty(struct quota_handle *h)
+{
+ h->qh_info.u.v2_mdqi.dqi_flags |= V2_IOFL_METAINFO_DIRTY;
+ mark_quotafile_info_dirty(h);
+}
+
/*
* Copy dquot from disk to memory
*/
@@ -213,8 +219,15 @@ static int v2_write_info(struct quota_handle *h)
kdqinfo.dqi_blocks = h->qh_info.u.v2_mdqi.dqi_blocks;
kdqinfo.dqi_free_blk = h->qh_info.u.v2_mdqi.dqi_free_blk;
kdqinfo.dqi_free_entry = h->qh_info.u.v2_mdqi.dqi_free_entry;
- if (quotactl(QCMD(Q_V2_SETINFO, h->qh_type), h->qh_quotadev, 0, (void *)&kdqinfo) < 0)
- return -1;
+ if (h->qh_info.u.v2_mdqi.dqi_flags & V2_IOFL_METAINFO_DIRTY) {
+ if (quotactl(QCMD(Q_V2_SETINFO, h->qh_type), h->qh_quotadev, 0, (void *)&kdqinfo) < 0)
+ return -1;
+ }
+ else {
+ if (quotactl(QCMD(Q_V2_SETGRACE, h->qh_type), h->qh_quotadev, 0, (void *)&kdqinfo) < 0 ||
+ quotactl(QCMD(Q_V2_SETFLAGS, h->qh_type), h->qh_quotadev, 0, (void *)&kdqinfo) < 0)
+ return -1;
+ }
}
else {
struct v2_disk_dqinfo ddqinfo;
@@ -276,7 +289,7 @@ static int get_free_dqblk(struct quota_handle *h)
}
blk = info->dqi_blocks++;
}
- mark_quotafile_info_dirty(h);
+ mark_quotafile_metainfo_dirty(h);
freedqbuf(buf);
return blk;
}
@@ -291,7 +304,7 @@ static void put_free_dqblk(struct quota_handle *h, dqbuf_t buf, uint blk)
dh->dqdh_prev_free = __cpu_to_le32(0);
dh->dqdh_entries = __cpu_to_le16(0);
info->dqi_free_blk = blk;
- mark_quotafile_info_dirty(h);
+ mark_quotafile_metainfo_dirty(h);
write_blk(h, blk, buf);
}
@@ -316,7 +329,7 @@ static void remove_free_dqentry(struct quota_handle *h, dqbuf_t buf, uint blk)
}
else {
h->qh_info.u.v2_mdqi.dqi_free_entry = nextblk;
- mark_quotafile_info_dirty(h);
+ mark_quotafile_metainfo_dirty(h);
}
freedqbuf(tmpbuf);
dh->dqdh_next_free = dh->dqdh_prev_free = __cpu_to_le32(0);
@@ -340,7 +353,7 @@ static void insert_free_dqentry(struct quota_handle *h, dqbuf_t buf, uint blk)
}
freedqbuf(tmpbuf);
info->dqi_free_entry = blk;
- mark_quotafile_info_dirty(h);
+ mark_quotafile_metainfo_dirty(h);
}
/* Find space for dquot */
@@ -369,7 +382,7 @@ static uint find_free_dqentry(struct quota_handle *h, struct dquot *dquot, int *
}
memset(buf, 0, V2_DQBLKSIZE);
info->dqi_free_entry = blk;
- mark_quotafile_info_dirty(h);
+ mark_quotafile_metainfo_dirty(h);
}
if (__le16_to_cpu(dh->dqdh_entries) + 1 >= V2_DQSTRINBLK) /* Block will be full? */
remove_free_dqentry(h, buf, blk);
diff --git a/quotaio_v2.h b/quotaio_v2.h
index 2482156..bb3a000 100644
--- a/quotaio_v2.h
+++ b/quotaio_v2.h
@@ -20,6 +20,8 @@
#define V2_GETENTRIES(buf) ((struct v2_disk_dqblk *)(((char *)(buf)) + sizeof(struct v2_disk_dqdbheader)))
#define INIT_V2_VERSIONS { 0, 0}
+#define V2_IOFL_METAINFO_DIRTY 0x100 /* Is dirty also metadata information in info? */
+
struct v2_disk_dqheader {
u_int32_t dqh_magic; /* Magic number identifying file */
u_int32_t dqh_version; /* File version */
diff --git a/quotastats.c b/quotastats.c
index 9e412be..1879b6d 100644
--- a/quotastats.c
+++ b/quotastats.c
@@ -10,7 +10,7 @@
*
* Author: Marco van Wieringen <mvw@planets.elm.net>
*
- * Version: $Id: quotastats.c,v 1.6 2001/10/12 13:38:56 jkar8572 Exp $
+ * Version: $Id: quotastats.c,v 1.7 2001/11/08 23:56:11 jkar8572 Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -59,13 +59,14 @@ static inline int get_stats(struct util_dqstats *dqstats)
goto out;
}
}
- else if (quotactl(QCMD(Q_V1_GETSTATS, 0), NULL, 0, (caddr_t)&old_dqstats) >= 0) {
+ else if (quotactl(QCMD(Q_V1_GETSTATS, 0), "/dev/null", 0, (caddr_t)&old_dqstats) >= 0) {
/* Structures are currently the same */
memcpy(dqstats, &old_dqstats, sizeof(old_dqstats));
dqstats->version = 0;
}
else {
- if (errno != EINVAL) {
+ /* Sadly these all are possible to get from kernel :( */
+ if (errno != EINVAL && errno != ENOTBLK && errno != EPERM) {
errstr(_("Error while getting quota statistics from kernel: %s\n"), strerror(errno));
goto out;
}
diff --git a/quotasys.c b/quotasys.c
index 2147f52..6f579b7 100644
--- a/quotasys.c
+++ b/quotasys.c
@@ -292,8 +292,6 @@ static int hasxfsquota(struct mntent *mnt, int type)
*/
int hasquota(struct mntent *mnt, int type)
{
- char *option;
-
if (!CORRECT_FSTYPE(mnt->mnt_type))
return 0;
@@ -302,11 +300,11 @@ int hasquota(struct mntent *mnt, int type)
if (!strcmp(mnt->mnt_type, MNTTYPE_NFS)) /* NFS always has quota or better there is no good way how to detect it */
return 1;
- if ((type == USRQUOTA) && (option = hasmntopt(mnt, MNTOPT_USRQUOTA)))
+ if ((type == USRQUOTA) && hasmntopt(mnt, MNTOPT_USRQUOTA))
return 1;
- if ((type == GRPQUOTA) && (option = hasmntopt(mnt, MNTOPT_GRPQUOTA)))
+ if ((type == GRPQUOTA) && hasmntopt(mnt, MNTOPT_GRPQUOTA))
return 1;
- if ((type == USRQUOTA) && (option = hasmntopt(mnt, MNTOPT_QUOTA)))
+ if ((type == USRQUOTA) && hasmntopt(mnt, MNTOPT_QUOTA))
return 1;
return 0;
}
@@ -757,15 +755,16 @@ static int find_next_entry_all(int *pos)
{
struct mntent mnt;
-restart:
- if (++act_checked == mnt_entries_cnt)
+ while (++act_checked < mnt_entries_cnt) {
+ mnt.mnt_fsname = (char *)mnt_entries[act_checked].me_devname;
+ mnt.mnt_type = mnt_entries[act_checked].me_type;
+ mnt.mnt_opts = mnt_entries[act_checked].me_opts;
+ mnt.mnt_dir = (char *)mnt_entries[act_checked].me_dir;
+ if (!hasmntopt(&mnt, MNTOPT_NOAUTO))
+ break;
+ }
+ if (act_checked >= mnt_entries_cnt)
return 0;
- mnt.mnt_fsname = (char *)mnt_entries[act_checked].me_devname;
- mnt.mnt_type = mnt_entries[act_checked].me_type;
- mnt.mnt_opts = mnt_entries[act_checked].me_opts;
- mnt.mnt_dir = (char *)mnt_entries[act_checked].me_dir;
- if (hasmntopt(&mnt, MNTOPT_NOAUTO))
- goto restart;
*pos = act_checked;
return 1;
}