[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;
}