Module Name: src
Committed By: dholland
Date: Wed Jan 25 17:43:37 UTC 2012
Modified Files:
src/lib/libquota: quota_cursor.c quota_delete.c quota_get.c
quota_oldfiles.c quota_open.c quota_put.c quota_schema.c quotapvt.h
Log Message:
Improve how quota_open() works and generally improve function
dispatching. Allow access to the quota files via the oldfiles code if
quotaon hasn't run yet. Change the latter so it calls getfsent() up
front (and only once) to make it easier to avoid whacking caller
state.
To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/lib/libquota/quota_cursor.c \
src/lib/libquota/quota_get.c src/lib/libquota/quota_schema.c
cvs rdiff -u -r1.2 -r1.3 src/lib/libquota/quota_delete.c \
src/lib/libquota/quota_oldfiles.c src/lib/libquota/quota_put.c
cvs rdiff -u -r1.4 -r1.5 src/lib/libquota/quota_open.c
cvs rdiff -u -r1.9 -r1.10 src/lib/libquota/quotapvt.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libquota/quota_cursor.c
diff -u src/lib/libquota/quota_cursor.c:1.3 src/lib/libquota/quota_cursor.c:1.4
--- src/lib/libquota/quota_cursor.c:1.3 Mon Jan 9 15:41:58 2012
+++ src/lib/libquota/quota_cursor.c Wed Jan 25 17:43:37 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: quota_cursor.c,v 1.3 2012/01/09 15:41:58 dholland Exp $ */
+/* $NetBSD: quota_cursor.c,v 1.4 2012/01/25 17:43:37 dholland Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: quota_cursor.c,v 1.3 2012/01/09 15:41:58 dholland Exp $");
+__RCSID("$NetBSD: quota_cursor.c,v 1.4 2012/01/25 17:43:37 dholland Exp $");
#include <stdlib.h>
#include <errno.h>
@@ -44,20 +44,31 @@ quota_opencursor(struct quotahandle *qh)
int8_t version;
int serrno;
- if (qh->qh_isnfs) {
+ switch (qh->qh_mode) {
+ case QUOTA_MODE_NFS:
errno = EOPNOTSUPP;
return NULL;
- }
- if (__quota_proplib_getversion(qh, &version)) {
- return NULL;
+ case QUOTA_MODE_PROPLIB:
+ if (__quota_proplib_getversion(qh, &version)) {
+ return NULL;
+ }
+ break;
+
+ case QUOTA_MODE_OLDFILES:
+ version = 1;
+ break;
+
+ default:
+ errno = EINVAL;
+ break;
}
/*
* For the time being at least the version 1 kernel code
* cannot do cursors.
*/
- if (version == 1 && !qh->qh_hasoldfiles) {
+ if (version == 1 && !qh->qh_oldfilesopen) {
if (__quota_oldfiles_initialize(qh)) {
return NULL;
}
Index: src/lib/libquota/quota_get.c
diff -u src/lib/libquota/quota_get.c:1.3 src/lib/libquota/quota_get.c:1.4
--- src/lib/libquota/quota_get.c:1.3 Mon Jan 9 15:29:55 2012
+++ src/lib/libquota/quota_get.c Wed Jan 25 17:43:37 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: quota_get.c,v 1.3 2012/01/09 15:29:55 dholland Exp $ */
+/* $NetBSD: quota_get.c,v 1.4 2012/01/25 17:43:37 dholland Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -29,7 +29,9 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: quota_get.c,v 1.3 2012/01/09 15:29:55 dholland Exp $");
+__RCSID("$NetBSD: quota_get.c,v 1.4 2012/01/25 17:43:37 dholland Exp $");
+
+#include <errno.h>
#include <quota.h>
#include "quotapvt.h"
@@ -47,9 +49,19 @@ quotaval_clear(struct quotaval *qv)
int
quota_get(struct quotahandle *qh, const struct quotakey *qk, struct quotaval *qv)
{
- if (qh->qh_isnfs) {
+ switch (qh->qh_mode) {
+ case QUOTA_MODE_NFS:
return __quota_nfs_get(qh, qk, qv);
- } else {
+
+ case QUOTA_MODE_PROPLIB:
return __quota_proplib_get(qh, qk, qv);
+
+ case QUOTA_MODE_OLDFILES:
+ return __quota_oldfiles_get(qh, qk, qv);
+
+ default:
+ break;
}
+ errno = EINVAL;
+ return -1;
}
Index: src/lib/libquota/quota_schema.c
diff -u src/lib/libquota/quota_schema.c:1.3 src/lib/libquota/quota_schema.c:1.4
--- src/lib/libquota/quota_schema.c:1.3 Wed Jan 25 01:22:57 2012
+++ src/lib/libquota/quota_schema.c Wed Jan 25 17:43:37 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: quota_schema.c,v 1.3 2012/01/25 01:22:57 dholland Exp $ */
+/* $NetBSD: quota_schema.c,v 1.4 2012/01/25 17:43:37 dholland Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: quota_schema.c,v 1.3 2012/01/25 01:22:57 dholland Exp $");
+__RCSID("$NetBSD: quota_schema.c,v 1.4 2012/01/25 17:43:37 dholland Exp $");
#include <sys/types.h>
#include <sys/statvfs.h>
@@ -47,45 +47,132 @@ __RCSID("$NetBSD: quota_schema.c,v 1.3 2
const char *
quota_getimplname(struct quotahandle *qh)
{
- if (qh->qh_isnfs) {
+ switch (qh->qh_mode) {
+ case QUOTA_MODE_NFS:
/* XXX this should maybe report the rquotad protocol version */
return "nfs via rquotad";
- } else {
+
+ case QUOTA_MODE_PROPLIB:
+ return __quota_proplib_getimplname(qh);
+
+ case QUOTA_MODE_OLDFILES:
return __quota_proplib_getimplname(qh);
+
+ default:
+ break;
}
+ errno = EINVAL;
+ return NULL;
}
/* ARGSUSED */
unsigned
quota_getnumidtypes(struct quotahandle *qh)
{
- return __quota_proplib_getnumidtypes();
+ switch (qh->qh_mode) {
+ case QUOTA_MODE_NFS:
+ /* XXX for old rquotad versions this should be 1... */
+ return 2;
+
+ case QUOTA_MODE_PROPLIB:
+ return __quota_proplib_getnumidtypes();
+
+ case QUOTA_MODE_OLDFILES:
+ default:
+ break;
+ }
+ return 2;
}
/* ARGSUSED */
const char *
quota_idtype_getname(struct quotahandle *qh, int idtype)
{
- return __quota_proplib_idtype_getname(idtype);
+ switch (qh->qh_mode) {
+ case QUOTA_MODE_PROPLIB:
+ return __quota_proplib_idtype_getname(idtype);
+
+ case QUOTA_MODE_NFS:
+ case QUOTA_MODE_OLDFILES:
+ break;
+ }
+
+ switch (idtype) {
+ case QUOTA_IDTYPE_USER:
+ return "user";
+
+ case QUOTA_IDTYPE_GROUP:
+ return "group";
+
+ default:
+ break;
+ }
+ errno = EINVAL;
+ return "???";
}
/* ARGSUSED */
unsigned
quota_getnumobjtypes(struct quotahandle *qh)
{
- return __quota_proplib_getnumobjtypes();
+ switch (qh->qh_mode) {
+ case QUOTA_MODE_PROPLIB:
+ return __quota_proplib_getnumobjtypes();
+
+ case QUOTA_MODE_NFS:
+ case QUOTA_MODE_OLDFILES:
+ default:
+ break;
+ }
+ return 2;
}
/* ARGSUSED */
const char *
quota_objtype_getname(struct quotahandle *qh, int objtype)
{
- return __quota_proplib_objtype_getname(objtype);
+ switch (qh->qh_mode) {
+ case QUOTA_MODE_PROPLIB:
+ return __quota_proplib_objtype_getname(objtype);
+ case QUOTA_MODE_NFS:
+ case QUOTA_MODE_OLDFILES:
+ default:
+ break;
+ }
+
+ switch (objtype) {
+ case QUOTA_OBJTYPE_BLOCKS:
+ return "block";
+ case QUOTA_OBJTYPE_FILES:
+ return "file";
+ default:
+ break;
+ }
+ errno = EINVAL;
+ return "???"; /* ? */
}
/* ARGSUSED */
int
quota_objtype_isbytes(struct quotahandle *qh, int objtype)
{
- return __quota_proplib_objtype_isbytes(objtype);
+ switch (qh->qh_mode) {
+ case QUOTA_MODE_PROPLIB:
+ return __quota_proplib_objtype_isbytes(objtype);
+ case QUOTA_MODE_NFS:
+ case QUOTA_MODE_OLDFILES:
+ default:
+ break;
+ }
+
+ switch (objtype) {
+ case QUOTA_OBJTYPE_BLOCKS:
+ return 1;
+ case QUOTA_OBJTYPE_FILES:
+ return 0;
+ default:
+ break;
+ }
+ errno = EINVAL;
+ return 0; /* ? */
}
Index: src/lib/libquota/quota_delete.c
diff -u src/lib/libquota/quota_delete.c:1.2 src/lib/libquota/quota_delete.c:1.3
--- src/lib/libquota/quota_delete.c:1.2 Mon Jan 9 15:43:19 2012
+++ src/lib/libquota/quota_delete.c Wed Jan 25 17:43:37 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: quota_delete.c,v 1.2 2012/01/09 15:43:19 dholland Exp $ */
+/* $NetBSD: quota_delete.c,v 1.3 2012/01/25 17:43:37 dholland Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: quota_delete.c,v 1.2 2012/01/09 15:43:19 dholland Exp $");
+__RCSID("$NetBSD: quota_delete.c,v 1.3 2012/01/25 17:43:37 dholland Exp $");
#include <errno.h>
@@ -39,10 +39,20 @@ __RCSID("$NetBSD: quota_delete.c,v 1.2 2
int
quota_delete(struct quotahandle *qh, const struct quotakey *qk)
{
- if (qh->qh_isnfs) {
+ switch (qh->qh_mode) {
+ case QUOTA_MODE_NFS:
errno = EOPNOTSUPP;
return -1;
- } else {
+
+ case QUOTA_MODE_PROPLIB:
return __quota_proplib_delete(qh, qk);
+
+ case QUOTA_MODE_OLDFILES:
+ return __quota_oldfiles_delete(qh, qk);
+
+ default:
+ break;
}
+ errno = EINVAL;
+ return -1;
}
Index: src/lib/libquota/quota_oldfiles.c
diff -u src/lib/libquota/quota_oldfiles.c:1.2 src/lib/libquota/quota_oldfiles.c:1.3
--- src/lib/libquota/quota_oldfiles.c:1.2 Mon Jan 9 15:45:19 2012
+++ src/lib/libquota/quota_oldfiles.c Wed Jan 25 17:43:37 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: quota_oldfiles.c,v 1.2 2012/01/09 15:45:19 dholland Exp $ */
+/* $NetBSD: quota_oldfiles.c,v 1.3 2012/01/25 17:43:37 dholland Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
@@ -49,6 +49,14 @@
#include <quota.h>
#include "quotapvt.h"
+struct oldfiles_fstabentry {
+ char *ofe_mountpoint;
+ int ofe_hasuserquota;
+ int ofe_hasgroupquota;
+ char *ofe_userquotafile;
+ char *ofe_groupquotafile;
+};
+
struct oldfiles_quotacursor {
unsigned oqc_doingusers;
unsigned oqc_doinggroups;
@@ -63,6 +71,172 @@ struct oldfiles_quotacursor {
unsigned oqc_didblocks;
};
+static struct oldfiles_fstabentry *__quota_oldfiles_fstab;
+static unsigned __quota_oldfiles_numfstab;
+static unsigned __quota_oldfiles_maxfstab;
+static int __quota_oldfiles_fstab_loaded;
+
+static const struct oldfiles_fstabentry *
+__quota_oldfiles_find_fstabentry(const char *mountpoint)
+{
+ unsigned i;
+
+ for (i = 0; i < __quota_oldfiles_numfstab; i++) {
+ if (!strcmp(mountpoint,
+ __quota_oldfiles_fstab[i].ofe_mountpoint)) {
+ return &__quota_oldfiles_fstab[i];
+ }
+ }
+ return NULL;
+}
+
+static int
+__quota_oldfiles_add_fstabentry(struct oldfiles_fstabentry *ofe)
+{
+ unsigned newmax;
+ struct oldfiles_fstabentry *newptr;
+
+ if (__quota_oldfiles_numfstab + 1 >= __quota_oldfiles_maxfstab) {
+ if (__quota_oldfiles_maxfstab == 0) {
+ newmax = 4;
+ } else {
+ newmax = __quota_oldfiles_maxfstab * 2;
+ }
+ newptr = realloc(__quota_oldfiles_fstab,
+ newmax * sizeof(__quota_oldfiles_fstab[0]));
+ if (newptr == NULL) {
+ return -1;
+ }
+ __quota_oldfiles_maxfstab = newmax;
+ __quota_oldfiles_fstab = newptr;
+ }
+
+ __quota_oldfiles_fstab[__quota_oldfiles_numfstab++] = *ofe;
+ return 0;
+}
+
+static int
+__quota_oldfiles_fill_fstabentry(const struct fstab *fs,
+ struct oldfiles_fstabentry *ofe)
+{
+ char buf[sizeof(fs->fs_mntops)];
+ char *opt, *state, *s;
+ int serrno;
+ int ret = 0;
+
+ /*
+ * Inspect the mount options to find the quota files.
+ * XXX this info should be gotten from the kernel.
+ *
+ * The options are:
+ * userquota[=path] enable user quotas
+ * groupquota[=path] enable group quotas
+ */
+
+ ofe->ofe_mountpoint = NULL;
+ ofe->ofe_hasuserquota = ofe->ofe_hasgroupquota = 0;
+ ofe->ofe_userquotafile = ofe->ofe_groupquotafile = NULL;
+
+ strlcpy(buf, fs->fs_mntops, sizeof(buf));
+ for (opt = strtok_r(buf, ",", &state);
+ opt != NULL;
+ opt = strtok_r(NULL, ",", &state)) {
+ s = strchr(opt, '=');
+ if (s != NULL) {
+ *(s++) = '\0';
+ }
+ if (!strcmp(opt, "userquota")) {
+ ret = 1;
+ ofe->ofe_hasuserquota = 1;
+ if (s != NULL) {
+ ofe->ofe_userquotafile = strdup(s);
+ if (ofe->ofe_userquotafile == NULL) {
+ goto fail;
+ }
+ }
+ } else if (!strcmp(opt, "groupquota")) {
+ ret = 1;
+ ofe->ofe_hasgroupquota = 1;
+ if (s != NULL) {
+ ofe->ofe_groupquotafile = strdup(s);
+ if (ofe->ofe_groupquotafile == NULL) {
+ goto fail;
+ }
+ }
+ }
+ }
+
+ if (ret == 1) {
+ ofe->ofe_mountpoint = strdup(fs->fs_file);
+ if (ofe->ofe_mountpoint == NULL) {
+ goto fail;
+ }
+ }
+
+ return ret;
+
+fail:
+ serrno = errno;
+ if (ofe->ofe_mountpoint != NULL) {
+ free(ofe->ofe_mountpoint);
+ }
+ if (ofe->ofe_groupquotafile != NULL) {
+ free(ofe->ofe_groupquotafile);
+ }
+ if (ofe->ofe_userquotafile != NULL) {
+ free(ofe->ofe_userquotafile);
+ }
+ errno = serrno;
+ return -1;
+}
+
+void
+__quota_oldfiles_load_fstab(void)
+{
+ struct oldfiles_fstabentry ofe;
+ struct fstab *fs;
+ int result;
+
+ if (__quota_oldfiles_fstab_loaded) {
+ return;
+ }
+
+ /*
+ * XXX: should be able to handle ext2fs quota1 files too
+ *
+ * XXX: should use getfsent_r(), but there isn't one.
+ */
+ setfsent();
+ while ((fs = getfsent()) != NULL) {
+ if (!strcmp(fs->fs_vfstype, "ffs") ||
+ !strcmp(fs->fs_vfstype, "lfs")) {
+ result = __quota_oldfiles_fill_fstabentry(fs, &ofe);
+ if (result == -1) {
+ goto failed;
+ }
+ if (result == 0) {
+ continue;
+ }
+ if (__quota_oldfiles_add_fstabentry(&ofe)) {
+ goto failed;
+ }
+ }
+ }
+ endfsent();
+ __quota_oldfiles_fstab_loaded = 1;
+
+ return;
+failed:
+ warn("Failed reading fstab");
+ return;
+}
+
+int
+__quota_oldfiles_infstab(const char *mountpoint)
+{
+ return __quota_oldfiles_find_fstabentry(mountpoint) != NULL;
+}
+
static uint64_t
dqblk_getlimit(uint32_t val)
{
@@ -144,79 +318,35 @@ __quota_oldfiles_initialize(struct quota
{
static const char *const names[] = INITQFNAMES;
- struct fstab *fs;
- char buf[sizeof(fs->fs_mntops)];
- char *opt, *state, *s;
+ const struct oldfiles_fstabentry *ofe;
char path[PATH_MAX];
const char *userquotafile, *groupquotafile;
- int hasuserquota, hasgroupquota;
- if (qh->qh_hasoldfiles) {
+ if (qh->qh_oldfilesopen) {
/* already initialized */
return 0;
}
/*
* Find the fstab entry.
- *
- * XXX: should be able to handle not just ffs quota1 files but
- * also lfs and even ext2fs.
*/
- setfsent();
- while ((fs = getfsent()) != NULL) {
- if (!strcmp(fs->fs_vfstype, "ffs") &&
- !strcmp(fs->fs_file, qh->qh_mountpoint)) {
- break;
- }
- }
- endfsent();
-
- if (fs == NULL) {
+ ofe = __quota_oldfiles_find_fstabentry(qh->qh_mountpoint);
+ if (ofe == NULL) {
warnx("%s not found in fstab", qh->qh_mountpoint);
errno = ENXIO;
return -1;
}
- /*
- * Inspect the mount options to find the quota files.
- * XXX this info should be gotten from the kernel.
- *
- * The options are:
- * userquota[=path] enable user quotas
- * groupquota[=path] enable group quotas
- */
- hasuserquota = hasgroupquota = 0;
- userquotafile = groupquotafile = NULL;
- strlcpy(buf, fs->fs_mntops, sizeof(buf));
- for (opt = strtok_r(buf, ",", &state);
- opt != NULL;
- opt = strtok_r(NULL, ",", &state)) {
- s = strchr(opt, '=');
- if (s != NULL) {
- *(s++) = '\0';
- }
- if (!strcmp(opt, "userquota")) {
- hasuserquota = 1;
- if (s != NULL) {
- userquotafile = s;
- }
- } else if (!strcmp(opt, "groupquota")) {
- hasgroupquota = 1;
- if (s != NULL) {
- groupquotafile = s;
- }
- }
- }
-
- if (!hasuserquota && !hasgroupquota) {
+ if (!ofe->ofe_hasuserquota && !ofe->ofe_hasgroupquota) {
errno = ENXIO;
return -1;
}
- if (hasuserquota) {
+ if (ofe->ofe_hasuserquota) {
+ userquotafile = ofe->ofe_userquotafile;
if (userquotafile == NULL) {
(void)snprintf(path, sizeof(path), "%s/%s.%s",
- fs->fs_file,
+ qh->qh_mountpoint,
QUOTAFILENAME, names[USRQUOTA]);
userquotafile = path;
}
@@ -225,10 +355,11 @@ __quota_oldfiles_initialize(struct quota
return -1;
}
}
- if (hasgroupquota) {
+ if (ofe->ofe_hasgroupquota) {
+ groupquotafile = ofe->ofe_groupquotafile;
if (groupquotafile == NULL) {
(void)snprintf(path, sizeof(path), "%s/%s.%s",
- fs->fs_file,
+ qh->qh_mountpoint,
QUOTAFILENAME, names[GRPQUOTA]);
groupquotafile = path;
}
@@ -238,7 +369,7 @@ __quota_oldfiles_initialize(struct quota
}
}
- qh->qh_hasoldfiles = 1;
+ qh->qh_oldfilesopen = 1;
return 0;
}
@@ -246,7 +377,7 @@ __quota_oldfiles_initialize(struct quota
const char *
__quota_oldfiles_getimplname(struct quotahandle *qh)
{
- return "ffs quota1 direct file access";
+ return "ufs/ffs quota v1 file access";
}
static int
@@ -258,6 +389,12 @@ __quota_oldfiles_doget(struct quotahandl
struct dqblk dq;
ssize_t result;
+ if (!qh->qh_oldfilesopen) {
+ if (__quota_oldfiles_initialize(qh)) {
+ return -1;
+ }
+ }
+
switch (qk->qk_idtype) {
case QUOTA_IDTYPE_USER:
file = qh->qh_userfile;
@@ -339,6 +476,12 @@ __quota_oldfiles_doput(struct quotahandl
struct dqblk dq;
ssize_t result;
+ if (!qh->qh_oldfilesopen) {
+ if (__quota_oldfiles_initialize(qh)) {
+ return -1;
+ }
+ }
+
switch (qk->qk_idtype) {
case QUOTA_IDTYPE_USER:
file = qh->qh_userfile;
@@ -465,6 +608,8 @@ __quota_oldfiles_cursor_create(struct qu
struct stat st;
int serrno;
+ /* quota_opencursor calls initialize for us, no need to do it here */
+
oqc = malloc(sizeof(*oqc));
if (oqc == NULL) {
return NULL;
Index: src/lib/libquota/quota_put.c
diff -u src/lib/libquota/quota_put.c:1.2 src/lib/libquota/quota_put.c:1.3
--- src/lib/libquota/quota_put.c:1.2 Mon Jan 9 15:43:19 2012
+++ src/lib/libquota/quota_put.c Wed Jan 25 17:43:37 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: quota_put.c,v 1.2 2012/01/09 15:43:19 dholland Exp $ */
+/* $NetBSD: quota_put.c,v 1.3 2012/01/25 17:43:37 dholland Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: quota_put.c,v 1.2 2012/01/09 15:43:19 dholland Exp $");
+__RCSID("$NetBSD: quota_put.c,v 1.3 2012/01/25 17:43:37 dholland Exp $");
#include <errno.h>
@@ -40,10 +40,20 @@ int
quota_put(struct quotahandle *qh, const struct quotakey *qk,
const struct quotaval *qv)
{
- if (qh->qh_isnfs) {
+ switch (qh->qh_mode) {
+ case QUOTA_MODE_NFS:
errno = EOPNOTSUPP;
return -1;
- } else {
+
+ case QUOTA_MODE_PROPLIB:
return __quota_proplib_put(qh, qk, qv);
+
+ case QUOTA_MODE_OLDFILES:
+ return __quota_oldfiles_put(qh, qk, qv);
+
+ default:
+ break;
}
+ errno = EINVAL;
+ return -1;
}
Index: src/lib/libquota/quota_open.c
diff -u src/lib/libquota/quota_open.c:1.4 src/lib/libquota/quota_open.c:1.5
--- src/lib/libquota/quota_open.c:1.4 Mon Jan 9 15:41:58 2012
+++ src/lib/libquota/quota_open.c Wed Jan 25 17:43:37 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: quota_open.c,v 1.4 2012/01/09 15:41:58 dholland Exp $ */
+/* $NetBSD: quota_open.c,v 1.5 2012/01/25 17:43:37 dholland Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: quota_open.c,v 1.4 2012/01/09 15:41:58 dholland Exp $");
+__RCSID("$NetBSD: quota_open.c,v 1.5 2012/01/25 17:43:37 dholland Exp $");
#include <sys/types.h>
#include <sys/statvfs.h>
@@ -47,30 +47,40 @@ quota_open(const char *path)
struct statvfs stv;
struct quotahandle *qh;
- int isnfs;
+ int mode;
int serrno;
+ /*
+ * Probe order:
+ *
+ * 1. Check for NFS. NFS quota ops don't go to the kernel
+ * at all but instead do RPCs to the NFS server's
+ * rpc.rquotad, so it doesn't matter what the kernel
+ * thinks.
+ *
+ * 2. Check if quotas are enabled in the mount flags. If
+ * so, we can do quotactl calls.
+ *
+ * 3. Check if the volume is listed in fstab as one of
+ * the filesystem types supported by quota_oldfiles.c,
+ * and with the proper mount options to enable quotas.
+ */
+
if (statvfs(path, &stv) < 0) {
return NULL;
}
- /*
- * We need to know up front if the volume is NFS. If so, we
- * don't go to the kernel at all but instead do RPCs to the
- * NFS server's rpc.rquotad. Therefore, don't check the
- * mount flags for quota support or do anything else that
- * reaches the kernel.
- */
-
+ __quota_oldfiles_load_fstab();
+
if (!strcmp(stv.f_fstypename, "nfs")) {
- isnfs = 1;
+ mode = QUOTA_MODE_NFS;
+ } else if ((stv.f_flag & ST_QUOTA) != 0) {
+ mode = QUOTA_MODE_PROPLIB;
+ } else if (__quota_oldfiles_infstab(stv.f_mntonname)) {
+ mode = QUOTA_MODE_OLDFILES;
} else {
- isnfs = 0;
- if ((stv.f_flag & ST_QUOTA) == 0) {
- /* XXX: correct errno? */
- errno = EOPNOTSUPP;
- return NULL;
- }
+ errno = EOPNOTSUPP;
+ return NULL;
}
qh = malloc(sizeof(*qh));
@@ -100,9 +110,9 @@ quota_open(const char *path)
return NULL;
}
- qh->qh_isnfs = isnfs;
+ qh->qh_mode = mode;
- qh->qh_hasoldfiles = 0;
+ qh->qh_oldfilesopen = 0;
qh->qh_userfile = -1;
qh->qh_groupfile = -1;
Index: src/lib/libquota/quotapvt.h
diff -u src/lib/libquota/quotapvt.h:1.9 src/lib/libquota/quotapvt.h:1.10
--- src/lib/libquota/quotapvt.h:1.9 Wed Jan 25 01:22:57 2012
+++ src/lib/libquota/quotapvt.h Wed Jan 25 17:43:37 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: quotapvt.h,v 1.9 2012/01/25 01:22:57 dholland Exp $ */
+/* $NetBSD: quotapvt.h,v 1.10 2012/01/25 17:43:37 dholland Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -28,13 +28,17 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#define QUOTA_MODE_NFS 1
+#define QUOTA_MODE_PROPLIB 2
+#define QUOTA_MODE_OLDFILES 3
+
struct quotahandle {
char *qh_mountpoint;
char *qh_mountdevice;
- int qh_isnfs;
+ int qh_mode;
/* these are used only by quota_oldfiles */
- int qh_hasoldfiles;
+ int qh_oldfilesopen;
int qh_userfile;
int qh_groupfile;
@@ -86,6 +90,8 @@ int __quota_nfs_get(struct quotahandle *
/* direct interface to old (quota1-type) files */
+void __quota_oldfiles_load_fstab(void);
+int __quota_oldfiles_infstab(const char *);
int __quota_oldfiles_initialize(struct quotahandle *qh);
const char *__quota_oldfiles_getimplname(struct quotahandle *);
int __quota_oldfiles_get(struct quotahandle *qh, const struct quotakey *qk,