[DRBD-cvs] DRBD CVS: drbd by phil from
drbd-cvs@linbit.com
drbd-cvs@linbit.com
Sun, 11 Jan 2004 09:56:41 +0100 (CET)
DRBD CVS committal
Author : phil
Host :
Module : drbd
Dir : drbd/drbd
Modified Files:
Tag: rel-0_7-branch
drbd_dsender.c drbd_int.h drbd_main.c
Log Message:
Changed the way drbd_wait_for_other_sync_groups() works, so that
dsender stays operational while waiting for an other sync group.
Completely untested. Probabely breaks something. Will test and
debug it later today.
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/Attic/drbd_dsender.c,v
retrieving revision 1.1.2.39
retrieving revision 1.1.2.40
diff -u -3 -r1.1.2.39 -r1.1.2.40
--- drbd_dsender.c 10 Jan 2004 21:39:56 -0000 1.1.2.39
+++ drbd_dsender.c 11 Jan 2004 08:56:40 -0000 1.1.2.40
@@ -98,37 +98,56 @@
return ok;
}
-void drbd_wait_for_other_sync_groups(struct Drbd_Conf *mdev)
+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.
+
+ drbd_dev *mdev = (drbd_dev*) dh->data;
+
+ 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);
+ }
+}
+
+STATIC void drbd_wait_for_other_sync_groups(struct Drbd_Conf *mdev)
+{
+ drbd_dev *odev;
+ struct drbd_hook *dh=NULL;
int i;
- int did_wait=0;
- do {
- for (i=0; i < minor_count; i++) {
- if (signal_pending(current)) return;
- if ( drbd_conf[i].sync_conf.group < mdev->sync_conf.group
- && drbd_conf[i].cstate > Connected )
- {
- int ret;
- INFO("Syncer waits for sync group %i\n",
- drbd_conf[i].sync_conf.group);
- drbd_send_short_cmd(mdev,SyncStop);
- set_cstate(mdev,PausedSyncT);
- ret = wait_event_interruptible(
- drbd_conf[i].cstate_wait,
- drbd_conf[i].cstate <= Connected );
- // FIXME if (ret < 0) do something sensible...
- did_wait=1;
- // XXX why sleep again?
+
+ 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/10);
- break;
- };
+ schedule_timeout(HZ);
+ goto retry;
+ }
+
+ dh->data = mdev;
+ dh->callback = _ds_wait_osg;
+
+ 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!
+
+ return;
}
- } while (i < minor_count);
- if (did_wait) {
- INFO("resumed synchronisation.\n");
- drbd_send_short_cmd(mdev,SyncCont);
- set_cstate(mdev,SyncTarget);
}
}
@@ -138,7 +157,7 @@
int number,i;
sector_t sector;
-#define SLEEP_TIME 10
+#define SLEEP_TIME (HZ/10)
number = SLEEP_TIME*mdev->sync_conf.rate / ((BM_BLOCK_SIZE/1024)*HZ);
@@ -212,8 +231,9 @@
static inline int _dsender_cond(struct Drbd_Conf *mdev)
{
int rv;
- rv = test_bit(START_SYNC,&mdev->flags)
- || test_bit(SYNC_FINISHED,&mdev->flags);
+ rv = test_bit(START_SYNC,&mdev->flags) // TODO Use Lars' style _FLAG
+ || test_bit(SYNC_FINISHED,&mdev->flags)
+ || test_bit(SYNC_CONTINUE,&mdev->flags);
spin_lock_irq(&mdev->ee_lock);
rv |= !list_empty(&mdev->rdone_ee);
@@ -262,8 +282,16 @@
D_ASSERT(list_empty(&mdev->resync->lru));
}
+ if(test_and_clear_bit(SYNC_CONTINUE,&mdev->flags)) {
+ time=SLEEP_TIME;
+ INFO("resumed synchronisation.\n");
+ drbd_send_short_cmd(mdev,SyncCont);
+ set_cstate(mdev,SyncTarget);
+ }
+
if(time == SLEEP_TIME) {
- if(!ds_issue_requests(mdev)) {
+ if(!ds_issue_requests(mdev) ||
+ mdev->cstate == PausedSyncT ) {
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.80
retrieving revision 1.58.2.81
diff -u -3 -r1.58.2.80 -r1.58.2.81
--- drbd_int.h 10 Jan 2004 07:53:55 -0000 1.58.2.80
+++ drbd_int.h 11 Jan 2004 08:56:40 -0000 1.58.2.81
@@ -506,6 +506,7 @@
#define PARTNER_DISKLESS 7
#define SYNC_FINISHED 8
#define PROCESS_EE_RUNNING 9
+#define SYNC_CONTINUE 10
struct BitMap {
unsigned long dev_size;
@@ -528,8 +529,12 @@
#define BME_NO_WRITES 0
#define BME_LOCKED 1
-struct al_transaction;
-struct drbd_extent;
+struct drbd_hook {
+ struct list_head list;
+ void* data;
+ void (*callback) (drbd_dev*, struct drbd_hook* );
+};
+
// TODO sort members for performance
// MAYBE group them further
@@ -557,7 +562,8 @@
Drbd_State state;
Drbd_CState cstate;
wait_queue_head_t cstate_wait;
- wait_queue_head_t state_wait;
+ struct list_head cstate_hook; // processed if cstate changes.
+ wait_queue_head_t state_wait; // TODO: Remove state_wait.
Drbd_State o_state;
unsigned long int la_size; // last agreed disk size
unsigned int send_cnt;
@@ -915,8 +921,17 @@
static inline void set_cstate(drbd_dev* mdev,Drbd_CState cs)
{
+ struct list_head *le;
+ struct drbd_hook *dh;
+
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);
+ dh->callback(mdev,dh);
+ }
}
static inline void inc_pending(drbd_dev* mdev)
===================================================================
RCS file: /var/lib/cvs/drbd/drbd/drbd/drbd_main.c,v
retrieving revision 1.73.2.88
retrieving revision 1.73.2.89
diff -u -3 -r1.73.2.88 -r1.73.2.89
--- drbd_main.c 10 Jan 2004 19:24:00 -0000 1.73.2.88
+++ drbd_main.c 11 Jan 2004 08:56:40 -0000 1.73.2.89
@@ -996,6 +996,7 @@
mdev->pr_lock = SPIN_LOCK_UNLOCKED;
mdev->send_task_lock = SPIN_LOCK_UNLOCKED;
+ INIT_LIST_HEAD(&mdev->cstate_hook);
INIT_LIST_HEAD(&mdev->free_ee);
INIT_LIST_HEAD(&mdev->active_ee);
INIT_LIST_HEAD(&mdev->sync_ee);