[DRBD-cvs] drbd by phil; * Implemented the cleanup of the workque...

drbd-user@lists.linbit.com drbd-user@lists.linbit.com
Sun, 14 Mar 2004 20:32:53 +0100 (CET)


DRBD CVS committal

Author  : phil
Module  : drbd

Dir     : drbd/drbd


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


Log Message:
* Implemented the cleanup of the workqueue. For this all work
  callbacks got a new parameter "cancel". If the queue is cleaned
  up cancel is set to 1.
    

===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/Attic/drbd_actlog.c,v
retrieving revision 1.1.2.77
retrieving revision 1.1.2.78
diff -u -3 -r1.1.2.77 -r1.1.2.78
--- drbd_actlog.c	11 Mar 2004 13:50:16 -0000	1.1.2.77
+++ drbd_actlog.c	14 Mar 2004 19:32:47 -0000	1.1.2.78
@@ -566,7 +566,7 @@
 #undef BM_WORDS_PER_EXTENT
 #undef EXTENTS_PER_SECTOR
 
-STATIC int w_update_odbm(drbd_dev *mdev, struct drbd_work *w)
+STATIC int w_update_odbm(drbd_dev *mdev, struct drbd_work *w, int unused)
 {
 	struct update_odbm_work *udw = (struct update_odbm_work*)w;
 
@@ -582,9 +582,7 @@
 
 	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);
+		drbd_resync_finished(mdev);
 	}
 
 	return 1;
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/Attic/drbd_dsender.c,v
retrieving revision 1.1.2.84
retrieving revision 1.1.2.85
diff -u -3 -r1.1.2.84 -r1.1.2.85
--- drbd_dsender.c	11 Mar 2004 13:50:16 -0000	1.1.2.84
+++ drbd_dsender.c	14 Mar 2004 19:32:47 -0000	1.1.2.85
@@ -346,31 +346,35 @@
 }
 #endif
 
