[DRBD-cvs] DRBD CVS: drbd by phil from
drbd-cvs@linbit.com
drbd-cvs@linbit.com
Mon, 12 Jan 2004 11:46: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_dsender.c drbd_int.h
Log Message:
Some work on drbd_wait_for_other_sync_groups() ... Next step is to test
this...
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/Attic/drbd_actlog.c,v
retrieving revision 1.1.2.44
retrieving revision 1.1.2.45
diff -u -3 -r1.1.2.44 -r1.1.2.45
--- drbd_actlog.c 12 Jan 2004 09:31:36 -0000 1.1.2.44
+++ drbd_actlog.c 12 Jan 2004 10:46:42 -0000 1.1.2.45
@@ -514,8 +514,8 @@
D_ASSERT((long)ext->rs_left >= 0);
} else {
WARN("Recounting sectors (resync LRU too small?)\n");
- lc_changed(mdev->resync,(struct lc_element*)ext);
ext->rs_left = bm_count_sectors(mdev->mbds_id,enr);
+ lc_changed(mdev->resync,(struct lc_element*)ext);
}
lc_put(mdev->resync,(struct lc_element*)ext);
} else {
@@ -589,8 +589,8 @@
bm_ext = (struct bm_extent*) lc_get(mdev->resync,enr);
if (bm_ext) {
if(bm_ext->lce.lc_number != enr) {
- lc_changed(mdev->resync,(struct lc_element*)bm_ext);
bm_ext->rs_left = bm_count_sectors(mdev->mbds_id,enr);
+ lc_changed(mdev->resync,(struct lc_element*)bm_ext);
wake_up(&mdev->al_wait);
}
set_bit(BME_NO_WRITES,&bm_ext->flags); // within the lock
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/Attic/drbd_dsender.c,v
retrieving revision 1.1.2.40
retrieving revision 1.1.2.41
diff -u -3 -r1.1.2.40 -r1.1.2.41
--- drbd_dsender.c 11 Jan 2004 08:56:40 -0000 1.1.2.40
+++ drbd_dsender.c 12 Jan 2004 10:46:42 -0000 1.1.2.41
@@ -98,57 +98,86 @@
return ok;
}
+STATIC drbd_dev *ds_find_osg(drbd_dev *mdev)
+{
+ drbd_dev *odev;
+ int i;
+
+ for (i=0; i < minor_count; i++) {
+ odev = drbd_conf + i;
+ if ( odev->sync_conf.group < mdev->sync_conf.group
+ && odev->cstate > Connected ) {
+ return odev;
+ }
+ }
+
+ return 0;
+}
+
STATIC void _ds_wait_osg(drbd_dev* odev, struct drbd_hook* dh)
{
// This is a callback, I better not assume that this
// is a context which allows to send something from.
-
+ unsigned long flags;
drbd_dev *mdev = (drbd_dev*) dh->data;
+ int added=0;
if(odev->cstate <= Connected) {
- set_bit(SYNC_CONTINUE,&mdev->flags);
- wake_up_interruptible(&mdev->dsender_wait);
- list_del(&dh->list); // TODO: Lock for list manipulaton.
- kfree(dh);
+ spin_lock_irqsave(&mdev->req_lock,flags);
+ list_del(&dh->list);
+ spin_unlock_irqrestore(&mdev->req_lock,flags);
+ retry:
+ if( (odev = ds_find_osg(mdev)) ) {
+ spin_lock_irqsave(&odev->req_lock,flags);
+ if(odev->cstate > Connected) {
+ list_add(&dh->list,&odev->cstate_hook);
+ added=1;
+ }
+ spin_unlock_irqrestore(&odev->req_lock,flags);
+ if(!added) goto retry;
+ } else {
+ set_bit(SYNC_CONTINUE,&mdev->flags);
+ wake_up_interruptible(&mdev->dsender_wait);
+ kfree(dh);
+ }
}
}
-STATIC void drbd_wait_for_other_sync_groups(struct Drbd_Conf *mdev)
+STATIC int drbd_wait_for_other_sync_groups(drbd_dev *mdev)
{
drbd_dev *odev;
struct drbd_hook *dh=NULL;
- int i;
+ int added=0;
retry:
- for (i=0; i < minor_count; i++) {
- odev = drbd_conf + i;
- if (signal_pending(current)) return;
- if ( odev->sync_conf.group < mdev->sync_conf.group
- && odev->cstate > Connected ) {
- INFO("Syncer waits for sync group %i\n",
- odev->sync_conf.group);
- drbd_send_short_cmd(mdev,SyncStop);
- set_cstate(mdev,PausedSyncT);
-
- dh=kmalloc(sizeof(struct drbd_hook),GFP_KERNEL);
- if(!dh) {
- ERR("could not kmalloc drbd_hook\n");
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ);
- goto retry;
- }
+ odev = ds_find_osg(mdev);
+ if(!odev) return FALSE;
- dh->data = mdev;
- dh->callback = _ds_wait_osg;
+ while( dh == NULL ) {
+ dh=kmalloc(sizeof(struct drbd_hook),GFP_KERNEL);
+ if(dh) break;
+ ERR("could not kmalloc drbd_hook\n");
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(HZ);
+ }
- list_add(&dh->list,&odev->cstate_hook);
- // TODO: Need some locking here!
- // over the test of odev->cstate and list_add.
- // otherwise we could miss the run of the hook!
+ dh->data = mdev;
+ dh->callback = _ds_wait_osg;
- return;
- }
+ spin_lock_irq(&odev->req_lock);
+ if(odev->cstate > Connected) {
+ list_add(&dh->list,&odev->cstate_hook);
+ added=1;
}
+ spin_unlock_irq(&odev->req_lock);
+ if(!added) goto retry;
+
+ INFO("Syncer waits for sync group %i\n",
+ odev->sync_conf.group);
+ drbd_send_short_cmd(mdev,SyncStop);
+ set_cstate(mdev,PausedSyncT);
+
+ return TRUE;
}
/* bool */
@@ -169,7 +198,7 @@
}
// /Remove later
- drbd_wait_for_other_sync_groups(mdev);
+ if(drbd_wait_for_other_sync_groups(mdev)) return FALSE;
for(i=0;i<number;i++) {
struct Pending_read *pr;
@@ -282,7 +311,8 @@
D_ASSERT(list_empty(&mdev->resync->lru));
}
- if(test_and_clear_bit(SYNC_CONTINUE,&mdev->flags)) {
+ if(test_and_clear_bit(SYNC_CONTINUE,&mdev->flags) &&
+ (mdev->cstate == PausedSyncT) ) {
time=SLEEP_TIME;
INFO("resumed synchronisation.\n");
drbd_send_short_cmd(mdev,SyncCont);
@@ -290,8 +320,7 @@
}
if(time == SLEEP_TIME) {
- if(!ds_issue_requests(mdev) ||
- mdev->cstate == PausedSyncT ) {
+ if (!ds_issue_requests(mdev)) {
time=MAX_SCHEDULE_TIMEOUT;
}
if (!disable_io_hints) {
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/drbd_int.h,v
retrieving revision 1.58.2.82
retrieving revision 1.58.2.83
diff -u -3 -r1.58.2.82 -r1.58.2.83
--- drbd_int.h 12 Jan 2004 09:31:36 -0000 1.58.2.82
+++ drbd_int.h 12 Jan 2004 10:46:42 -0000 1.58.2.83
@@ -921,15 +921,21 @@
{
struct list_head *le;
struct drbd_hook *dh;
+ unsigned long flags;
+ spin_lock_irqsave(&mdev->req_lock,flags);
mdev->cstate = cs;
- wake_up_interruptible(&mdev->cstate_wait);
while(!list_empty(&mdev->cstate_hook)) {
le = mdev->cstate_hook.next;
dh = list_entry(le, struct drbd_hook,list);
+ spin_unlock_irqrestore(&mdev->req_lock,flags);
dh->callback(mdev,dh);
+ spin_lock_irqsave(&mdev->req_lock,flags);
}
+ spin_unlock_irqrestore(&mdev->req_lock,flags);
+
+ wake_up_interruptible(&mdev->cstate_wait);
}
static inline void inc_pending(drbd_dev* mdev)