[DRBD-cvs] r1755 - in trunk/drbd: . linux

svn at svn.drbd.org svn at svn.drbd.org
Wed Feb 2 22:19:47 CET 2005


Author: phil
Date: 2005-02-02 22:19:44 +0100 (Wed, 02 Feb 2005)
New Revision: 1755

Modified:
   trunk/drbd/drbd_compat_wrappers.h
   trunk/drbd/drbd_fs.c
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/drbd_req.c
   trunk/drbd/linux/drbd.h
Log:
- Fixed random problems with the tl_hash
- Added the ee_hash
...everything ufinished currently...


Modified: trunk/drbd/drbd_compat_wrappers.h
===================================================================
--- trunk/drbd/drbd_compat_wrappers.h	2005-02-02 17:38:17 UTC (rev 1754)
+++ trunk/drbd/drbd_compat_wrappers.h	2005-02-02 21:19:44 UTC (rev 1755)
@@ -84,7 +84,7 @@
 	return req->master_bio->bi_size;
 }
 
-static inline drbd_bio_t* drbd_req_private_bio(struct drbd_request *req)
+static inline struct bio* drbd_req_private_bio(struct drbd_request *req)
 {
 	return req->private_bio;
 }

Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c	2005-02-02 17:38:17 UTC (rev 1754)
+++ trunk/drbd/drbd_fs.c	2005-02-02 21:19:44 UTC (rev 1755)
@@ -522,6 +522,8 @@
 	enum ret_codes retcode;
 	struct net_config new_conf;
 	struct crypto_tfm* tfm = NULL;
+	struct hlist_head *new_tl_hash = NULL;
+	struct hlist_head *new_ee_hash = NULL;
 
 	minor=(int)(mdev-drbd_conf);
 
@@ -566,6 +568,25 @@
 
 	mdev->cram_hmac_tfm = tfm;
 
+
+	if (mdev->tl_hash_s != new_conf.max_epoch_size/8 ) {
+		new_tl_hash = kmalloc(mdev->tl_hash_s * sizeof(void*),
+				      GFP_KERNEL);
+		if(!new_tl_hash) {
+			retcode=KMallocFailed;
+			goto fail_ioctl;
+		}
+	}
+
+	if (mdev->ee_hash_s != new_conf.max_buffers/8 ) {
+		new_ee_hash = kmalloc(mdev->ee_hash_s * sizeof(void*),
+				      GFP_KERNEL);
+		if(!new_ee_hash) {
+			retcode=KMallocFailed;
+			goto fail_ioctl;
+		}
+	}
+
 	/* IMPROVE:
 	   We should warn the user if the LL_DEV is
 	   used already. E.g. some FS mounted on it.
@@ -607,19 +628,20 @@
 	mdev->send_cnt = 0;
 	mdev->recv_cnt = 0;
 
-	if (mdev->tl_hash_s != mdev->conf.max_epoch_size/8 ) {
+	if(new_tl_hash) {
 		if (mdev->tl_hash) kfree(mdev->tl_hash);
 		mdev->tl_hash_s = mdev->conf.max_epoch_size/8;
-		mdev->tl_hash = kmalloc(mdev->tl_hash_s * sizeof(void*),
-					GFP_KERNEL);
-		if(!mdev->tl_hash) {
-			mdev->tl_hash_s = 0;
-			return -ENOMEM;
-		}
-
+		mdev->tl_hash = new_tl_hash;
 		memset(mdev->tl_hash, 0, mdev->tl_hash_s * sizeof(void*));
 	}
 
+	if(new_ee_hash) {
+		if (mdev->ee_hash) kfree(mdev->ee_hash);
+		mdev->ee_hash_s = mdev->conf.max_buffers/8;
+		mdev->ee_hash = new_ee_hash;
+		memset(mdev->ee_hash, 0, mdev->ee_hash_s * sizeof(void*));
+	}
+
 	drbd_thread_start(&mdev->worker);
 	if( drbd_request_state(mdev,NS(conn,Unconnected)) > 0) {
 		drbd_thread_start(&mdev->receiver);
@@ -628,6 +650,8 @@
 	return 0;
 
   fail_ioctl:
+	if (new_tl_hash) kfree(new_tl_hash);
+	if (new_ee_hash) kfree(new_ee_hash);
 	if (put_user(retcode, &arg->ret_code)) return -EFAULT;
 	return -EINVAL;
 }

Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2005-02-02 17:38:17 UTC (rev 1754)
+++ trunk/drbd/drbd_int.h	2005-02-02 21:19:44 UTC (rev 1755)
@@ -606,6 +606,7 @@
 	long magic;
 	unsigned int ee_size;
 	sector_t ee_sector;
+	struct hlist_node colision;
 	// THINK: maybe we rather want bio_alloc(GFP_*,1)
 	struct bio_vec ee_bvec;
 };
@@ -741,6 +742,8 @@
 	struct list_head done_ee;   // send ack
 	struct list_head read_ee;   // IO in progress
 	struct list_head net_ee;    // zero-copy network send in progress
+	struct hlist_head * ee_hash; // is proteced by tl_lock!
+	unsigned int ee_hash_s;     
 	spinlock_t pr_lock;
 	struct list_head app_reads;
 	struct list_head resync_reads;
@@ -789,7 +792,7 @@
 extern int tl_verify(drbd_dev *mdev, drbd_request_t * item, sector_t sector);
 #define TLHW_FLAG_SENT   0x10000000
 #define TLHW_FLAG_RECVW  0x20000000
-extern int req_have_write(drbd_dev *mdev, sector_t sector, int size_n_flags);
+extern int req_have_write(drbd_dev *mdev, struct Tl_epoch_entry *e, int flags);
 extern void drbd_free_sock(drbd_dev *mdev);
 extern int drbd_send(drbd_dev *mdev, struct socket *sock,
 		     void* buf, size_t size, unsigned msg_flags);

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2005-02-02 17:38:17 UTC (rev 1754)
+++ trunk/drbd/drbd_main.c	2005-02-02 21:19:44 UTC (rev 1755)
@@ -201,6 +201,7 @@
 	b->n_req--;
 
 	list_del(&item->w.list);
+	hlist_del(&item->colision);
 	item->rq_status &= ~RQ_DRBD_IN_TL;
 
 	spin_unlock_irq(&mdev->tl_lock);
@@ -300,6 +301,7 @@
 
 	r = ( item->barrier == mdev->newest_barrier );
 	list_del(&item->w.list);
+	hlist_del(&item->colision);
 
 	if( item->rq_status & RQ_DRBD_RECVW ) wake_up(&mdev->cstate_wait);
 
@@ -360,6 +362,11 @@
 	}
 }
 
+STATIC unsigned int ee_hash_fn(drbd_dev *mdev, sector_t sector)
+{
+	return (sector>>HT_SHIFT) % mdev->ee_hash_s;
+}
+
 STATIC int overlaps(sector_t s1, int l1, sector_t s2, int l2)
 {
 	return !( ( s1 + (l1>>9) <= s2 ) || ( s1 >= s2 + (l2>>9) ) );
@@ -371,12 +378,13 @@
  * 1 ... a conflicting write, have not got ack by now.
  * 2 ... a conflicting write, have got also got ack.
  */
