Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Hack QUOTACTL_GETALL to return results without using pro...



details:   https://anonhg.NetBSD.org/src/rev/c223de8b1e28
branches:  trunk
changeset: 773191:c223de8b1e28
user:      dholland <dholland%NetBSD.org@localhost>
date:      Sun Jan 29 07:02:06 2012 +0000

description:
Hack QUOTACTL_GETALL to return results without using proplib.

(this interface is abusive and is going to be cleaned up in the
immediate future)

Note: this change requires a kernel version bump.

diffstat:

 sys/kern/vfs_quotactl.c  |  141 ++++++++++++++++++++++++++++++++++++++++++++++-
 sys/sys/quotactl.h       |   12 +++-
 sys/ufs/ufs/ufs_quota.c  |   23 ++-----
 sys/ufs/ufs/ufs_quota.h  |    5 +-
 sys/ufs/ufs/ufs_quota2.c |   73 +++++++++++++++--------
 5 files changed, 204 insertions(+), 50 deletions(-)

diffs (truncated from 494 to 300 lines):

diff -r 975916fe991c -r c223de8b1e28 sys/kern/vfs_quotactl.c
--- a/sys/kern/vfs_quotactl.c   Sun Jan 29 07:00:39 2012 +0000
+++ b/sys/kern/vfs_quotactl.c   Sun Jan 29 07:02:06 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_quotactl.c,v 1.22 2012/01/29 07:00:39 dholland Exp $       */
+/*     $NetBSD: vfs_quotactl.c,v 1.23 2012/01/29 07:02:06 dholland Exp $       */
 
 /*
  * Copyright (c) 1991, 1993, 1994
@@ -80,8 +80,9 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_quotactl.c,v 1.22 2012/01/29 07:00:39 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_quotactl.c,v 1.23 2012/01/29 07:02:06 dholland Exp $");
 
+#include <sys/malloc.h> /* XXX: temporary */
 #include <sys/mount.h>
 #include <sys/quota.h>
 #include <sys/quotactl.h>
@@ -437,14 +438,84 @@
        return error;
 }
 
