summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--convertquota.c2
-rw-r--r--quotaio.c24
-rw-r--r--quotaio_generic.c63
-rw-r--r--quotaio_generic.h6
-rw-r--r--quotaio_meta.c6
-rw-r--r--quotaio_xfs.c68
-rw-r--r--quotasys.h2
-rw-r--r--repquota.c4
-rw-r--r--warnquota.c4
9 files changed, 104 insertions, 75 deletions
diff --git a/convertquota.c b/convertquota.c
index ab16193..1e40804 100644
--- a/convertquota.c
+++ b/convertquota.c
@@ -312,7 +312,7 @@ static int convert_format(int type, struct mntent *mnt)
struct quota_handle *qo;
int ret = 0;
- if (!(qo = init_io(mnt, type, infmt, IOI_OPENFILE))) {
+ if (!(qo = init_io(mnt, type, infmt, IOI_INITSCAN))) {
errstr(_("Cannot open old format file for %ss on %s\n"),
type2name(type), mnt->mnt_dir);
return -1;
diff --git a/quotaio.c b/quotaio.c
index 21881fc..bf0de85 100644
--- a/quotaio.c
+++ b/quotaio.c
@@ -43,6 +43,7 @@ struct quota_handle *init_io(struct mntent *mnt, int type, int fmt, int flags)
int fd = -1, kernfmt;
struct quota_handle *h = smalloc(sizeof(struct quota_handle));
const char *mnt_fsname = NULL;
+ int nameflag;
if (!hasquota(mnt, type, 0))
goto out_handle;
@@ -110,44 +111,33 @@ struct quota_handle *init_io(struct mntent *mnt, int type, int fmt, int flags)
errstr(_("Quota not supported by the filesystem.\n"));
goto out_handle;
}
- if (flags & IOI_OPENFILE) {
- errstr(_("Operation not supported for filesystems with hidden quota files!\n"));
- goto out_handle;
- }
h->qh_fd = -1;
h->qh_fmt = fmt;
goto set_ops;
}
+ nameflag = (!QIO_ENABLED(h) || flags & IOI_INITSCAN) ? NF_FORMAT : 0;
if (fmt == -1) {
/* Let's try any VFSv0 quota format... */
- if (get_qf_name(mnt, type, QF_VFSV0,
- (!QIO_ENABLED(h) || flags & IOI_OPENFILE) ? NF_FORMAT : 0,
- &qfname) >= 0)
+ if (get_qf_name(mnt, type, QF_VFSV0, nameflag, &qfname) >= 0)
fmt = QF_VFSV0;
/* And then VFSv1 quota format... */
- else if (get_qf_name(mnt, type, QF_VFSV1,
- (!QIO_ENABLED(h) || flags & IOI_OPENFILE) ? NF_FORMAT : 0,
- &qfname) >= 0)
+ else if (get_qf_name(mnt, type, QF_VFSV1, nameflag, &qfname) >= 0)
fmt = QF_VFSV1;
/* And then old quota format... */
- else if (get_qf_name(mnt, type, QF_VFSOLD,
- (!QIO_ENABLED(h) || flags & IOI_OPENFILE) ? NF_FORMAT : 0,
- &qfname) >= 0)
+ else if (get_qf_name(mnt, type, QF_VFSOLD, nameflag, &qfname) >= 0)
fmt = QF_VFSOLD;
else { /* Don't know... */
errstr(_("Cannot find any quota file to work on.\n"));
goto out_handle;
}
} else {
- if (get_qf_name(mnt, type, fmt,
- (!QIO_ENABLED(h) || flags & IOI_OPENFILE) ? NF_FORMAT : 0,
- &qfname) < 0) {
+ if (get_qf_name(mnt, type, fmt, nameflag, &qfname) < 0) {
errstr(_("Quota file not found or has wrong format.\n"));
goto out_handle;
}
}
- if (!QIO_ENABLED(h) || flags & IOI_OPENFILE) { /* Need to open file? */
+ if (!QIO_ENABLED(h) || flags & IOI_INITSCAN) { /* Need to open file? */
if (QIO_ENABLED(h)) { /* Kernel uses same file? */
unsigned int cmd =
(kernel_iface == IFACE_GENERIC) ? Q_SYNC : Q_6_5_SYNC;
diff --git a/quotaio_generic.c b/quotaio_generic.c
index e5df683..5001a56 100644
--- a/quotaio_generic.c
+++ b/quotaio_generic.c
@@ -8,6 +8,9 @@
#include <errno.h>
#include <string.h>
+#include <pwd.h>
+#include <grp.h>
+#include <stdlib.h>
#include <sys/types.h>
#include "pot.h"
@@ -98,3 +101,63 @@ int vfs_set_dquot(struct dquot *dquot, int flags)
}
return 0;
}
+
+static int scan_one_dquot(struct dquot *dquot, int (*get_dquot)(struct dquot *))
+{
+ int ret;
+ struct util_dqblk *dqb = &dquot->dq_dqb;
+
+ memset(dqb, 0, sizeof(struct util_dqblk));
+ ret = get_dquot(dquot);
+ if (ret < 0)
+ return ret;
+ if (!dqb->dqb_bhardlimit && !dqb->dqb_bsoftlimit && !dqb->dqb_ihardlimit && !dqb->dqb_isoftlimit && !dqb->dqb_curinodes && !dqb->dqb_curspace)
+ return 1;
+ return 0;
+}
+
+/* Generic quota scanning using passwd... */
+int generic_scan_dquots(struct quota_handle *h,
+ int (*process_dquot)(struct dquot *dquot, char *dqname),
+ int (*get_dquot)(struct dquot *dquot))
+{
+ struct dquot *dquot = get_empty_dquot();
+ int ret = 0;
+
+ dquot->dq_h = h;
+ if (h->qh_type == USRQUOTA) {
+ struct passwd *usr;
+
+ setpwent();
+ while ((usr = getpwent()) != NULL) {
+ dquot->dq_id = usr->pw_uid;
+ ret = scan_one_dquot(dquot, get_dquot);
+ if (ret < 0)
+ break;
+ if (ret > 0)
+ continue;
+ ret = process_dquot(dquot, usr->pw_name);
+ if (ret < 0)
+ break;
+ }
+ endpwent();
+ } else if (h->qh_type == GRPQUOTA) {
+ struct group *grp;
+
+ setgrent();
+ while ((grp = getgrent()) != NULL) {
+ dquot->dq_id = grp->gr_gid;
+ ret = scan_one_dquot(dquot, get_dquot);
+ if (ret < 0)
+ break;
+ if (ret > 0)
+ continue;
+ ret = process_dquot(dquot, grp->gr_name);
+ if (ret < 0)
+ break;
+ }
+ endgrent();
+ }
+ free(dquot);
+ return ret;
+}
diff --git a/quotaio_generic.h b/quotaio_generic.h
index 422fb52..5edc11c 100644
--- a/quotaio_generic.h
+++ b/quotaio_generic.h
@@ -21,4 +21,10 @@ int vfs_get_dquot(struct dquot *dquot);
/* Set dquot in kernel */
int vfs_set_dquot(struct dquot *dquot, int flags);
+/* Generic routine for scanning dquots when quota format does not have
+ * better way */
+int generic_scan_dquots(struct quota_handle *h,
+ int (*process_dquot)(struct dquot *dquot, char *dqname),
+ int (*get_dquot)(struct dquot *dquot));
+
#endif
diff --git a/quotaio_meta.c b/quotaio_meta.c
index f1f714f..e52b4f4 100644
--- a/quotaio_meta.c
+++ b/quotaio_meta.c
@@ -53,9 +53,15 @@ static int meta_commit_dquot(struct dquot *dquot, int flags)
return vfs_set_dquot(dquot, flags);
}
+static int meta_scan_dquots(struct quota_handle *h, int (*process_dquot)(struct dquot *dquot, char *dqname))
+{
+ return generic_scan_dquots(h, process_dquot, vfs_get_dquot);
+}
+
struct quotafile_ops quotafile_ops_meta = {
init_io: meta_init_io,
write_info: meta_write_info,
read_dquot: meta_read_dquot,
commit_dquot: meta_commit_dquot,
+scan_dquots: meta_scan_dquots,
};
diff --git a/quotaio_xfs.c b/quotaio_xfs.c
index 62075b5..2e879e6 100644
--- a/quotaio_xfs.c
+++ b/quotaio_xfs.c
@@ -10,8 +10,6 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
-#include <pwd.h>
-#include <grp.h>
#include "pot.h"
#include "common.h"
@@ -19,6 +17,7 @@
#include "quotaio.h"
#include "quotasys.h"
#include "dqblk_xfs.h"
+#include "quotaio_generic.h"
#define XFS_USRQUOTA(h) ((h)->qh_type == USRQUOTA && \
(h)->qh_info.u.xfs_mdqi.qs_flags & XFS_QUOTA_UDQ_ACCT)
@@ -175,24 +174,21 @@ static int xfs_commit_dquot(struct dquot *dquot, int flags)
/*
* xfs_scan_dquots helper - processes a single dquot
*/
-static int xfs_scan_dquot(struct quota_handle *h,
- struct xfs_kern_dqblk *d,
- char *name, struct dquot *dq,
- int (*process_dquot) (struct dquot *dquot, char *dqname))
+static int xfs_get_dquot(struct dquot *dq)
{
- int qcmd = QCMD(Q_XFS_GETQUOTA, h->qh_type);
-
- memset(d, 0, sizeof(struct xfs_kern_dqblk));
-
- if (quotactl(qcmd, h->qh_quotadev, dq->dq_id, (void *)d) < 0) {
- return 0;
+ struct xfs_kern_dqblk d;
+ int qcmd = QCMD(Q_XFS_GETQUOTA, dq->dq_h->qh_type);
+ int ret;
+
+ memset(&d, 0, sizeof(d));
+ ret = quotactl(qcmd, dq->dq_h->qh_quotadev, dq->dq_id, (void *)&d);
+ if (ret < 0) {
+ if (ret == -ENOENT)
+ return 0;
+ return ret;
}
- if (d->d_blk_hardlimit == 0 &&
- d->d_blk_softlimit == 0 &&
- d->d_ino_hardlimit == 0 &&
- d->d_ino_softlimit == 0 && d->d_bcount == 0 && d->d_icount == 0) return 0;
- xfs_kern2utildqblk(&dq->dq_dqb, d);
- return process_dquot(dq, name);
+ xfs_kern2utildqblk(&dq->dq_dqb, &d);
+ return 0;
}
/*
@@ -200,42 +196,10 @@ static int xfs_scan_dquot(struct quota_handle *h,
*/
static int xfs_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct dquot *dquot, char *dqname))
{
- struct dquot *dq;
- struct xfs_kern_dqblk d;
- int rd = 0;
-
if (!XFS_USRQUOTA(h) && !XFS_GRPQUOTA(h))
- return rd;
-
- dq = get_empty_dquot();
- dq->dq_h = h;
- if (h->qh_type == USRQUOTA) {
- struct passwd *usr;
-
- setpwent();
- while ((usr = getpwent()) != NULL) {
- dq->dq_id = usr->pw_uid;
- rd = xfs_scan_dquot(h, &d, usr->pw_name, dq, process_dquot);
- if (rd < 0)
- break;
- }
- endpwent();
- }
- else { /* GRPQUOTA */
- struct group *grp;
-
- setgrent();
- while ((grp = getgrent()) != NULL) {
- dq->dq_id = grp->gr_gid;
- rd = xfs_scan_dquot(h, &d, grp->gr_name, dq, process_dquot);
- if (rd < 0)
- break;
- }
- endgrent();
- }
+ return 0;
- free(dq);
- return rd;
+ return generic_scan_dquots(h, process_dquot, xfs_get_dquot);
}
/*
diff --git a/quotasys.h b/quotasys.h
index 90e5aae..005b275 100644
--- a/quotasys.h
+++ b/quotasys.h
@@ -20,7 +20,7 @@
/* Flags for IO initialization */
#define IOI_READONLY 0x1 /* Only readonly access */
-#define IOI_OPENFILE 0x2 /* Open file even if kernel has quotas turned on */
+#define IOI_INITSCAN 0x2 /* Prepare handle for scanning dquots */
#define IOI_NFS_MIXED_PATHS 0x4 /* Trim leading / from NFSv4 mountpoints */
#define KERN_KNOWN_QUOTA_VERSION (6*10000 + 5*100 + 1)
diff --git a/repquota.c b/repquota.c
index f781f0d..17dd9e4 100644
--- a/repquota.c
+++ b/repquota.c
@@ -317,9 +317,9 @@ static void report(int type)
int i;
if (flags & FL_ALL)
- handles = create_handle_list(0, NULL, type, fmt, IOI_READONLY | IOI_OPENFILE, MS_LOCALONLY | (flags & FL_NOAUTOFS ? MS_NO_AUTOFS : 0));
+ handles = create_handle_list(0, NULL, type, fmt, IOI_READONLY | IOI_INITSCAN, MS_LOCALONLY | (flags & FL_NOAUTOFS ? MS_NO_AUTOFS : 0));
else
- handles = create_handle_list(mntcnt, mnt, type, fmt, IOI_READONLY | IOI_OPENFILE, MS_LOCALONLY | (flags & FL_NOAUTOFS ? MS_NO_AUTOFS : 0));
+ handles = create_handle_list(mntcnt, mnt, type, fmt, IOI_READONLY | IOI_INITSCAN, MS_LOCALONLY | (flags & FL_NOAUTOFS ? MS_NO_AUTOFS : 0));
for (i = 0; handles[i]; i++)
report_it(handles[i], type);
dispose_handle_list(handles);
diff --git a/warnquota.c b/warnquota.c
index 9f09fcd..2ca286f 100644
--- a/warnquota.c
+++ b/warnquota.c
@@ -951,7 +951,7 @@ static void warn_quota(void)
wc_exit(1);
if (flags & FL_USER) {
- handles = create_handle_list(0, NULL, USRQUOTA, -1, IOI_READONLY | IOI_OPENFILE, MS_LOCALONLY | (flags & FL_NOAUTOFS ? MS_NO_AUTOFS : 0));
+ handles = create_handle_list(0, NULL, USRQUOTA, -1, IOI_READONLY | IOI_INITSCAN, MS_LOCALONLY | (flags & FL_NOAUTOFS ? MS_NO_AUTOFS : 0));
if (!maildev[0] || !strcasecmp(maildev, "any"))
maildev_handle = NULL;
else
@@ -963,7 +963,7 @@ static void warn_quota(void)
if (flags & FL_GROUP) {
if (get_groupadmins() < 0)
wc_exit(1);
- handles = create_handle_list(0, NULL, GRPQUOTA, -1, IOI_READONLY | IOI_OPENFILE, MS_LOCALONLY | (flags & FL_NOAUTOFS ? MS_NO_AUTOFS : 0));
+ handles = create_handle_list(0, NULL, GRPQUOTA, -1, IOI_READONLY | IOI_INITSCAN, MS_LOCALONLY | (flags & FL_NOAUTOFS ? MS_NO_AUTOFS : 0));
if (!maildev[0] || !strcasecmp(maildev, "any"))
maildev_handle = NULL;
else