Source-Changes-HG archive

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

[src/trunk]: src/sys Call QUOTACTL_GETALL in a loop to get results 8 at a tim...



details:   https://anonhg.NetBSD.org/src/rev/81e25905a9b3
branches:  trunk
changeset: 773197:81e25905a9b3
user:      dholland <dholland%NetBSD.org@localhost>
date:      Sun Jan 29 07:07:22 2012 +0000

description:
Call QUOTACTL_GETALL in a loop to get results 8 at a time. Make
the QUOTACTL_GETALL interface less abusive.

Note: this change requires a kernel version bump.

diffstat:

 sys/kern/vfs_quotactl.c  |  133 ++++++++++++++++++++++++----------------------
 sys/sys/quotactl.h       |   14 +---
 sys/ufs/ufs/ufs_quota.c  |   17 ++++-
 sys/ufs/ufs/ufs_quota.h  |    5 +-
 sys/ufs/ufs/ufs_quota2.c |  109 ++++++++++++++++----------------------
 5 files changed, 134 insertions(+), 144 deletions(-)

diffs (truncated from 523 to 300 lines):

diff -r e8234927b151 -r 81e25905a9b3 sys/kern/vfs_quotactl.c
--- a/sys/kern/vfs_quotactl.c   Sun Jan 29 07:06:37 2012 +0000
+++ b/sys/kern/vfs_quotactl.c   Sun Jan 29 07:07:22 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_quotactl.c,v 1.26 2012/01/29 07:06:37 dholland Exp $       */
+/*     $NetBSD: vfs_quotactl.c,v 1.27 2012/01/29 07:07:22 dholland Exp $       */
 
 /*
  * Copyright (c) 1991, 1993, 1994
@@ -80,7 +80,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_quotactl.c,v 1.26 2012/01/29 07:06:37 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_quotactl.c,v 1.27 2012/01/29 07:07:22 dholland Exp $");
 
 #include <sys/malloc.h> /* XXX: temporary */
 #include <sys/mount.h>
@@ -525,16 +525,18 @@
                        prop_array_t datas)
 {
        struct quotakcursor cursor;
-       struct quota_getall_result result;
+       struct quotakey *keys;
+       struct quotaval *vals;
+       unsigned loopmax = 8;
+       unsigned loopnum;
        struct vfs_quotactl_args args;
        prop_array_t replies;
-       prop_dictionary_t thisreply;
        struct quotakey *key;
        struct quotaval *val;
        id_t lastid;
+       prop_dictionary_t thisreply;
        unsigned i;
        int error, error2;
-       int skip = 0;
 
        KASSERT(prop_object_type(cmddict) == PROP_TYPE_DICTIONARY);
 
@@ -545,30 +547,8 @@
                return error;
        }
 
-       result.qr_keys = NULL;
-       result.qr_vals = NULL;
-       result.qr_num = 0;
-       result.qr_max = 0x7fffffff; /* XXX bogus; but temporary */
-
-       args.qc_type = QCT_GETALL;
-       args.u.getall.qc_cursor = &cursor;
-       args.u.getall.qc_idtype = q2type;
-       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;
-       }
+       keys = malloc(loopmax * sizeof(keys[0]), M_TEMP, M_WAITOK);
+       vals = malloc(loopmax * sizeof(vals[0]), M_TEMP, M_WAITOK);
 
        replies = prop_array_create();
        if (replies == NULL) {
@@ -576,44 +556,73 @@
                goto err;
        }
 
-       if (skip) {
-               goto skip;
-       }
-
        thisreply = NULL;
        lastid = 0; /* value not actually referenced */
