Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Add quota_quotaon() and quota_quotaoff(). Use them in quotao...
details: https://anonhg.NetBSD.org/src/rev/55b45ae3f969
branches: trunk
changeset: 773288:55b45ae3f969
user: dholland <dholland%NetBSD.org@localhost>
date: Mon Jan 30 16:45:13 2012 +0000
description:
Add quota_quotaon() and quota_quotaoff(). Use them in quotaon(8).
diffstat:
include/quota.h | 3 +
lib/libquota/quota_oldfiles.c | 104 +++++++++++++++++++++--
lib/libquota/quota_open.c | 51 +++++++++++-
lib/libquota/quota_proplib.c | 113 +++++++++++++++++++++++++-
lib/libquota/quotapvt.h | 7 +-
usr.sbin/quotaon/Makefile | 7 +-
usr.sbin/quotaon/quotaon.c | 185 ++++++++++++++++++++++-------------------
7 files changed, 366 insertions(+), 104 deletions(-)
diffs (truncated from 700 to 300 lines):
diff -r 2463e04370dc -r 55b45ae3f969 include/quota.h
--- a/include/quota.h Mon Jan 30 16:44:23 2012 +0000
+++ b/include/quota.h Mon Jan 30 16:45:13 2012 +0000
@@ -55,6 +55,9 @@
const char *quota_objtype_getname(struct quotahandle *, int /*objtype*/);
int quota_objtype_isbytes(struct quotahandle *, int /*objtype*/);
+int quota_quotaon(struct quotahandle *, int /*idtype*/);
+int quota_quotaoff(struct quotahandle *, int /*idtype*/);
+
int quota_get(struct quotahandle *, const struct quotakey *,
struct quotaval *);
diff -r 2463e04370dc -r 55b45ae3f969 lib/libquota/quota_oldfiles.c
--- a/lib/libquota/quota_oldfiles.c Mon Jan 30 16:44:23 2012 +0000
+++ b/lib/libquota/quota_oldfiles.c Mon Jan 30 16:45:13 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: quota_oldfiles.c,v 1.4 2012/01/30 06:15:22 dholland Exp $ */
+/* $NetBSD: quota_oldfiles.c,v 1.5 2012/01/30 16:45:13 dholland Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
@@ -237,6 +237,57 @@
return __quota_oldfiles_find_fstabentry(mountpoint) != NULL;
}
+static void
+__quota_oldfiles_defquotafile(struct quotahandle *qh, int idtype,
+ char *buf, size_t maxlen)
+{
+ static const char *const names[] = INITQFNAMES;
+
+ (void)snprintf(buf, maxlen, "%s/%s.%s",
+ qh->qh_mountpoint,
+ QUOTAFILENAME, names[USRQUOTA]);
+}
+
+const char *
+__quota_oldfiles_getquotafile(struct quotahandle *qh, int idtype,
+ char *buf, size_t maxlen)
+{
+ const struct oldfiles_fstabentry *ofe;
+ const char *file;
+
+ ofe = __quota_oldfiles_find_fstabentry(qh->qh_mountpoint);
+ if (ofe == NULL) {
+ errno = ENXIO;
+ return NULL;
+ }
+
+ switch (idtype) {
+ case USRQUOTA:
+ if (!ofe->ofe_hasuserquota) {
+ errno = ENXIO;
+ return NULL;
+ }
+ file = ofe->ofe_userquotafile;
+ break;
+ case GRPQUOTA:
+ if (!ofe->ofe_hasgroupquota) {
+ errno = ENXIO;
+ return NULL;
+ }
+ file = ofe->ofe_groupquotafile;
+ break;
+ default:
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (file == NULL) {
+ __quota_oldfiles_defquotafile(qh, idtype, buf, maxlen);
+ file = buf;
+ }
+ return file;
+}
+
static uint64_t
dqblk_getlimit(uint32_t val)
{
@@ -316,8 +367,6 @@
int
__quota_oldfiles_initialize(struct quotahandle *qh)
{
- static const char *const names[] = INITQFNAMES;
-
const struct oldfiles_fstabentry *ofe;
char path[PATH_MAX];
const char *userquotafile, *groupquotafile;
@@ -345,9 +394,8 @@
if (ofe->ofe_hasuserquota) {
userquotafile = ofe->ofe_userquotafile;
if (userquotafile == NULL) {
- (void)snprintf(path, sizeof(path), "%s/%s.%s",
- qh->qh_mountpoint,
- QUOTAFILENAME, names[USRQUOTA]);
+ __quota_oldfiles_defquotafile(qh, USRQUOTA,
+ path, sizeof(path));
userquotafile = path;
}
if (__quota_oldfiles_open(qh, userquotafile,
@@ -358,9 +406,8 @@
if (ofe->ofe_hasgroupquota) {
groupquotafile = ofe->ofe_groupquotafile;
if (groupquotafile == NULL) {
- (void)snprintf(path, sizeof(path), "%s/%s.%s",
- qh->qh_mountpoint,
- QUOTAFILENAME, names[GRPQUOTA]);
+ __quota_oldfiles_defquotafile(qh, GRPQUOTA,
+ path, sizeof(path));
groupquotafile = path;
}
if (__quota_oldfiles_open(qh, groupquotafile,
@@ -380,6 +427,45 @@
return "ufs/ffs quota v1 file access";
}
+int
+__quota_oldfiles_quotaon(struct quotahandle *qh, int idtype)
+{
+ int result;
+
+ /*
+ * If we have the quota files open, close them.
+ */
+
+ if (qh->qh_oldfilesopen) {
+ if (qh->qh_userfile >= 0) {
+ close(qh->qh_userfile);
+ qh->qh_userfile = -1;
+ }
+ if (qh->qh_groupfile >= 0) {
+ close(qh->qh_groupfile);
+ qh->qh_groupfile = -1;
+ }
+ qh->qh_oldfilesopen = 0;
+ }
+
+ /*
+ * Go over to the syscall interface.
+ */
+
+ result = __quota_proplib_quotaon(qh, idtype);
+ if (result < 0) {
+ return -1;
+ }
+
+ /*
+ * We succeeded, so all further access should be via the
+ * kernel.
+ */
+
+ qh->qh_mode = QUOTA_MODE_PROPLIB;
+ return 0;
+}
+
static int
__quota_oldfiles_doget(struct quotahandle *qh, const struct quotakey *qk,
struct quotaval *qv, int *isallzero)
diff -r 2463e04370dc -r 55b45ae3f969 lib/libquota/quota_open.c
--- a/lib/libquota/quota_open.c Mon Jan 30 16:44:23 2012 +0000
+++ b/lib/libquota/quota_open.c Mon Jan 30 16:45:13 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: quota_open.c,v 1.5 2012/01/25 17:43:37 dholland Exp $ */
+/* $NetBSD: quota_open.c,v 1.6 2012/01/30 16:45:13 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.5 2012/01/25 17:43:37 dholland Exp $");
+__RCSID("$NetBSD: quota_open.c,v 1.6 2012/01/30 16:45:13 dholland Exp $");
#include <sys/types.h>
#include <sys/statvfs.h>
@@ -64,6 +64,15 @@
* 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.
+ *
+ * Note that (as of this writing) the mount options for
+ * enabling quotas are accepted by mount for *all* filesystem
+ * types and then ignored -- the kernel mount flag (ST_QUOTA /
+ * MNT_QUOTA) gets set either by the filesystem based on its
+ * own criteria, or for old-style quotas, during quotaon. The
+ * quota filenames specified in fstab are not passed to or
+ * known by the kernel except via quota_oldfiles.c! This is
+ * generally gross but not easily fixed.
*/
if (statvfs(path, &stv) < 0) {
@@ -144,3 +153,41 @@
free(qh->qh_mountpoint);
free(qh);
}
+
+int
+quota_quotaon(struct quotahandle *qh, int idtype)
+{
+ switch (qh->qh_mode) {
+ case QUOTA_MODE_NFS:
+ errno = EOPNOTSUPP;
+ break;
+ case QUOTA_MODE_PROPLIB:
+ return __quota_proplib_quotaon(qh, idtype);
+ case QUOTA_MODE_OLDFILES:
+ return __quota_oldfiles_quotaon(qh, idtype);
+ default:
+ errno = EINVAL;
+ break;
+ }
+ return -1;
+}
+
+int
+quota_quotaoff(struct quotahandle *qh, int idtype)
+{
+ switch (qh->qh_mode) {
+ case QUOTA_MODE_NFS:
+ errno = EOPNOTSUPP;
+ break;
+ case QUOTA_MODE_PROPLIB:
+ return __quota_proplib_quotaoff(qh, idtype);
+ case QUOTA_MODE_OLDFILES:
+ /* can't quotaoff if we haven't quotaon'd */
+ errno = ENOTCONN;
+ break;
+ default:
+ errno = EINVAL;
+ break;
+ }
+ return -1;
+}
diff -r 2463e04370dc -r 55b45ae3f969 lib/libquota/quota_proplib.c
--- a/lib/libquota/quota_proplib.c Mon Jan 30 16:44:23 2012 +0000
+++ b/lib/libquota/quota_proplib.c Mon Jan 30 16:45:13 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: quota_proplib.c,v 1.9 2012/01/30 16:44:08 dholland Exp $ */
+/* $NetBSD: quota_proplib.c,v 1.10 2012/01/30 16:45:13 dholland Exp $ */
/*-
* Copyright (c) 2011 Manuel Bouyer
* All rights reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: quota_proplib.c,v 1.9 2012/01/30 16:44:08 dholland Exp $");
+__RCSID("$NetBSD: quota_proplib.c,v 1.10 2012/01/30 16:45:13 dholland Exp $");
#include <stdlib.h>
#include <string.h>
@@ -35,6 +35,7 @@
#include <err.h>
#include <quota.h>
+#include <ufs/ufs/quota1.h>
#include "quotapvt.h"
#include <quota/quotaprop.h>
@@ -55,6 +56,8 @@
unsigned didblocks;
};
+static const char *const __quota1_qfnames[] = INITQFNAMES;
+
int
__quota_proplib_getversion(struct quotahandle *qh, int8_t *version_ret)
{
@@ -240,6 +243,112 @@
}
static int
+__quota_proplib_quotaonoff(struct quotahandle *qh, int idtype, int offmode)
+{
+ prop_dictionary_t dict, data, cmd;
+ prop_array_t cmds, datas;
+ struct plistref pref;
+ int8_t error8;
+ const char *file;
+ char path[PATH_MAX];
+
+ /*
+ * Note that while it is an error to call quotaon on something
+ * that isn't a volume with old-style quotas that expects
+ * quotaon to be called, it's not our responsibility to check
+ * for that; the filesystem will. Also note that it is not an
+ * error to call quotaon repeatedly -- apparently this is to
+ * permit changing the quota file in use on the fly or
+ * something. So all we need to do here is ask the oldfiles
+ * code if the mount option was set in fstab and fetch back
+ * the filename.
+ */
+
+ if (offmode) {
+ file = NULL;
+ } else {
+ file = __quota_oldfiles_getquotafile(qh, idtype,
+ path, sizeof(path));
Home |
Main Index |
Thread Index |
Old Index