Module Name: src
Committed By: dholland
Date: Sun Jan 29 07:05:13 UTC 2012
Modified Files:
src/sys/kern: vfs_quotactl.c
src/sys/sys: quotactl.h
src/sys/ufs/ufs: ufs_quota2.c
Log Message:
Teach quota2 QUOTACTL_GETALL to acecpt a limit on how much it sends back.
Pass in a dummy limit for now.
Note: this change requires a kernel version bump.
To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 src/sys/kern/vfs_quotactl.c
cvs rdiff -u -r1.21 -r1.22 src/sys/sys/quotactl.h
cvs rdiff -u -r1.20 -r1.21 src/sys/ufs/ufs/ufs_quota2.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/kern/vfs_quotactl.c
diff -u src/sys/kern/vfs_quotactl.c:1.23 src/sys/kern/vfs_quotactl.c:1.24
--- src/sys/kern/vfs_quotactl.c:1.23 Sun Jan 29 07:02:06 2012
+++ src/sys/kern/vfs_quotactl.c Sun Jan 29 07:05:12 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_quotactl.c,v 1.23 2012/01/29 07:02:06 dholland Exp $ */
+/* $NetBSD: vfs_quotactl.c,v 1.24 2012/01/29 07:05:12 dholland Exp $ */
/*
* Copyright (c) 1991, 1993, 1994
@@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_quotactl.c,v 1.23 2012/01/29 07:02:06 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_quotactl.c,v 1.24 2012/01/29 07:05:12 dholland Exp $");
#include <sys/malloc.h> /* XXX: temporary */
#include <sys/mount.h>
@@ -526,6 +526,8 @@ vfs_quotactl_getall(struct mount *mp,
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;
Index: src/sys/sys/quotactl.h
diff -u src/sys/sys/quotactl.h:1.21 src/sys/sys/quotactl.h:1.22
--- src/sys/sys/quotactl.h:1.21 Sun Jan 29 07:02:06 2012
+++ src/sys/sys/quotactl.h Sun Jan 29 07:05:12 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: quotactl.h,v 1.21 2012/01/29 07:02:06 dholland Exp $ */
+/* $NetBSD: quotactl.h,v 1.22 2012/01/29 07:05:12 dholland Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -112,6 +112,7 @@ struct vfs_quotactl_args {
struct quotakey *qr_keys;
struct quotaval *qr_vals;
unsigned qr_num;
+ unsigned qr_max;
} *qc_result;
} getall;
} u;
Index: src/sys/ufs/ufs/ufs_quota2.c
diff -u src/sys/ufs/ufs/ufs_quota2.c:1.20 src/sys/ufs/ufs/ufs_quota2.c:1.21
--- src/sys/ufs/ufs/ufs_quota2.c:1.20 Sun Jan 29 07:04:21 2012
+++ src/sys/ufs/ufs/ufs_quota2.c Sun Jan 29 07:05:12 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_quota2.c,v 1.20 2012/01/29 07:04:21 dholland Exp $ */
+/* $NetBSD: ufs_quota2.c,v 1.21 2012/01/29 07:05:12 dholland Exp $ */
/*-
* Copyright (c) 2010 Manuel Bouyer
* All rights reserved.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.20 2012/01/29 07:04:21 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.21 2012/01/29 07:05:12 dholland Exp $");
#include <sys/buf.h>
#include <sys/param.h>
@@ -829,7 +829,8 @@ out_dq:
static int
quota2_result_add_q2e(struct ufsmount *ump, int idtype,
- int id, struct quota_getall_result *result, unsigned pos)
+ int id, struct quota_getall_result *result, unsigned pos,
+ int skipfirst, int skiplast)
{
struct dquot *dq;
int error;
@@ -859,15 +860,21 @@ quota2_result_add_q2e(struct ufsmount *u
mutex_exit(&dq->dq_interlock);
dqrele(NULLVP, dq);
- result->qr_keys[pos].qk_idtype = idtype;
- result->qr_keys[pos].qk_objtype = QUOTA_OBJTYPE_BLOCKS;
- q2e_to_quotaval(&q2e, 0, &result->qr_keys[pos].qk_id,
- QL_BLOCK, &result->qr_vals[pos]);
-
- result->qr_keys[pos+1].qk_idtype = idtype;
- result->qr_keys[pos+1].qk_objtype = QUOTA_OBJTYPE_FILES;
- q2e_to_quotaval(&q2e, 0, &result->qr_keys[pos+1].qk_id,
- QL_FILE, &result->qr_vals[pos+1]);
+ if (skipfirst == 0) {
+ result->qr_keys[pos].qk_idtype = idtype;
+ result->qr_keys[pos].qk_objtype = QUOTA_OBJTYPE_BLOCKS;
+ q2e_to_quotaval(&q2e, 0, &result->qr_keys[pos].qk_id,
+ QL_BLOCK, &result->qr_vals[pos]);
+ pos++;
+ }
+
+ if (skiplast == 0) {
+ result->qr_keys[pos].qk_idtype = idtype;
+ result->qr_keys[pos].qk_objtype = QUOTA_OBJTYPE_FILES;
+ q2e_to_quotaval(&q2e, 0, &result->qr_keys[pos].qk_id,
+ QL_FILE, &result->qr_vals[pos]);
+ pos++;
+ }
return 0;
}
@@ -997,6 +1004,7 @@ struct getuids {
uid_t *uids; /* array of uids, dynamically allocated */
long skip;
long seen;
+ long limit;
};
static int
@@ -1026,6 +1034,9 @@ quota2_getuids_callback(struct ufsmount
gu->uids[gu->nuids] = ufs_rw32(q2ep->q2e_uid, needswap);
gu->nuids++;
gu->seen++;
+ if (gu->nuids == gu->limit) {
+ return Q2WL_ABORT;
+ }
return 0;
}
@@ -1046,6 +1057,7 @@ quota2_handle_cmd_getall(struct ufsmount
id_t junkid;
struct quotaval qv;
unsigned num, maxnum;
+ int skipfirst, skiplast;
cursor = Q2CURSOR(qkc);
error = q2cursor_check(cursor);
@@ -1098,11 +1110,20 @@ quota2_handle_cmd_getall(struct ufsmount
gu.skip = cursor->q2c_uidpos;
gu.seen = 0;
+ gu.limit = result->qr_max / 2;
+ if (gu.limit == 0 && result->qr_max > 0) {
+ gu.limit = 1;
+ }
for (i = cursor->q2c_hashpos; i < quota2_hash_size ; i++) {
offset = q2h->q2h_entries[i];
gu.seen = 0;
error = quota2_walk_list(ump, hbp, idtype, &offset, 0, &gu,
quota2_getuids_callback);
+ if (error == Q2WL_ABORT) {
+ /* got enough uids for now */
+ error = 0;
+ break;
+ }
if (error) {
if (gu.uids != NULL)
free(gu.uids, M_TEMP);
@@ -1124,10 +1145,22 @@ fail:
result->qr_vals = malloc(maxnum * sizeof(result->qr_vals[0]),
M_TEMP, M_WAITOK);
+ /*
+ * If we've already sent back the blocks value for the first id,
+ * don't send it again (skipfirst).
+ *
+ * If we have an odd number of available result slots and we
+ * aren't going to skip the first result entry, we need to
+ * leave off the last result entry (skiplast).
+ */
+ skipfirst = (cursor->q2c_blocks_done != 0);
+ skiplast = skipfirst == 0 && (result->qr_max < maxnum);
num = 0;
for (j = 0; j < gu.nuids; j++) {
error = quota2_result_add_q2e(ump, idtype,
- gu.uids[j], result, j*2);
+ gu.uids[j], result, j*2,
+ j == 0 && skipfirst,
+ j + 1 == gu.nuids && skiplast);
if (error == ENOENT)
continue;
if (error)
@@ -1136,6 +1169,8 @@ fail:
}
result->qr_num = num;
+ cursor->q2c_blocks_done = skiplast;
+
free(gu.uids, M_TEMP);
return error;
}