Module Name:    src
Committed By:   reinoud
Date:           Thu Jul  2 16:56:35 UTC 2009

Modified Files:
        src/sys/fs/udf: udf_strat_rmw.c

Log Message:
Enhance dumping on buffer screwup. Also prevent races or invalid combinations
to exist for ecclines.


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/sys/fs/udf/udf_strat_rmw.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/fs/udf/udf_strat_rmw.c
diff -u src/sys/fs/udf/udf_strat_rmw.c:1.19 src/sys/fs/udf/udf_strat_rmw.c:1.20
--- src/sys/fs/udf/udf_strat_rmw.c:1.19	Wed May 20 15:30:26 2009
+++ src/sys/fs/udf/udf_strat_rmw.c	Thu Jul  2 16:56:35 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: udf_strat_rmw.c,v 1.19 2009/05/20 15:30:26 reinoud Exp $ */
+/* $NetBSD: udf_strat_rmw.c,v 1.20 2009/07/02 16:56:35 reinoud Exp $ */
 
 /*
  * Copyright (c) 2006, 2008 Reinoud Zandijk
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__KERNEL_RCSID(0, "$NetBSD: udf_strat_rmw.c,v 1.19 2009/05/20 15:30:26 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udf_strat_rmw.c,v 1.20 2009/07/02 16:56:35 reinoud Exp $");
 #endif /* not lint */
 
 
@@ -242,22 +242,26 @@
 	if (curqueue) {
 		ret = bufq_cancel(priv->queues[curqueue], eccline->buf);
 
-		DPRINTF(PARANOIA, ("push_eccline bufq_cancel returned %p when "
-			"requested to remove %p from queue %d\n", ret,
-			eccline->buf, curqueue));
 #ifdef DIAGNOSTIC
 		if (ret == NULL) {
 			int i;
 
 			printf("udf_push_eccline: bufq_cancel can't find "
-				"buffer; dumping queues\n");
+				"buffer %p on queue %d; "
+				"dumping queues\n", eccline->buf, curqueue);
 			for (i = 1; i < UDF_SHED_MAX; i++) {
 				printf("queue %d\n\t", i);
 				ret = bufq_get(priv->queues[i]);
 				while (ret) {
 					printf("%p ", ret);
+					if (BTOE(ret)->queued_on != i)
+						printf("WRONGQ ");
 					if (ret == eccline->buf)
 						printf("[<-] ");
+					if (ret == bufq_peek(priv->queues[i])) {
+						printf("LOOP ");
+						break;
+					}
 					ret = bufq_get(priv->queues[i]);
 				}
 				printf("\n");
@@ -275,9 +279,9 @@
 	eccline->buf->b_blkno    = eccline->start_sector;
 	eccline->buf->b_rawblkno = eccline->start_sector;
 
-	bufq_put(priv->queues[newqueue], eccline->buf);
 	eccline->queued_on = newqueue;
 	priv->num_queued[newqueue]++;
+	bufq_put(priv->queues[newqueue], eccline->buf);
 	vfs_timestamp(&priv->last_queued[newqueue]);
 
 	if (eccline->flags & ECC_FLOATING) {
@@ -300,7 +304,7 @@
 	KASSERT(mutex_owned(&priv->discstrat_mutex));
 
 	buf = bufq_get(priv->queues[queued_on]);
-	if (!buf) {
+	if (buf == NULL) {
 		KASSERT(priv->num_queued[queued_on] == 0);
 		return NULL;
 	}
@@ -390,9 +394,11 @@
 				&priv->discstrat_mutex, hz/8);
 			goto retry;
 		}
-		/* push back line if we're waiting for it */
-		if (eccline->flags & ECC_WANTED) {
-			udf_push_eccline(eccline, UDF_SHED_IDLE);
+
+		/* push back line if we're waiting for it or its locked */
+		if (eccline->flags & (ECC_WANTED | ECC_LOCKED)) {
+			/* XXX what were they doing on the free list anyway? */
+			udf_push_eccline(eccline, UDF_SHED_WAITING);
 			goto retry;
 		}
 
@@ -1002,6 +1008,7 @@
 	 */
 
 	udf_puteccline(eccline);
+
 	DPRINTF(ECCLINE, ("read callback finished\n"));
 }
 
@@ -1014,7 +1021,7 @@
 	uint64_t bit;
 	int error, i, len;
 
-	DPRINTF(ECCLINE, ("write callback called\n"));
+	DPRINTF(ECCLINE, ("write callback called buf %p\n", buf));
 	/* post process write action */
 	error = buf->b_error;
 	for (i = 0; i < ump->packet_size; i++) {
@@ -1179,16 +1186,18 @@
 						new_queue = UDF_SHED_READING;
 				}
 			}
+			if (eccline->flags & ECC_LOCKED)
+				new_queue = UDF_SHED_WAITING;
 			udf_push_eccline(eccline, new_queue);
 			cnt++;
 		}
 
-		/* maintenance: free exess ecclines */
+		/* maintenance: free excess ecclines */
 		while (priv->num_queued[UDF_SHED_FREE] > UDF_ECCLINE_MAXFREE) {
 			eccline = udf_pop_eccline(priv, UDF_SHED_FREE);
 			KASSERT(eccline);
 			KASSERT(eccline->refcnt == 0);
-			if (eccline->flags & ECC_WANTED) {
+			if (eccline->flags & (ECC_WANTED | ECC_LOCKED)) {
 				udf_push_eccline(eccline, UDF_SHED_IDLE);
 				DPRINTF(ECCLINE, ("Tried removing, pushed back to free list\n"));
 			} else {

Reply via email to