Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern Use QUOTACTL_CURSORSKIPIDTYPE and QUOTACTL_CURSORAT...
details: https://anonhg.NetBSD.org/src/rev/358cb9939b7b
branches: trunk
changeset: 773201:358cb9939b7b
user: dholland <dholland%NetBSD.org@localhost>
date: Sun Jan 29 07:10:24 2012 +0000
description:
Use QUOTACTL_CURSORSKIPIDTYPE and QUOTACTL_CURSORATEND in
vfs_quotactl. Have it restart from the beginning if it receives
EDEADLK, which requires QUOTACTL_CURSORREWIND.
diffstat:
sys/kern/vfs_quotactl.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 79 insertions(+), 5 deletions(-)
diffs (150 lines):
diff -r 01c405e84130 -r 358cb9939b7b sys/kern/vfs_quotactl.c
--- a/sys/kern/vfs_quotactl.c Sun Jan 29 07:09:52 2012 +0000
+++ b/sys/kern/vfs_quotactl.c Sun Jan 29 07:10:24 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_quotactl.c,v 1.29 2012/01/29 07:09:52 dholland Exp $ */
+/* $NetBSD: vfs_quotactl.c,v 1.30 2012/01/29 07:10:24 dholland Exp $ */
/*
* Copyright (c) 1991, 1993, 1994
@@ -80,7 +80,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_quotactl.c,v 1.29 2012/01/29 07:09:52 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_quotactl.c,v 1.30 2012/01/29 07:10:24 dholland Exp $");
#include <sys/malloc.h> /* XXX: temporary */
#include <sys/mount.h>
@@ -529,8 +529,10 @@
struct quotaval *vals;
unsigned loopmax = 8;
unsigned loopnum;
+ int skipidtype;
struct vfs_quotactl_args args;
prop_array_t replies;
+ int atend, atzero;
struct quotakey *key;
struct quotaval *val;
id_t lastid;
@@ -550,6 +552,15 @@
keys = malloc(loopmax * sizeof(keys[0]), M_TEMP, M_WAITOK);
vals = malloc(loopmax * sizeof(vals[0]), M_TEMP, M_WAITOK);
+ skipidtype = (q2type == QUOTA_IDTYPE_USER ?
+ QUOTA_IDTYPE_GROUP : QUOTA_IDTYPE_USER);
+ args.qc_type = QCT_CURSORSKIPIDTYPE;
+ args.u.cursorskipidtype.qc_cursor = &cursor;
+ args.u.cursorskipidtype.qc_idtype = skipidtype;
+ error = VFS_QUOTACTL(mp, QUOTACTL_CURSORSKIPIDTYPE, &args);
+ /* ignore if it fails */
+ (void)error;
+
replies = prop_array_create();
if (replies == NULL) {
error = ENOMEM;
@@ -558,8 +569,20 @@
thisreply = NULL;
lastid = 0; /* value not actually referenced */
+ atzero = 0;
while (1) {
+ args.qc_type = QCT_CURSORATEND;
+ args.u.cursoratend.qc_cursor = &cursor;
+ args.u.cursoratend.qc_ret = &atend;
+ error = VFS_QUOTACTL(mp, QUOTACTL_CURSORATEND, &args);
+ if (error) {
+ goto err;
+ }
+ if (atend) {
+ break;
+ }
+
args.qc_type = QCT_CURSORGET;
args.u.cursorget.qc_cursor = &cursor;
args.u.cursorget.qc_keys = keys;
@@ -568,13 +591,58 @@
args.u.cursorget.qc_ret = &loopnum;
error = VFS_QUOTACTL(mp, QUOTACTL_CURSORGET, &args);
+ if (error == EDEADLK) {
+ /*
+ * transaction abort, start over
+ */
+
+ args.qc_type = QCT_CURSORREWIND;
+ args.u.cursorrewind.qc_cursor = &cursor;
+ error = VFS_QUOTACTL(mp, QUOTACTL_CURSORREWIND, &args);
+ if (error) {
+ goto err;
+ }
+
+ args.qc_type = QCT_CURSORSKIPIDTYPE;
+ args.u.cursorskipidtype.qc_cursor = &cursor;
+ args.u.cursorskipidtype.qc_idtype = skipidtype;
+ error = VFS_QUOTACTL(mp, QUOTACTL_CURSORSKIPIDTYPE,
+ &args);
+ /* ignore if it fails */
+ (void)error;
+
+ prop_object_release(replies);
+ replies = prop_array_create();
+ if (replies == NULL) {
+ error = ENOMEM;
+ goto err;
+ }
+
+ thisreply = NULL;
+ lastid = 0;
+ atzero = 0;
+
+ continue;
+ }
if (error) {
goto err;
}
if (loopnum == 0) {
- /* end of iteration */
- break;
+ /*
+ * This is not supposed to happen. However,
+ * allow a return of zero items once as long
+ * as something happens (including an atend
+ * indication) on the next pass. If it happens
+ * twice, warn and assume end of iteration.
+ */
+ if (atzero) {
+ printf("vfs_quotactl: zero items returned\n");
+ break;
+ }
+ atzero = 1;
+ } else {
+ atzero = 0;
}
for (i = 0; i < loopnum; i++) {
@@ -616,15 +684,21 @@
}
if (!prop_dictionary_set_and_rel(cmddict, "data", replies)) {
+ replies = NULL;
error = ENOMEM;
goto err;
}
+ replies = NULL;
+ error = 0;
- error = 0;
err:
free(keys, M_TEMP);
free(vals, M_TEMP);
+ if (replies != NULL) {
+ prop_object_release(replies);
+ }
+
args.qc_type = QCT_CURSORCLOSE;
args.u.cursorclose.qc_cursor = &cursor;
error2 = VFS_QUOTACTL(mp, QUOTACTL_CURSORCLOSE, &args);
Home |
Main Index |
Thread Index |
Old Index