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