[DRBD-cvs] r1683 - in trunk: . drbd

svn at svn.drbd.org svn at svn.drbd.org
Tue Dec 21 01:32:32 CET 2004


Author: phil
Date: 2004-12-21 01:32:30 +0100 (Tue, 21 Dec 2004)
New Revision: 1683

Modified:
   trunk/ROADMAP
   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
Log:
Did item 6 of the ROADMAP document.


Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2004-12-15 19:48:31 UTC (rev 1682)
+++ trunk/ROADMAP	2004-12-21 00:32:30 UTC (rev 1683)
@@ -89,7 +89,7 @@
 
   Note: The actual key to the hash should be (sector & ~0x7).
         See item 9 for more details.
-  0% DONE
+  99% DONE
 
 7 Handle split brain situations; Support IO fencing; 
   introduce the "Dead" peer state (o_state)

Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c	2004-12-15 19:48:31 UTC (rev 1682)
+++ trunk/drbd/drbd_fs.c	2004-12-21 00:32:30 UTC (rev 1683)
@@ -576,6 +576,19 @@
 	mdev->send_cnt = 0;
 	mdev->recv_cnt = 0;
 
+	if (mdev->tl_hash_s != mdev->conf.max_epoch_size/8 ) {
+		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;
+		}
+
+		memset(mdev->tl_hash, 0, mdev->tl_hash_s * sizeof(void*));
+	}
+
 	drbd_thread_start(&mdev->worker);
 	if( drbd_request_state(mdev,NS(conn,Unconnected)) > 0) {
 		drbd_thread_start(&mdev->receiver);

Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2004-12-15 19:48:31 UTC (rev 1682)
+++ trunk/drbd/drbd_int.h	2004-12-21 00:32:30 UTC (rev 1683)
@@ -566,6 +566,7 @@
 	struct drbd_barrier *barrier; // The next barrier.
 	struct bio *master_bio;       // master bio pointer
 	struct bio private_bio;       // private bio struct
+	struct hlist_node colision;
 };
 
 struct drbd_barrier {
@@ -701,6 +702,8 @@
 	spinlock_t tl_lock;
 	struct drbd_barrier* newest_barrier;
 	struct drbd_barrier* oldest_barrier;
+	struct hlist_head * tl_hash;
+	unsigned int tl_hash_s;
 	unsigned long flags;
 	struct task_struct *send_task; /* about pid calling drbd_send */
 	spinlock_t send_task_lock;
@@ -767,6 +770,7 @@
 		       unsigned int set_size);
 extern void tl_clear(drbd_dev *mdev);
 extern int tl_dependence(drbd_dev *mdev, drbd_request_t * item);
+extern int tl_verify(drbd_dev *mdev, drbd_request_t * item, sector_t sector);
 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	2004-12-15 19:48:31 UTC (rev 1682)
+++ trunk/drbd/drbd_main.c	2004-12-21 00:32:30 UTC (rev 1683)
@@ -146,6 +146,9 @@
 	mdev->oldest_barrier = b;
 	mdev->newest_barrier = b;
 
+	mdev->tl_hash = NULL;
+	mdev->tl_hash_s = 0;
+
 	return 1;
 }
 
@@ -153,8 +156,19 @@
 {
 	D_ASSERT(mdev->oldest_barrier == mdev->newest_barrier);
 	kfree(mdev->oldest_barrier);
+	if(mdev->tl_hash) {
+		kfree(mdev->tl_hash);
+		mdev->tl_hash_s = 0;
+	}
 }
 
+STATIC unsigned int tl_hash_fn(drbd_dev *mdev, sector_t sector)
+{
+	// map sectors in the same 4k block to the same hash key.
+	return (sector>>3) % mdev->tl_hash_s;
+}
+
+
 STATIC void tl_add(drbd_dev *mdev, drbd_request_t * new_item)
 {
 	struct drbd_barrier *b;
@@ -171,6 +185,10 @@
 		set_bit(ISSUE_BARRIER,&mdev->flags);
 	}
 
+	INIT_HLIST_NODE(&new_item->colision);
+	hlist_add_head( &new_item->colision, mdev->tl_hash + 
+			tl_hash_fn(mdev, drbd_req_get_sector(new_item) ));
+
 	spin_unlock_irq(&mdev->tl_lock);
 }
 
@@ -243,6 +261,21 @@
 	kfree(b);
 }
 
+int tl_verify(drbd_dev *mdev, drbd_request_t * item, sector_t sector)
+{
+	struct hlist_head *slot = mdev->tl_hash + tl_hash_fn(mdev,sector);
+	struct hlist_node *n;
+	drbd_request_t * i;
+
+	hlist_for_each_entry(i, n, slot, colision) {
+		if (i==item) {
+			D_ASSERT(drbd_req_get_sector(i) == sector);
+			return 1;
+		}
+	}
+	return 0;
+}
+
 /* tl_dependence reports if this sector was present in the current
    epoch.
    As side effect it clears also the pointer to the request if it

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2004-12-15 19:48:31 UTC (rev 1682)
+++ trunk/drbd/drbd_receiver.c	2004-12-21 00:32:30 UTC (rev 1683)
@@ -1923,6 +1923,11 @@
 
 			ERR_IF (!VALID_POINTER(req)) return FALSE;
 
+			if (unlikely(!tl_verify(mdev,req,sector))) {
+				ERR("Got a corrupt block_id/sector pair.\n");
+				return FALSE;
+			}
+
 			drbd_end_req(req, RQ_DRBD_SENT, 1, sector);
 
 			if (test_bit(SYNC_STARTED,&mdev->flags) &&

Modified: trunk/drbd/drbd_req.c
===================================================================
--- trunk/drbd/drbd_req.c	2004-12-15 19:48:31 UTC (rev 1682)
+++ trunk/drbd/drbd_req.c	2004-12-21 00:32:30 UTC (rev 1683)
@@ -56,7 +56,10 @@
 
 	req->rq_status |= nextstate;
 	req->rq_status &= er_flags | ~0x0001;
-	if( (req->rq_status & RQ_DRBD_DONE) == RQ_DRBD_DONE ) goto end_it;
+	if( (req->rq_status & RQ_DRBD_DONE) == RQ_DRBD_DONE ) {
+		hlist_del(&req->colision);
+		goto end_it;
+	}
 
 	spin_unlock_irqrestore(&mdev->req_lock,flags);
 



More information about the drbd-cvs mailing list