-int req_have_write(drbd_dev *mdev, sector_t sector, int size_n_flags)
+int req_have_write(drbd_dev *mdev, struct Tl_epoch_entry *e, int flags)
 {
 	struct hlist_head *slot;
 	struct hlist_node *n;
 	drbd_request_t * req;
-	int size = size_n_flags & ~(TLHW_FLAG_SENT|TLHW_FLAG_RECVW);
+	sector_t sector = drbd_ee_get_sector(e);	
+	int size = drbd_ee_get_size(e);
 	int i, rv=0;
 
 	D_ASSERT(size <= 1<<(HT_SHIFT+9) );
@@ -393,10 +401,10 @@
 				     size) ) {
 				rv=1;
 				if( req->rq_status & RQ_DRBD_SENT ) rv++;
-				if( size_n_flags & TLHW_FLAG_SENT ) {
+				if( flags & TLHW_FLAG_SENT ) {
 					req->rq_status |= RQ_DRBD_SENT;
 				}
-				if( size_n_flags & TLHW_FLAG_RECVW ) {
+				if( flags & TLHW_FLAG_RECVW ) {
 					req->rq_status |= RQ_DRBD_RECVW;
 				}
 				goto out;
@@ -404,7 +412,10 @@
 		} // hlist_for_each_entry()
 	}
 
-	// PRE TODO: insert ee onto ee_hash_table here...
+	// Good, no conflict found
+	INIT_HLIST_NODE(&e->colision);
+	hlist_add_head( &e->colision, mdev->ee_hash + 
+			ee_hash_fn(mdev, sector) );
  out:
 	spin_unlock_irq(&mdev->tl_lock);
 
@@ -1858,6 +1869,11 @@
 				__free_page(mdev->md_io_tmpp);
 
 			if (mdev->act_log) lc_free(mdev->act_log);
+
+			if(mdev->ee_hash) {
+				kfree(mdev->ee_hash);
+				mdev->ee_hash_s = 0;
+			}
 		}
 		drbd_destroy_mempools();
 	}

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2005-02-02 17:38:17 UTC (rev 1754)
+++ trunk/drbd/drbd_receiver.c	2005-02-02 21:19:44 UTC (rev 1755)
@@ -1072,6 +1072,16 @@
 	e = read_in_block(mdev,data_size);
 	if (!e) return FALSE;
 
