[DRBD-cvs] DRBD CVS: drbd by phil from

drbd-user@lists.linbit.com drbd-user@lists.linbit.com
Fri, 16 Jan 2004 14:26:43 +0100 (CET)


DRBD CVS committal

Author  : phil
Host    : 
Module  : drbd

Dir     : drbd/drbd


Modified Files:
      Tag: rel-0_7-branch
	drbd_actlog.c drbd_int.h drbd_receiver.c drbd_req-2.4.c 


Log Message:
Removed the may_sleep parameter of drbd_set_in_sync(). Now the 
function _never_ sleeps, now it passes IO on to the worker thread by
the drbd_work infrastructure. -- Removes a case where the asender
could sleep outside its 'sleeping point'.

===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/Attic/drbd_actlog.c,v
retrieving revision 1.1.2.55
retrieving revision 1.1.2.56
diff -u -3 -r1.1.2.55 -r1.1.2.56
--- drbd_actlog.c	16 Jan 2004 12:35:44 -0000	1.1.2.55
+++ drbd_actlog.c	16 Jan 2004 13:26:43 -0000	1.1.2.56
@@ -45,6 +45,12 @@
        // transactions with correct xor_sums are considered.
 };     // sizeof() = 512 byte
 
+
+struct update_odbm_work {
+	struct drbd_work w;
+	unsigned int enr;
+};
+
 STATIC void drbd_al_write_transaction(struct Drbd_Conf *,struct lc_element *);
 STATIC void drbd_update_on_disk_bm(struct Drbd_Conf *,unsigned int ,int);
 
@@ -494,13 +500,34 @@
 #undef BM_WORDS_PER_EXTENT
 #undef EXTENTS_PER_SECTOR
 
+STATIC int w_update_odbm(drbd_dev *mdev, struct drbd_work *w)
+{
+	struct update_odbm_work *udw = (struct update_odbm_work*)w;
+
+	drbd_update_on_disk_bm(mdev,udw->enr,1);
+
+	kfree(udw);
+
+	if(mdev->rs_left == 0) {
+		D_ASSERT( mdev->resync_work.cb == w_resync_inactive );
+		// Could also call directly. This runs in worker's context.
+		mdev->resync_work.cb = w_resync_finished;
+		__drbd_queue_work(mdev,&mdev->data.work,&mdev->resync_work);
+	}
+	
+	return 1;
+}
+
 /* ATTENTION. The AL's extents are 4MB each, while the extents in the  *
  * resync LRU-cache are 16MB each.                                     */
 STATIC void drbd_try_clear_on_disk_bm(struct Drbd_Conf *mdev,sector_t sector,
-				      int cleared,int may_sleep)
+				      int cleared)
 {
+	struct list_head *le;
 	struct bm_extent* ext;
-	unsigned long enr;
+	struct update_odbm_work * udw;
+
+	unsigned int enr;
 	unsigned long flags;
 
 	// I simply assume that a sector/size pair never crosses
@@ -522,53 +549,45 @@
 				// pulled it already in.
 			}
 			ext->rs_left = bm_count_sectors(mdev->mbds_id,enr);
-			lc_changed(mdev->resync,(struct lc_element*)ext);
+			lc_changed(mdev->resync,&ext->lce);
 		}
-		lc_put(mdev->resync,(struct lc_element*)ext);
+		lc_put(mdev->resync,&ext->lce);
 	} else {
 		ERR("lc_get() failed! Probabely something stays"
 		    " dirty in the on disk BM\n");
 	}
