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; }