+	if(!inc_local(mdev)) {
+		if (DRBD_ratelimit(5*HZ,5))
+			ERR("Can not write mirrored data block to local disk.\n");
+		drbd_send_ack(mdev,NegAck,e);
+		spin_lock_irq(&mdev->ee_lock);
+		drbd_put_ee(mdev,e);
+		spin_unlock_irq(&mdev->ee_lock);
+		return TRUE;
+	}
+
 	if(discard) {
 		spin_lock_irq(&mdev->ee_lock);
 		drbd_put_ee(mdev,e);
@@ -1081,13 +1091,13 @@
 		return TRUE;
 	}
 
-	switch( req_have_write(mdev, sector, data_size) ) {
+	switch( req_have_write(mdev, e, 0) ) {
 	case 2: /* Conflicting write, got ACK */
 		/* write afterwards ...*/
 		WARN("Concurrent write! [W AFTERWARDS] sec=%lu\n",
 		     (unsigned long)sector);
 		if( wait_event_interruptible(mdev->cstate_wait,
-		     !req_have_write(mdev,sector,data_size|TLHW_FLAG_RECVW))) {
+		     !req_have_write(mdev,e,TLHW_FLAG_RECVW))) {
 			spin_lock_irq(&mdev->ee_lock);
 			drbd_put_ee(mdev,e);
 			spin_unlock_irq(&mdev->ee_lock);
@@ -1106,7 +1116,7 @@
 			WARN("Concurrent write! [W AFTERWARDS] sec=%lu\n",
 			     (unsigned long)sector);
 			if( wait_event_interruptible(mdev->cstate_wait,
-			      !req_have_write(mdev,sector,data_size|
+			      !req_have_write(mdev,e,
 				            TLHW_FLAG_RECVW|TLHW_FLAG_SENT))) {
 				spin_lock_irq(&mdev->ee_lock);
 				drbd_put_ee(mdev,e);
@@ -1120,16 +1130,6 @@
 
 	e->block_id = p->block_id; // no meaning on this side, e* on partner
 
-	if(!inc_local(mdev)) {
-		if (DRBD_ratelimit(5*HZ,5))
-			ERR("Can not write mirrored data block to local disk.\n");
-		drbd_send_ack(mdev,NegAck,e);
-		spin_lock_irq(&mdev->ee_lock);
-		drbd_put_ee(mdev,e);
-		spin_unlock_irq(&mdev->ee_lock);
-		return TRUE;
-	}
-
 	drbd_ee_prepare_write(mdev, e, sector, data_size);
 	e->w.cb     = e_end_block;
 

Modified: trunk/drbd/drbd_req.c
===================================================================
--- trunk/drbd/drbd_req.c	2005-02-02 17:38:17 UTC (rev 1754)
+++ trunk/drbd/drbd_req.c	2005-02-02 21:19:44 UTC (rev 1755)
@@ -57,7 +57,6 @@
 	req->rq_status |= nextstate;
 	req->rq_status &= er_flags | ~0x0001;
 	if( (req->rq_status & RQ_DRBD_DONE) == RQ_DRBD_DONE ) {
-		hlist_del(&req->colision);
 		goto end_it;
 	}
 
@@ -81,6 +80,7 @@
 				set_bit(ISSUE_BARRIER,&mdev->flags);
 		} else {
 			list_del(&req->w.list); // we have the tl_lock...
+			hlist_del(&req->colision);
 		}
 	}
 
@@ -324,6 +324,9 @@
 		}
 	}
 
+	/* NOTE: drbd_send_dlobck() must happen before start of local IO,
+	         to get he concurrent write detection right. */
+
 	if (local) {
 		if (rw == WRITE) {
 			if (!remote) drbd_set_out_of_sync(mdev,sector,size);

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2005-02-02 17:38:17 UTC (rev 1754)
+++ trunk/drbd/linux/drbd.h	2005-02-02 21:19:44 UTC (rev 1755)
@@ -136,6 +136,7 @@
 	MDIOError,
 	MDInvalid,
 	CRAMAlgNotAvail,
+	KMallocFailed,
 };
 
 struct ioctl_disk_config {



More information about the drbd-cvs mailing list