-       for (i = 0; i < result.qr_num; i++) {
-               key = &result.qr_keys[i];
-               val = &result.qr_vals[i];
+
+       while (1) {
+               args.qc_type = QCT_GETALL;
+               args.u.getall.qc_cursor = &cursor;
+               args.u.getall.qc_keys = keys;
+               args.u.getall.qc_vals = vals;
+               args.u.getall.qc_maxnum = loopmax;
+               args.u.getall.qc_ret = &loopnum;
+               args.u.getall.qc_idtype = q2type;       /* XXX */
+
+               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) {
+                       error = 0;
+                       break;
+               }
+
+               if (error) {
+                       goto err;
+               }
 
-               if (thisreply == NULL || key->qk_id != lastid) {
-                       lastid = key->qk_id;
-                       thisreply = vfs_quotactl_getall_makereply(key);
-                       if (thisreply == NULL) {
-                               error = ENOMEM;
-                               goto err;
+               if (loopnum == 0) {
+                       /* end of iteration */
+                       break;
+               }
+
+               for (i = 0; i < loopnum; i++) {
+                       key = &keys[i];
+                       val = &vals[i];
+
+                       if (thisreply == NULL || key->qk_id != lastid) {
+                               lastid = key->qk_id;
+                               thisreply = vfs_quotactl_getall_makereply(key);
+                               if (thisreply == NULL) {
+                                       error = ENOMEM;
+                                       goto err;
+                               }
+                               /*
+                                * Note: while we release our reference to
+                                * thisreply here, we can (and do) continue to
+                                * use the pointer in the loop because the
+                                * copy attached to the replies array is not
+                                * going away.
+                                */
+                               if (!prop_array_add_and_rel(replies,
+                                                           thisreply)) {
+                                       error = ENOMEM;
+                                       goto err;
+                               }
                        }
-                       /*
-                        * Note: while we release our reference to
-                        * thisreply here, we can (and do) continue to
-                        * use the pointer in the loop because the
-                        * copy attached to the replies array is not
-                        * going away.
-                        */
-                       if (!prop_array_add_and_rel(replies, thisreply)) {
-                               error = ENOMEM;
+
+                       error = vfs_quotactl_getall_addreply(thisreply,
+                                                            key, val);
+                       if (error) {
                                goto err;
                        }
                }
-
-               error = vfs_quotactl_getall_addreply(thisreply, key, val);
-               if (error) {
-                       goto err;
-               }
        }
 
-skip:
-
        if (!prop_dictionary_set_and_rel(cmddict, "data", replies)) {
                error = ENOMEM;
                goto err;
@@ -621,12 +630,8 @@
 
        error = 0;
  err:
-       if (result.qr_keys) {
-               free(result.qr_keys, M_TEMP);
-       }
-       if (result.qr_vals) {
-               free(result.qr_vals, M_TEMP);
-       }
+       free(keys, M_TEMP);
+       free(vals, M_TEMP);
 
        args.qc_type = QCT_CURSORCLOSE;
        args.u.cursorclose.qc_cursor = &cursor;
diff -r e8234927b151 -r 81e25905a9b3 sys/sys/quotactl.h
--- a/sys/sys/quotactl.h        Sun Jan 29 07:06:37 2012 +0000
+++ b/sys/sys/quotactl.h        Sun Jan 29 07:07:22 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: quotactl.h,v 1.23 2012/01/29 07:06:01 dholland Exp $   */
+/*     $NetBSD: quotactl.h,v 1.24 2012/01/29 07:07:22 dholland Exp $   */
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -37,8 +37,6 @@
  * 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,
@@ -105,13 +103,11 @@
                } cursorclose;
                struct {
                        struct quotakcursor *qc_cursor;
+                       struct quotakey *qc_keys;
+                       struct quotaval *qc_vals;
+                       unsigned qc_maxnum;
+                       unsigned *qc_ret;
                        int qc_idtype;
-                       struct quota_getall_result {
-                               struct quotakey *qr_keys;
-                               struct quotaval *qr_vals;
-                               unsigned qr_num;
-                               unsigned qr_max;
-                       } *qc_result;
                } getall;
        } u;
 };
diff -r e8234927b151 -r 81e25905a9b3 sys/ufs/ufs/ufs_quota.c
--- a/sys/ufs/ufs/ufs_quota.c   Sun Jan 29 07:06:37 2012 +0000
+++ b/sys/ufs/ufs/ufs_quota.c   Sun Jan 29 07:07:22 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ufs_quota.c,v 1.95 2012/01/29 07:02:06 dholland Exp $  */
+/*     $NetBSD: ufs_quota.c,v 1.96 2012/01/29 07:07:22 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.95 2012/01/29 07:02:06 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_quota.c,v 1.96 2012/01/29 07:07:22 dholland Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_quota.h"
@@ -370,14 +370,20 @@
 {
        struct ufsmount *ump = VFSTOUFS(mp);
        struct quotakcursor *cursor;
+       struct quotakey *keys;
+       struct quotaval *vals;
+       unsigned maxnum;
+       unsigned *ret;
        int idtype;
-       struct quota_getall_result *result;
        int error;
 
        KASSERT(args->qc_type == QCT_GETALL);
        cursor = args->u.getall.qc_cursor;
+       keys = args->u.getall.qc_keys;
+       vals = args->u.getall.qc_vals;
+       maxnum = args->u.getall.qc_maxnum;
+       ret = args->u.getall.qc_ret;
        idtype = args->u.getall.qc_idtype;
-       result = args->u.getall.qc_result;
 
        if ((ump->um_flags & UFS_QUOTA2) == 0)
                return EOPNOTSUPP;
@@ -389,7 +395,8 @@
                
 #ifdef QUOTA2
        if (ump->um_flags & UFS_QUOTA2) {
-               error = quota2_handle_cmd_getall(ump, cursor, idtype, result);
+               error = quota2_handle_cmd_getall(ump, cursor, idtype,
+                                                keys, vals, maxnum, ret);
        } else
 #endif
                panic("quota_handle_cmd_getall: no support ?");
diff -r e8234927b151 -r 81e25905a9b3 sys/ufs/ufs/ufs_quota.h
--- a/sys/ufs/ufs/ufs_quota.h   Sun Jan 29 07:06:37 2012 +0000
+++ b/sys/ufs/ufs/ufs_quota.h   Sun Jan 29 07:07:22 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ufs_quota.h,v 1.17 2012/01/29 07:02:06 dholland Exp $  */
+/*     $NetBSD: ufs_quota.h,v 1.18 2012/01/29 07:07:22 dholland Exp $  */
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993, 1995
@@ -37,7 +37,6 @@
 #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) */
@@ -133,7 +132,7 @@
     const struct quotaval *);
 int quota2_handle_cmd_delete(struct ufsmount *, const struct quotakey *);
 int quota2_handle_cmd_getall(struct ufsmount *, struct quotakcursor *, int,
-    struct quota_getall_result *);



Home | Main Index | Thread Index | Old Index