-int w_read_retry_remote(drbd_dev* mdev, struct drbd_work* w)
+int w_read_retry_remote(drbd_dev* mdev, struct drbd_work* w,int cancel)
 {
 	drbd_request_t *req = (drbd_request_t*)w;
+	int ok;
 
-	if ( mdev->cstate <= Connected ||
+	if ( cancel || 
+	     mdev->cstate <= Connected ||
 	     test_bit(PARTNER_DISKLESS,&mdev->flags) ) {
 		ERR("WE ARE LOST. Local IO failure, no peer.\n");
 		drbd_bio_endio(req->master_bio,0);
+		mempool_free(req,drbd_request_mempool);
 		// TODO: Do something like panic() or shut_down_cluster().
 		return 1;
 	}
 
 	// FIXME: what if partner was SyncTarget, and is out of sync for
 	// this area ?? ... should be handled in the receiver.
-	drbd_read_remote(mdev,req);
-	return 1;
+	ok = drbd_read_remote(mdev,req);
+	if(unlikely(!ok)) ERR("drbd_read_remote() failed\n");
+	return ok;
 }
 
-int w_resync_inactive(drbd_dev *mdev, struct drbd_work *w)
+int w_resync_inactive(drbd_dev *mdev, struct drbd_work *w, int unused)
 {
 	ERR("resync inactive, but callback triggered??\n");
 	return 0;
 }
 
-int w_is_resync_read(drbd_dev *mdev, struct drbd_work *w)
+int w_is_resync_read(drbd_dev *mdev, struct drbd_work *w, int unused)
 {
 	ERR("%s: Typecheck only, should never be called!\n", __FUNCTION__ );
 	return 0;
@@ -379,7 +383,7 @@
 /* in case we need it. currently unused,
  * since should be assigned to "w_read_retry_remote"
  */
-int w_is_app_read(drbd_dev *mdev, struct drbd_work *w)
+int w_is_app_read(drbd_dev *mdev, struct drbd_work *w, int unused)
 {
 	ERR("%s: Typecheck only, should never be called!\n", __FUNCTION__ );
 	return 0;
@@ -396,14 +400,15 @@
 	}
 }
 
-int w_make_resync_request(drbd_dev* mdev, struct drbd_work* w)
+int w_make_resync_request(drbd_dev* mdev, struct drbd_work* w,int cancel)
 {
 	sector_t sector;
 	int number,i,size;
 
 	PARANOIA_BUG_ON(w != &mdev->resync_work);
 
-	if(mdev->cstate < Connected ) return 1; // connection was lost...
+	if(unlikely(cancel)) return 1;
+	if(unlikely(mdev->cstate < Connected)) return 0;
 
 	D_ASSERT(mdev->cstate == SyncTarget);
 
@@ -454,12 +459,11 @@
 	return 1;
 }
 
-int w_resync_finished(drbd_dev* mdev, struct drbd_work* w)
+int drbd_resync_finished(drbd_dev* mdev)
 {
 	unsigned long dt;
 	sector_t n;
 
-	PARANOIA_BUG_ON(w != &mdev->resync_work);
 	D_ASSERT(mdev->rs_left == 0);
 
 	dt = (jiffies - mdev->rs_start) / HZ + 1;
@@ -482,11 +486,18 @@
 	return 1;
 }
 
-int w_e_end_data_req(drbd_dev *mdev, struct drbd_work *w)
+int w_e_end_data_req(drbd_dev *mdev, struct drbd_work *w, int cancel)
 {
 	struct Tl_epoch_entry *e = (struct Tl_epoch_entry*)w;
 	int ok;
 
+	if(unlikely(cancel)) {
+		spin_lock_irq(&mdev->ee_lock);
+		drbd_put_ee(mdev,e);
+		spin_unlock_irq(&mdev->ee_lock);
+		return 1;
+	}
+
 	if(likely(drbd_bio_uptodate(&e->private_bio))) {
 		ok=drbd_send_block(mdev, DataReply, e);
 	} else {
@@ -505,11 +516,18 @@
 	return ok;
 }
 
-int w_e_end_rsdata_req(drbd_dev *mdev, struct drbd_work *w)
+int w_e_end_rsdata_req(drbd_dev *mdev, struct drbd_work *w, int cancel)
 {
 	struct Tl_epoch_entry *e = (struct Tl_epoch_entry*)w;
 	int ok;
 
+	if(unlikely(cancel)) {
+		spin_lock_irq(&mdev->ee_lock);
+		drbd_put_ee(mdev,e);
+		spin_unlock_irq(&mdev->ee_lock);
+		return 1;
+	}
+
 	drbd_rs_complete_io(mdev,drbd_ee_get_sector(e));
 
 	if(likely(drbd_bio_uptodate(&e->private_bio))) {
@@ -617,7 +635,7 @@
 	return rv;
 }
 
-int w_resume_next_sg(drbd_dev* mdev, struct drbd_work* w)
+int w_resume_next_sg(drbd_dev* mdev, struct drbd_work* w, int unused)
 {
 	drbd_dev *odev;
 	int i,ng=10000;
@@ -688,8 +706,7 @@
 	PARANOIA_BUG_ON(mdev->resync_work.cb != w_resync_inactive);
 
 	if ( mdev->rs_left == 0 ) {
-		mdev->resync_work.cb = w_resync_finished;
-		drbd_queue_work(mdev,&mdev->data.work,&mdev->resync_work);
+		drbd_resync_finished(mdev);
 		return;
 	}
 
@@ -716,7 +733,7 @@
 int drbd_worker(struct Drbd_thread *thi)
 {
 	drbd_dev *mdev = thi->mdev;
-	struct drbd_work *w;
+	struct drbd_work *w = 0;
 	int intr;
 
 	sprintf(current->comm, "drbd%d_worker", (int)(mdev-drbd_conf));
@@ -740,7 +757,7 @@
 		if (need_resched())
 			schedule();
 
-		w = NULL;
+		w = 0;
 		spin_lock_irq(&mdev->req_lock);
 		if (!list_empty(&mdev->data.work.q)) {
 			w = list_entry(mdev->data.work.q.next,struct drbd_work,list);
@@ -748,14 +765,27 @@
 		}
 		spin_unlock_irq(&mdev->req_lock);
 
-		ERR_IF (!w)
-			continue; // BUG()... racy up() somewhere ??
+		if(!w->cb(mdev,w,0)) goto err;
+	}
 
-		ERR_IF ( !w->cb(mdev,w) )
-			break;
+	if(0) {
+	err:
+		drbd_thread_restart_nowait(&mdev->receiver);
+	}
+
+	while(!down_trylock(&mdev->data.work.s)) {
+		spin_lock_irq(&mdev->req_lock);
+		if (!list_empty(&mdev->data.work.q)) {
+			w = list_entry(mdev->data.work.q.next,
+				       struct drbd_work,list);
+			list_del_init(&w->list);
+		}
+		spin_unlock_irq(&mdev->req_lock);
+		
+		w->cb(mdev,w,1);
 	}
 
-	del_timer_sync(&mdev->resync_timer); // just in case... 
+	del_timer_sync(&mdev->resync_timer); // just in case...
 	INFO("worker terminated\n");
 
 	return 0;
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/drbd_int.h,v
retrieving revision 1.58.2.137
retrieving revision 1.58.2.138
diff -u -3 -r1.58.2.137 -r1.58.2.138
--- drbd_int.h	11 Mar 2004 13:50:16 -0000	1.58.2.137
+++ drbd_int.h	14 Mar 2004 19:32:47 -0000	1.58.2.138
@@ -472,7 +472,7 @@
  * Pending_read will soon be merged into drbd_request, stay tuned ... -lge
  */
 struct drbd_work;
-typedef int (*drbd_work_cb)(drbd_dev*, struct drbd_work*);
+typedef int (*drbd_work_cb)(drbd_dev*, struct drbd_work*, int cancel);
 struct drbd_work {
 	struct list_head list;
 	drbd_work_cb cb;
@@ -816,7 +816,7 @@
 #else
 extern int drbd_make_request_26(request_queue_t *q, struct bio *bio);
 #endif
-extern void drbd_read_remote(drbd_dev *mdev, drbd_request_t *req);
+extern int drbd_read_remote(drbd_dev *mdev, drbd_request_t *req);
 
 // drbd_fs.c
 extern int drbd_determin_dev_size(drbd_dev*);
@@ -828,17 +828,17 @@
 extern int drbd_worker(struct Drbd_thread *thi);
 extern void drbd_alter_sg(drbd_dev *mdev, int ng);
 extern void drbd_start_resync(drbd_dev *mdev, Drbd_CState side);
+extern int drbd_resync_finished(drbd_dev *mdev);
 // maybe rather drbd_main.c ?
 extern int drbd_md_sync_page_io(drbd_dev *mdev, sector_t sector, int rw);
 // worker callbacks
-extern int w_is_app_read         (drbd_dev *mdev, struct drbd_work *w);
-extern int w_is_resync_read      (drbd_dev *mdev, struct drbd_work *w);
-extern int w_read_retry_remote   (drbd_dev *mdev, struct drbd_work *w);
-extern int w_e_end_data_req      (drbd_dev *mdev, struct drbd_work *w);
-extern int w_e_end_rsdata_req    (drbd_dev *mdev, struct drbd_work *w);
-extern int w_resync_finished     (drbd_dev *mdev, struct drbd_work *w);
-extern int w_resync_inactive     (drbd_dev *mdev, struct drbd_work *w);
-extern int w_resume_next_sg      (drbd_dev *mdev, struct drbd_work *w);
+extern int w_is_app_read         (drbd_dev *, struct drbd_work *, int);
+extern int w_is_resync_read      (drbd_dev *, struct drbd_work *, int);
+extern int w_read_retry_remote   (drbd_dev *, struct drbd_work *, int);
+extern int w_e_end_data_req      (drbd_dev *, struct drbd_work *, int);
+extern int w_e_end_rsdata_req    (drbd_dev *, struct drbd_work *, int);
+extern int w_resync_inactive     (drbd_dev *, struct drbd_work *, int);
+extern int w_resume_next_sg      (drbd_dev *, struct drbd_work *, int);
 
 
 // drbd_receiver.c
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/drbd_receiver.c,v
retrieving revision 1.97.2.123
retrieving revision 1.97.2.124
diff -u -3 -r1.97.2.123 -r1.97.2.124
--- drbd_receiver.c	11 Mar 2004 13:50:16 -0000	1.97.2.123
+++ drbd_receiver.c	14 Mar 2004 19:32:47 -0000	1.97.2.124
@@ -334,7 +334,7 @@
 		list_del(le);
 		spin_unlock_irq(&mdev->ee_lock);
 		e = list_entry(le, struct Tl_epoch_entry, w.list);
-		ok = ok && e->w.cb(mdev,&e->w);
+		ok = ok && e->w.cb(mdev,&e->w,0);
 		spin_lock_irq(&mdev->ee_lock);
 		drbd_put_ee(mdev,e);
 	}
@@ -772,7 +772,7 @@
 	return ok;
 }
 
-STATIC int e_end_resync_block(drbd_dev *mdev, struct drbd_work *w)
+STATIC int e_end_resync_block(drbd_dev *mdev, struct drbd_work *w, int unused)
 {
 	struct Tl_epoch_entry *e = (struct Tl_epoch_entry*)w;
 	sector_t sector = drbd_ee_get_sector(e);
@@ -891,7 +891,7 @@
 	return ok;
 }
 
-STATIC int e_end_block(drbd_dev *mdev, struct drbd_work *w)
+STATIC int e_end_block(drbd_dev *mdev, struct drbd_work *w, int unused)
 {
 	struct Tl_epoch_entry *e = (struct Tl_epoch_entry*)w;
 	sector_t sector = drbd_ee_get_sector(e);
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/drbd_req-2.4.c,v
retrieving revision 1.33.2.58
retrieving revision 1.33.2.59
diff -u -3 -r1.33.2.58 -r1.33.2.59
--- drbd_req-2.4.c	11 Mar 2004 13:50:17 -0000	1.33.2.58
+++ drbd_req-2.4.c	14 Mar 2004 19:32:48 -0000	1.33.2.59
@@ -97,8 +97,9 @@
 		wake_asender(mdev);
 }
 
-void drbd_read_remote(drbd_dev *mdev, drbd_request_t *req)
+int drbd_read_remote(drbd_dev *mdev, drbd_request_t *req)
 {
+	int rv;
 	drbd_bio_t *bio = req->master_bio;
 
 	spin_lock(&mdev->pr_lock);
@@ -106,12 +107,13 @@
 	spin_unlock(&mdev->pr_lock);
 	inc_ap_pending(mdev);
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	drbd_send_drequest(mdev, DataRequest, bio->b_rsector, bio->b_size,
-			   (unsigned long)req);
+	rv=drbd_send_drequest(mdev, DataRequest, bio->b_rsector, bio->b_size,
+			      (unsigned long)req);
 #else
-	drbd_send_drequest(mdev, DataRequest, bio->bi_sector, bio->bi_size,
-			   (unsigned long)req);
+	rv=drbd_send_drequest(mdev, DataRequest, bio->bi_sector, bio->bi_size,
+			      (unsigned long)req);
 #endif
+	return rv;
 }