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