-	spin_unlock_irqrestore(&mdev->al_lock,flags);
-
-	if(may_sleep) {
-		struct list_head *le;
 
-		spin_lock(&mdev->al_lock);
-	restart:
-		list_for_each(le,&mdev->resync->lru) {
-			ext=(struct bm_extent *)list_entry(le,struct lc_element,list);
-			if(ext->rs_left == 0) {
-				ERR_IF(ext->lce.refcnt) continue;
-				spin_unlock(&mdev->al_lock);
-				drbd_update_on_disk_bm(mdev,enr*SM,1);
-				// TODO: reconsider to use the async version
-				// of drbd_update_on_disk_bm()
-				//INFO("Clearing e# %lu of on disk bm\n",enr);
-				spin_lock(&mdev->al_lock);
-				lc_del(mdev->resync,&ext->lce);
-				goto restart;
+	list_for_each(le,&mdev->resync->lru) {
+		ext=(struct bm_extent *)list_entry(le,struct lc_element,list);
+		if(ext->rs_left == 0) {
+			ERR_IF(ext->lce.refcnt) continue;
+			udw=kmalloc(sizeof(*udw),GFP_ATOMIC);
+			if(!udw) {
+				WARN("Could not kmalloc an udw\n");
+				break;
 			}
+			udw->enr = enr*SM;
+			udw->w.cb = w_update_odbm;
+			__drbd_queue_work(mdev,&mdev->data.work,&udw->w);
+			lc_del(mdev->resync,&ext->lce);
 		}
-		spin_unlock(&mdev->al_lock);
 	}
+
+	spin_unlock_irqrestore(&mdev->al_lock,flags);
 }
 
-void drbd_set_in_sync(drbd_dev* mdev, sector_t sector,
-		      int blk_size, int may_sleep)
+void drbd_set_in_sync(drbd_dev* mdev, sector_t sector, int blk_size)
 {
 	/* Is called by drbd_dio_end possibly from IRQ context, but
 	   from other places in non IRQ */
 	unsigned long flags=0;
 	int cleared;
-	int finished=0;
 
 	cleared = bm_set_bit(mdev, sector, blk_size, SS_IN_SYNC);
 
 	spin_lock_irqsave(&mdev->al_lock,flags);
 	mdev->rs_left -= cleared;
 	D_ASSERT((long)mdev->rs_left >= 0);
-	if( cleared && mdev->rs_left == 0 ) finished=1;
 
 	if( cleared == 0 ) {
 		WARN("cleared == 0; sector = %lu\n",sector);
@@ -580,14 +599,7 @@
 	}
 	spin_unlock_irqrestore(&mdev->al_lock,flags);
 
-	drbd_try_clear_on_disk_bm(mdev,sector,cleared,may_sleep);
-
-	if( finished ) {
-		// This must be after the last call to clear_on_disk_bm() !
-		D_ASSERT( mdev->resync_work.cb == w_resync_inactive );
-		mdev->resync_work.cb = w_resync_finished;
-		__drbd_queue_work(mdev,&mdev->data.work,&mdev->resync_work);
-	}
+	drbd_try_clear_on_disk_bm(mdev,sector,cleared);
 }
 
 
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/drbd_int.h,v
retrieving revision 1.58.2.94
retrieving revision 1.58.2.95
diff -u -3 -r1.58.2.94 -r1.58.2.95
--- drbd_int.h	16 Jan 2004 12:35:44 -0000	1.58.2.94
+++ drbd_int.h	16 Jan 2004 13:26:43 -0000	1.58.2.95
@@ -903,8 +903,7 @@
 extern void drbd_rs_complete_io(struct Drbd_Conf *mdev, sector_t sector);
 extern void drbd_rs_begin_io(struct Drbd_Conf *mdev, sector_t sector);
 extern void drbd_al_read_log(struct Drbd_Conf *mdev);
-extern void drbd_set_in_sync(drbd_dev* mdev, sector_t sector,
-			     int blk_size, int may_sleep);
+extern void drbd_set_in_sync(drbd_dev* mdev, sector_t sector,int blk_size);
 extern void drbd_read_bm(struct Drbd_Conf *mdev);
 extern void drbd_al_apply_to_bm(struct Drbd_Conf *mdev);
 extern void drbd_al_to_on_disk_bm(struct Drbd_Conf *mdev);
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/drbd_receiver.c,v
retrieving revision 1.97.2.85
retrieving revision 1.97.2.86
diff -u -3 -r1.97.2.85 -r1.97.2.86
--- drbd_receiver.c	16 Jan 2004 10:09:19 -0000	1.97.2.85
+++ drbd_receiver.c	16 Jan 2004 13:26:43 -0000	1.97.2.86
@@ -784,7 +784,7 @@
 	if( is_syncer_blk(mdev,p->block_id)) {
 		drbd_set_in_sync(mdev,
 				 be64_to_cpu(p->sector),
-				 be32_to_cpu(p->blksize),1);
+				 be32_to_cpu(p->blksize));
 	} else {
 		req=(drbd_request_t*)(long)p->block_id;
 
@@ -931,7 +931,7 @@
 STATIC int e_end_resync_block(drbd_dev *mdev, struct drbd_work *w)
 {
 	struct Tl_epoch_entry *e = (struct Tl_epoch_entry*)w;
-	drbd_set_in_sync(mdev,e->pbh.b_blocknr,e->pbh.b_size,1);
+	drbd_set_in_sync(mdev,e->pbh.b_blocknr,e->pbh.b_size);
 	drbd_send_ack(mdev,WriteAck,e);
 	dec_unacked(mdev,HERE); // FIXME unconditional ??
 	return TRUE;
@@ -1102,7 +1102,7 @@
 	if(mdev->conf.wire_protocol == DRBD_PROT_C) {
 		if( mdev->cstate > Connected ) {
 			drbd_set_in_sync(mdev,e->pbh.b_blocknr,
-					 e->pbh.b_size,1);
+					 e->pbh.b_size);
 		}
 		ok=drbd_send_ack(mdev,WriteAck,e);
 		dec_unacked(mdev,HERE); // FIXME unconditional ??
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/drbd_req-2.4.c,v
retrieving revision 1.33.2.37
retrieving revision 1.33.2.38
diff -u -3 -r1.33.2.37 -r1.33.2.38
--- drbd_req-2.4.c	14 Jan 2004 06:42:22 -0000	1.33.2.37
+++ drbd_req-2.4.c	16 Jan 2004 13:26:43 -0000	1.33.2.38
@@ -78,7 +78,7 @@
 	}
 
 	if(mdev->conf.wire_protocol==DRBD_PROT_C && mdev->cstate > Connected) {
-		drbd_set_in_sync(mdev,rsector,req->bh->b_size,0);
+		drbd_set_in_sync(mdev,rsector,req->bh->b_size);
 	}
 
 	req->bh->b_end_io(req->bh,(req->rq_status & 0x0001));