Module Name:    src
Committed By:   dholland
Date:           Wed Feb  1 05:10:45 UTC 2012

Modified Files:
        src/sys/ufs/ufs: ufs_quota2.c

Log Message:
Fix problems in cursor iteration that came to light when iterating one
value at a time, instead of in bulk. Yeah, repquota should do bulk get,
but it doesn't yet.


To generate a diff of this commit:
cvs rdiff -u -r1.30 -r1.31 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/ufs/ufs/ufs_quota2.c
diff -u src/sys/ufs/ufs/ufs_quota2.c:1.30 src/sys/ufs/ufs/ufs_quota2.c:1.31
--- src/sys/ufs/ufs/ufs_quota2.c:1.30	Sun Jan 29 07:21:00 2012
+++ src/sys/ufs/ufs/ufs_quota2.c	Wed Feb  1 05:10:44 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_quota2.c,v 1.30 2012/01/29 07:21:00 dholland Exp $ */
+/* $NetBSD: ufs_quota2.c,v 1.31 2012/02/01 05:10:44 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.30 2012/01/29 07:21:00 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_quota2.c,v 1.31 2012/02/01 05:10:44 dholland Exp $");
 
 #include <sys/buf.h>
 #include <sys/param.h>
@@ -1158,7 +1158,10 @@ q2cursor_getkeys(struct ufsmount *ump, i
 	/* If we haven't done the defaults yet, that goes first. */
 	if (cursor->q2c_defaults_done == 0) {
 		q2cursor_addid(state, idtype, QUOTA_DEFAULTID);
-		cursor->q2c_defaults_done = 1;
+		/* if we read both halves, mark it done */
+		if (state->numids < state->maxids || !state->skiplast) {
+			cursor->q2c_defaults_done = 1;
+		}
 	}
 
 	gi.state = state;
@@ -1181,14 +1184,22 @@ q2cursor_getkeys(struct ufsmount *ump, i
 		if (error == Q2WL_ABORT) {
 			/* callback stopped before reading whole chain */
 			cursor->q2c_uidpos = gi.new_skip;
+			/* if we didn't get both halves, back up */
+			if (state->numids == state->maxids && state->skiplast){
+				KASSERT(cursor->q2c_uidpos > 0);
+				cursor->q2c_uidpos--;
+			}
 			/* not an error */
 			error = 0;
 		} else if (error) {
 			break;
 		} else {
-			/* read whole chain, advance to next */
-			cursor->q2c_uidpos = 0;
-			cursor->q2c_hashpos++;
+			/* read whole chain */
+			/* if we got both halves of the last id, advance */
+			if (state->numids < state->maxids || !state->skiplast){
+				cursor->q2c_uidpos = 0;
+				cursor->q2c_hashpos++;
+			}
 		}
 	}
 

Reply via email to