+static prop_dictionary_t
+vfs_quotactl_getall_makereply(id_t id, int def,
+                             const struct quotaval *blocks,
+                             const struct quotaval *files)
+{
+#define INITQVNAMES_ALL { \
+    QUOTADICT_LIMIT_HARD, \
+    QUOTADICT_LIMIT_SOFT, \
+    QUOTADICT_LIMIT_USAGE, \
+    QUOTADICT_LIMIT_ETIME, \
+    QUOTADICT_LIMIT_GTIME \
+    }
+#define N_QV 5
+
+       const char *val_names[] = INITQVNAMES_ALL;
+       uint64_t vals[N_QV];
+       prop_dictionary_t dict1 = prop_dictionary_create();
+       prop_dictionary_t dict2;
+
+       if (dict1 == NULL)
+               return NULL;
+
+       if (def) {
+               if (!prop_dictionary_set_cstring_nocopy(dict1, "id",
+                   "default")) {
+                       goto err;
+               }
+       } else {
+               if (!prop_dictionary_set_uint32(dict1, "id", id)) {
+                       goto err;
+               }
+       }
+
+       vals[0] = blocks->qv_hardlimit;
+       vals[1] = blocks->qv_softlimit;
+       vals[2] = blocks->qv_usage;
+       vals[3] = blocks->qv_expiretime;
+       vals[4] = blocks->qv_grace;
+       dict2 = limits64toprop(vals, val_names, N_QV);
+       if (dict2 == NULL)
+               goto err;
+       if (!prop_dictionary_set_and_rel(dict1, QUOTADICT_LTYPE_BLOCK, dict2))
+               goto err;
+
+
+       vals[0] = files->qv_hardlimit;
+       vals[1] = files->qv_softlimit;
+       vals[2] = files->qv_usage;
+       vals[3] = files->qv_expiretime;
+       vals[4] = files->qv_grace;
+       dict2 = limits64toprop(vals, val_names, N_QV);
+       if (dict2 == NULL)
+               goto err;
+       if (!prop_dictionary_set_and_rel(dict1, QUOTADICT_LTYPE_FILE, dict2))
+               goto err;
+
+       return dict1;
+
+err:
+       prop_object_release(dict1);
+       return NULL;
+}
+
 static int
 vfs_quotactl_getall(struct mount *mp,
                        prop_dictionary_t cmddict, int q2type,
                        prop_array_t datas)
 {
        struct quotakcursor cursor;
+       struct quota_getall_result result;
        struct vfs_quotactl_args args;
+       prop_array_t replies;
+       prop_dictionary_t dict;
+       unsigned i;
        int error, error2;
+       int skip = 0;
+
+       KASSERT(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
 
        args.qc_type = QCT_CURSOROPEN;
        args.u.cursoropen.qc_cursor = &cursor;
@@ -453,11 +524,75 @@
                return error;
        }
 
+       result.qr_keys = NULL;
+       result.qr_vals = NULL;
+
        args.qc_type = QCT_GETALL;
        args.u.getall.qc_cursor = &cursor;
        args.u.getall.qc_idtype = q2type;
-       args.u.getall.qc_cmddict = cmddict;
+       args.u.getall.qc_result = &result;
        error = VFS_QUOTACTL(mp, QUOTACTL_GETALL, &args);
+       /*
+        * XXX this is bogus but up until now *all* errors
+        * from inside quotactl_getall were suppressed by the
+        * dispatching code in ufs_quota.c. Fixing that causes
+        * repquota to break in an undesirable way; this is a
+        * workaround.
+        */
+       if (error == ENODEV || error == ENXIO) {
+               skip = 1;
+               error = 0;
+       }
+       if (error) {
+               goto err;
+       }
+
+       replies = prop_array_create();
+       if (replies == NULL) {
+               error = ENOMEM;
+               goto err;
+       }
+
+       if (skip) {
+               goto skip;
+       }
+
+       dict = vfs_quotactl_getall_makereply(0, 1, &result.qr_defblocks,
+                                            &result.qr_deffiles);
+       if (!prop_array_add_and_rel(replies, dict)) {
+               error = ENOMEM;
+               goto err;
+       }
+
+       for (i = 0; i < result.qr_num; i += 2) {
+               dict = vfs_quotactl_getall_makereply(result.qr_keys[i].qk_id,0,
+                                                    &result.qr_vals[i],
+                                                    &result.qr_vals[i+1]);
+               if (dict == NULL) {
+                       error = ENOMEM;
+                       goto err;
+               }
+               if (!prop_array_add_and_rel(replies, dict)) {
+                       error = ENOMEM;
+                       goto err;
+               }
+       }
+
+skip:
+
+       if (!prop_dictionary_set_and_rel(cmddict, "data", replies)) {
+               error = ENOMEM;
+               goto err;
+       }
+
+       error = 0;
+ err:
+       if (result.qr_keys) {
+               free(result.qr_keys, M_TEMP);
+       }
+       if (result.qr_vals) {
+               free(result.qr_vals, M_TEMP);
+       }
 
        args.qc_type = QCT_CURSORCLOSE;
        args.u.cursorclose.qc_cursor = &cursor;
diff -r 975916fe991c -r c223de8b1e28 sys/sys/quotactl.h
--- a/sys/sys/quotactl.h        Sun Jan 29 07:00:39 2012 +0000
+++ b/sys/sys/quotactl.h        Sun Jan 29 07:02:06 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: quotactl.h,v 1.20 2012/01/29 07:00:39 dholland Exp $   */
+/*     $NetBSD: quotactl.h,v 1.21 2012/01/29 07:02:06 dholland Exp $   */
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -37,6 +37,8 @@
  * use the <quota.h> API instead.
  */
 
+#include <sys/quota.h>
+
 /*
  * Semi-opaque structure for cursors. This holds the cursor state in
  * userland; the size is exposed only to libquota, not to client code,
@@ -104,7 +106,13 @@
                struct {
                        struct quotakcursor *qc_cursor;
                        int qc_idtype;
-                       prop_dictionary_t qc_cmddict;
+                       struct quota_getall_result {
+                               struct quotaval qr_defblocks;
+                               struct quotaval qr_deffiles;
+                               struct quotakey *qr_keys;
+                               struct quotaval *qr_vals;
+                               unsigned qr_num;
+                       } *qc_result;
                } getall;
        } u;
 };
diff -r 975916fe991c -r c223de8b1e28 sys/ufs/ufs/ufs_quota.c
--- a/sys/ufs/ufs/ufs_quota.c   Sun Jan 29 07:00:39 2012 +0000
+++ b/sys/ufs/ufs/ufs_quota.c   Sun Jan 29 07:02:06 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ufs_quota.c,v 1.94 2012/01/29 07:00:39 dholland Exp $  */
+/*     $NetBSD: ufs_quota.c,v 1.95 2012/01/29 07:02:06 dholland Exp $  */
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993, 1995
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.94 2012/01/29 07:00:39 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.95 2012/01/29 07:02:06 dholland Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_quota.h"
@@ -368,19 +368,16 @@
 quota_handle_cmd_getall(struct mount *mp, struct lwp *l, 
     struct vfs_quotactl_args *args)
 {
-       prop_array_t replies;
        struct ufsmount *ump = VFSTOUFS(mp);
        struct quotakcursor *cursor;
        int idtype;
-       prop_dictionary_t cmddict;
+       struct quota_getall_result *result;
        int error;
 
        KASSERT(args->qc_type == QCT_GETALL);
        cursor = args->u.getall.qc_cursor;
        idtype = args->u.getall.qc_idtype;
-       cmddict = args->u.getall.qc_cmddict;
-
-       KASSERT(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
+       result = args->u.getall.qc_result;
 
        if ((ump->um_flags & UFS_QUOTA2) == 0)
                return EOPNOTSUPP;
@@ -390,21 +387,13 @@
        if (error)
                return error;
                
-       replies = prop_array_create();
-       if (replies == NULL)
-               return ENOMEM;
-
 #ifdef QUOTA2
        if (ump->um_flags & UFS_QUOTA2) {
-               error = quota2_handle_cmd_getall(ump, cursor, idtype, replies);
+               error = quota2_handle_cmd_getall(ump, cursor, idtype, result);
        } else
 #endif
                panic("quota_handle_cmd_getall: no support ?");
-       if (!prop_dictionary_set_and_rel(cmddict, "data", replies)) {
-               error = ENOMEM;
-       } else {
-               error = 0;
-       }
+
        return error;
 }
 
diff -r 975916fe991c -r c223de8b1e28 sys/ufs/ufs/ufs_quota.h
--- a/sys/ufs/ufs/ufs_quota.h   Sun Jan 29 07:00:39 2012 +0000
+++ b/sys/ufs/ufs/ufs_quota.h   Sun Jan 29 07:02:06 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ufs_quota.h,v 1.16 2012/01/29 07:00:40 dholland Exp $  */
+/*     $NetBSD: ufs_quota.h,v 1.17 2012/01/29 07:02:06 dholland Exp $  */
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993, 1995
@@ -37,6 +37,7 @@
 #include <ufs/ufs/quota2.h>
 
 struct quotakcursor; /* from <sys/quotactl.h> */
+struct quota_getall_result; /* ditto, but: XXX temporary */
 
 
 /* link to this quota in the quota inode (for QUOTA2) */
@@ -132,7 +133,7 @@
     const struct quotaval *);
 int quota2_handle_cmd_delete(struct ufsmount *, const struct quotakey *);
 int quota2_handle_cmd_getall(struct ufsmount *, struct quotakcursor *, int,



Home | Main Index | Thread Index | Old Index