[DRBD-cvs] svn commit by phil - r2305 - trunk/drbd - Finally found and fixed that terribly bug that tortured

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Fri Jul 28 12:41:11 CEST 2006


Author: phil
Date: 2006-07-28 12:41:09 +0200 (Fri, 28 Jul 2006)
New Revision: 2305

Modified:
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_req.c
   trunk/drbd/drbd_worker.c
Log:
Finally found and fixed that terribly bug that tortured me te last
days. 

The w_send_dblock() could run even after tl_clear() ...


Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-07-28 07:38:43 UTC (rev 2304)
+++ trunk/drbd/drbd_main.c	2006-07-28 10:41:09 UTC (rev 2305)
@@ -211,7 +211,7 @@
 	b=mdev->newest_barrier;
 
 	req->barrier = b;
-	req->rq_status |= RQ_DRBD_IN_TL;
+	req->rq_status |= RQ_DRBD_IN_TL; /* BUG, not holding req_lock */
 	list_add(&req->tl_requests,&b->requests);
 
 	if( b->n_req++ > mdev->net_conf->max_epoch_size ) {

Modified: trunk/drbd/drbd_req.c
===================================================================
--- trunk/drbd/drbd_req.c	2006-07-28 07:38:43 UTC (rev 2304)
+++ trunk/drbd/drbd_req.c	2006-07-28 10:41:09 UTC (rev 2305)
@@ -32,6 +32,22 @@
 #include <linux/drbd.h>
 #include "drbd_int.h"
 
+/*
+void drbd_show_req(struct Drbd_Conf* mdev, char *txt, drbd_request_t *req)
+{
+	INFO("req %s %p %c%c%c%c%c %p\n",
+	     txt,
+	     req,
+	     req->rq_status & RQ_DRBD_ON_WIRE ? 'w' :'_',
+	     req->rq_status & RQ_DRBD_IN_TL   ? 't' :'_',
+	     req->rq_status & RQ_DRBD_SENT    ? 's' :'_',
+	     req->rq_status & RQ_DRBD_LOCAL   ? 'l' :'_',
+	     req->rq_status & RQ_DRBD_NOTHING ? 'u' :'_',
+	     req->barrier
+	     );
+}
+*/
+
 void drbd_end_req(drbd_request_t *req, int nextstate, int er_flags,
 		  sector_t rsector)
 {
@@ -205,6 +221,7 @@
 		req->mdev        = mdev;
 		req->master_bio  = bio_src;
 		req->private_bio = bio;
+		req->barrier     = NULL;
 
 		bio->bi_private  = req;
 		bio->bi_end_io   =
@@ -326,6 +343,8 @@
 	// inc_ap_bio(mdev); do not allow more open requests than max_buffers!
 	wait_event( mdev->rq_wait,atomic_add_unless(&mdev->ap_bio_cnt,1,mxb) );
 
+	/* remote might be already wrong here, since we might slept after
+	   looking at the connection state, but this is ok. */
 	if (remote) {
 		/* either WRITE and Connected,
 		 * or READ, and no local disk,

Modified: trunk/drbd/drbd_worker.c
===================================================================
--- trunk/drbd/drbd_worker.c	2006-07-28 07:38:43 UTC (rev 2304)
+++ trunk/drbd/drbd_worker.c	2006-07-28 10:41:09 UTC (rev 2305)
@@ -559,10 +559,21 @@
 int w_send_dblock(drbd_dev *mdev, struct drbd_work *w, int cancel)
 {
 	drbd_request_t *req = (drbd_request_t *)w;
+	sector_t sector;
+	unsigned int size;
 	int ok;
 
-	if (unlikely(cancel)) { 
-		/* Nothing to do, here. tl_clear() does the work. */
+	D_ASSERT( !(req->rq_status & RQ_DRBD_SENT) );
+
+	if (unlikely(cancel)) {
+		/* We clear it up here explicit, since we might be _after_ the
+		   run of tl_clear() */
+		sector = drbd_req_get_sector(req);
+		size   = drbd_req_get_size(req);
+
+		drbd_end_req(req,RQ_DRBD_SENT,1, sector);
+		drbd_set_out_of_sync(mdev, sector, size);
+
 		return 1;
 	}
 
@@ -583,6 +594,7 @@
 		if (mdev->state.conn >= Connected) 
 			drbd_force_state(mdev,NS(conn,NetworkFailure));
 		drbd_thread_restart_nowait(&mdev->receiver);
+		/* The request gets cleared up by tl_clear() */
 	}
 
 	return ok;



More information about the drbd-cvs mailing list