[DRBD-cvs] svn commit by lars - r2862 - trunk/drbd - fix potential
dereference after free/reuse of epoch_ent
drbd-cvs at lists.linbit.com
drbd-cvs at lists.linbit.com
Fri Apr 20 15:23:21 CEST 2007
Author: lars
Date: 2007-04-20 15:23:20 +0200 (Fri, 20 Apr 2007)
New Revision: 2862
Modified:
trunk/drbd/drbd_worker.c
Log:
fix potential dereference after free/reuse of epoch_entries
Modified: trunk/drbd/drbd_worker.c
===================================================================
--- trunk/drbd/drbd_worker.c 2007-04-19 08:43:30 UTC (rev 2861)
+++ trunk/drbd/drbd_worker.c 2007-04-20 13:23:20 UTC (rev 2862)
@@ -106,8 +106,11 @@
unsigned long flags=0;
struct Tl_epoch_entry *e=NULL;
drbd_dev *mdev;
+ sector_t e_sector;
+ int e_size;
int do_wake;
int is_syncer_req;
+ int do_al_complete_io;
e = bio->bi_private;
mdev = e->mdev;
@@ -120,9 +123,23 @@
spin_lock_irqsave(&mdev->req_lock,flags);
mdev->writ_cnt += e->size >> 9;
is_syncer_req = is_syncer_block_id(e->block_id);
+
+ /* after we moved e to done_ee,
+ * we may no longer access it,
+ * it may be freed/reused already!
+ * (as soon as we release the req_lock) */
+ e_sector = e->sector;
+ e_size = e->size;
+ do_al_complete_io = e->flags & EE_CALL_AL_COMPLETE_IO;
+
list_del(&e->w.list); /* has been on active_ee or sync_ee */
list_add_tail(&e->w.list,&mdev->done_ee);
+ MTRACE(TraceTypeEE,TraceLvlAll,
+ INFO("Moved EE (WRITE) to done_ee sec=%llus size=%u ee=%p\n",
+ (unsigned long long)e->sector,e->size,e);
+ );
+
/* No hlist_del_init(&e->colision) here, we did not send the Ack yet,
* neither did we wake possibly waiting conflicting requests.
* done from "drbd_process_done_ee" within the appropriate w.cb
@@ -137,19 +154,15 @@
if (error) __drbd_chk_io_error(mdev,FALSE);
spin_unlock_irqrestore(&mdev->req_lock,flags);
- if(is_syncer_req) drbd_rs_complete_io(mdev,e->sector);
+ if (is_syncer_req) drbd_rs_complete_io(mdev,e_sector);
if (do_wake) wake_up(&mdev->ee_wait);
- if(e->flags & EE_CALL_AL_COMPLETE_IO) drbd_al_complete_io(mdev,e->sector);
+ if (do_al_complete_io) drbd_al_complete_io(mdev,e_sector);
wake_asender(mdev);
dec_local(mdev);
- MTRACE(TraceTypeEE,TraceLvlAll,
- INFO("Moved EE (WRITE) to done_ee sec=%llus size=%u ee=%p\n",
- (unsigned long long)e->sector,e->size,e);
- );
return 0;
}
More information about the drbd-cvs
mailing list