[DRBD-cvs] svn commit by phil - r2305 - trunk/drbd - Finally found
and fixed that terribly bug that tortured
drbd-cvs at lists.linbit.com
drbd-cvs at lists.linbit.com
Fri Jul 28 12:41:11 CEST 2006
Author: phil
Date: 2006-07-28 12:41:09 +0200 (Fri, 28 Jul 2006)
New Revision: 2305
Modified:
trunk/drbd/drbd_main.c
trunk/drbd/drbd_req.c
trunk/drbd/drbd_worker.c
Log:
Finally found and fixed that terribly bug that tortured me te last
days.
The w_send_dblock() could run even after tl_clear() ...
Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c 2006-07-28 07:38:43 UTC (rev 2304)
+++ trunk/drbd/drbd_main.c 2006-07-28 10:41:09 UTC (rev 2305)
@@ -211,7 +211,7 @@
b=mdev->newest_barrier;
req->barrier = b;
- req->rq_status |= RQ_DRBD_IN_TL;
+ req->rq_status |= RQ_DRBD_IN_TL; /* BUG, not holding req_lock */
list_add(&req->tl_requests,&b->requests);
if( b->n_req++ > mdev->net_conf->max_epoch_size ) {
Modified: trunk/drbd/drbd_req.c
===================================================================
--- trunk/drbd/drbd_req.c 2006-07-28 07:38:43 UTC (rev 2304)
+++ trunk/drbd/drbd_req.c 2006-07-28 10:41:09 UTC (rev 2305)
@@ -32,6 +32,22 @@
#include <linux/drbd.h>
#include "drbd_int.h"
+/*
+void drbd_show_req(struct Drbd_Conf* mdev, char *txt, drbd_request_t *req)
+{
+ INFO("req %s %p %c%c%c%c%c %p\n",
+ txt,
+ req,
+ req->rq_status & RQ_DRBD_ON_WIRE ? 'w' :'_',
+ req->rq_status & RQ_DRBD_IN_TL ? 't' :'_',
+ req->rq_status & RQ_DRBD_SENT ? 's' :'_',
+ req->rq_status & RQ_DRBD_LOCAL ? 'l' :'_',
+ req->rq_status & RQ_DRBD_NOTHING ? 'u' :'_',
+ req->barrier
+ );
+}
+*/
+
void drbd_end_req(drbd_request_t *req, int nextstate, int er_flags,
sector_t rsector)
{
@@ -205,6 +221,7 @@
req->mdev = mdev;
req->master_bio = bio_src;
req->private_bio = bio;
+ req->barrier = NULL;
bio->bi_private = req;
bio->bi_end_io =
@@ -326,6 +343,8 @@
// inc_ap_bio(mdev); do not allow more open requests than max_buffers!
wait_event( mdev->rq_wait,atomic_add_unless(&mdev->ap_bio_cnt,1,mxb) );
+ /* remote might be already wrong here, since we might slept after
+ looking at the connection state, but this is ok. */
if (remote) {
/* either WRITE and Connected,
* or READ, and no local disk,
Modified: trunk/drbd/drbd_worker.c
===================================================================
--- trunk/drbd/drbd_worker.c 2006-07-28 07:38:43 UTC (rev 2304)
+++ trunk/drbd/drbd_worker.c 2006-07-28 10:41:09 UTC (rev 2305)
@@ -559,10 +559,21 @@
int w_send_dblock(drbd_dev *mdev, struct drbd_work *w, int cancel)
{
drbd_request_t *req = (drbd_request_t *)w;
+ sector_t sector;
+ unsigned int size;
int ok;
- if (unlikely(cancel)) {
- /* Nothing to do, here. tl_clear() does the work. */
+ D_ASSERT( !(req->rq_status & RQ_DRBD_SENT) );
+
+ if (unlikely(cancel)) {
+ /* We clear it up here explicit, since we might be _after_ the
+ run of tl_clear() */
+ sector = drbd_req_get_sector(req);
+ size = drbd_req_get_size(req);
+
+ drbd_end_req(req,RQ_DRBD_SENT,1, sector);
+ drbd_set_out_of_sync(mdev, sector, size);
+
return 1;
}
@@ -583,6 +594,7 @@
if (mdev->state.conn >= Connected)
drbd_force_state(mdev,NS(conn,NetworkFailure));
drbd_thread_restart_nowait(&mdev->receiver);
+ /* The request gets cleared up by tl_clear() */
}
return ok;
More information about the drbd-cvs
mailing list