[DRBD-cvs] svn commit by phil - r2902 - in trunk: drbd drbd/linux scripts user - It is for sure broken in many ways, but I want to have

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Tue May 22 15:12:35 CEST 2007


Author: phil
Date: 2007-05-22 15:12:31 +0200 (Tue, 22 May 2007)
New Revision: 2902

Modified:
   trunk/drbd/drbd_compat_wrappers.h
   trunk/drbd/drbd_nl.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/linux/drbd.h
   trunk/drbd/linux/drbd_nl.h
   trunk/scripts/drbd.conf
   trunk/user/drbdadm_scanner.fl
   trunk/user/drbdsetup.c
Log:
It is for sure broken in many ways, but I want to have it in SVN...


Modified: trunk/drbd/drbd_compat_wrappers.h
===================================================================
--- trunk/drbd/drbd_compat_wrappers.h	2007-05-22 13:04:31 UTC (rev 2901)
+++ trunk/drbd/drbd_compat_wrappers.h	2007-05-22 13:12:31 UTC (rev 2902)
@@ -338,3 +338,12 @@
 	return rv;
 }
 #endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+static inline void radix_tree_replace_slot(void **pslot, void *item)
+{
+	rcu_assign_pointer(*pslot,
+		(void *)((unsigned long)item |
+			((unsigned long)*pslot & 1)));
+}
+#endif

Modified: trunk/drbd/drbd_nl.c
===================================================================
--- trunk/drbd/drbd_nl.c	2007-05-22 13:04:31 UTC (rev 2901)
+++ trunk/drbd/drbd_nl.c	2007-05-22 13:12:31 UTC (rev 2902)
@@ -1053,6 +1053,7 @@
 		new_conf->wire_protocol   = DRBD_PROT_C;
 		new_conf->ping_timeo      = DRBD_PING_TIMEO_DEF;
 		new_conf->rr_conflict     = DRBD_RR_CONFLICT_DEF;
+		new_conf->preheat_cache   = 0;
 	}
 
 	if (!net_conf_from_tags(mdev,nlp->tag_list,new_conf)) {
@@ -1063,8 +1064,13 @@
 	if (new_conf->two_primaries && (new_conf->wire_protocol != DRBD_PROT_C)) {
 		retcode=ProtocolCRequired;
 		goto fail;
-	};
+	}
 
+	if( new_conf->preheat_cache && new_conf->two_primaries ) {
+		retcode=PreHeatAndTwoPrimaries;
+		goto fail;
+	}
+
 	if( mdev->state.role == Primary && new_conf->want_lose ) {
 		retcode=DiscardNotAllowed;
 		goto fail;

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2007-05-22 13:04:31 UTC (rev 2901)
+++ trunk/drbd/drbd_receiver.c	2007-05-22 13:12:31 UTC (rev 2902)
@@ -1186,11 +1186,89 @@
 	return ok;
 }
 
+
+static inline void swap_struct_page(struct page* p1, struct page* p2)
+{
+	struct page tmp;
+
+	tmp = *p1;
+	*p1 = *p2;
+	*p2 = tmp;
+}
+
+STATIC void drbd_update_page_cache(drbd_dev *mdev,
+				   sector_t sector,
+				   struct bio_vec *bvec)
+{
+	struct inode *inode = mdev->this_bdev->bd_inode;
+	struct address_space *mapping = inode->i_mapping;
+	struct page **ppage, *tp, *npage;
+	struct zone *zone;
+	pgoff_t index;
+	int whole_page;
+
+	index = sector >> (PAGE_CACHE_SHIFT - inode->i_blkbits);
+	whole_page = bvec->bv_offset==0 && bvec->bv_len==PAGE_CACHE_SIZE;
+	npage = bvec->bv_page;
+		
+	write_lock_irq(&mapping->tree_lock);
+	ppage = (struct page **)radix_tree_lookup_slot(&mapping->page_tree, index);
+	if(ppage && *ppage) {
+		if( whole_page ) {
+			struct address_space *before;
+			tp = *ppage;
+
+			before = tp->mapping;
+			zone = page_zone(tp);
+			spin_lock(&zone->lru_lock);
+			if (PageLRU(tp)) {
+				del_page_from_lru(zone,tp);
+			}
+			spin_unlock(&zone->lru_lock);
+
+			clear_bit(PG_lru, &(tp)->flags);
+			D_ASSERT(!PageLRU(npage));
+			radix_tree_replace_slot((void**)ppage, npage);
+			swap_struct_page(tp,npage);
+			bvec->bv_page = tp;
+
+		}
+		write_unlock_irq(&mapping->tree_lock);
+		
+		if( !whole_page ) {
+			unsigned int o = bvec->bv_offset;
+			// lock page necessary ?
+			memcpy(kmap(*ppage)+o, kmap(npage)+o, 
+			       bvec->bv_len);
+
+			kunmap(*ppage);
+			kunmap(npage);
+		}
+	} else {
+		write_unlock_irq(&mapping->tree_lock);
+		if(whole_page && (tp = alloc_page(GFP_TRY))) {
+			if(add_to_page_cache(npage,mapping,
+					     index, GFP_KERNEL)==0) {
+				// add_to_page_cache suceeded.
+				ClearPageDirty(npage);
+				SetPageUptodate(npage);
+				// lru_cache_add(page); can't do that ?!?
+				ClearPagePrivate(npage);
+				ClearPageLocked(npage);
+				D_ASSERT(!PageLRU(npage));
+				clear_bit(PG_lru, &(npage)->flags);
+				bvec->bv_page = tp;
+			} else {
+				__free_page(tp);
+			}
+		}
+	}
+}
+
+
+
 /* e_end_block() is called via drbd_process_done_ee().
  * this means this function only runs in the asender thread
- *
- * for a broken example implementation of the TCQ barrier version of
- * e_end_block see older revisions...
  */
 STATIC int e_end_block(drbd_dev *mdev, struct drbd_work *w, int unused)
 {
@@ -1236,6 +1314,16 @@
 		D_ASSERT(hlist_unhashed(&e->colision));
 	}
 
+	// Preheat cache code here.
+	if (mdev->net_conf->preheat_cache) {
+		struct bio_vec *bvec;
+		int i;
+		__bio_for_each_segment(bvec, e->private_bio, i, 0) {
+			drbd_update_page_cache(mdev,sector,bvec);
+			sector += bvec->bv_len>>9;
+		}
+	}
+
 	return ok;
 }
 

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2007-05-22 13:04:31 UTC (rev 2901)
+++ trunk/drbd/linux/drbd.h	2007-05-22 13:12:31 UTC (rev 2902)
@@ -112,6 +112,7 @@
 	UnknownNetLinkPacket,
 	HaveNoDiskConfig,
 	ProtocolCRequired,
+	PreHeatAndTwoPrimaries,
 
 	/* insert new ones above this line */
 	AfterLastRetCode

Modified: trunk/drbd/linux/drbd_nl.h
===================================================================
--- trunk/drbd/linux/drbd_nl.h	2007-05-22 13:04:31 UTC (rev 2901)
+++ trunk/drbd/linux/drbd_nl.h	2007-05-22 13:12:31 UTC (rev 2902)
@@ -51,6 +51,7 @@
 	BIT(		27,	T_MAY_IGNORE,	want_lose)
 	BIT(		28,	T_MAY_IGNORE,	two_primaries)
 	BIT(		41,	T_MAY_IGNORE,	always_asbp)
+	BIT(		42,	T_MAY_IGNORE,	preheat_cache)
 )
 
 PACKET(disconnect, 6, )

Modified: trunk/scripts/drbd.conf
===================================================================
--- trunk/scripts/drbd.conf	2007-05-22 13:04:31 UTC (rev 2901)
+++ trunk/scripts/drbd.conf	2007-05-22 13:12:31 UTC (rev 2902)
@@ -256,6 +256,10 @@
     # cram-hmac-alg "sha1";
     # shared-secret "FooFunFactory";
 
+    # In case your application's performance depends on hot disk
+    # caches, DRBD can preheat the standby node's disk cache for your
+    # preheat-cache;
+
     # In case the nodes of your cluster nodes see each other again, after
     # an split brain situation in which both nodes where primary
     # at the same time, you have two diverged versions of your data.

Modified: trunk/user/drbdadm_scanner.fl
===================================================================
--- trunk/user/drbdadm_scanner.fl	2007-05-22 13:04:31 UTC (rev 2901)
+++ trunk/user/drbdadm_scanner.fl	2007-05-22 13:12:31 UTC (rev 2902)
@@ -83,6 +83,7 @@
 unplug-watermark	{ DP; CP; return TK_NET_OPTION;         }
 allow-two-primaries	{ DP; CP; return TK_NET_SWITCH;		}
 always-asbp		{ DP; CP; return TK_NET_SWITCH;		}
+preheat-cache		{ DP; CP; return TK_NET_SWITCH;		}
 rate			{ DP; CP; RC(RATE); return TK_SYNCER_OPTION;	}
 after			{ DP; CP; return TK_SYNCER_OPTION;	}
 al-extents		{ DP; CP; RC(AL_EXTENTS); return TK_SYNCER_OPTION;}

Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2007-05-22 13:04:31 UTC (rev 2901)
+++ trunk/user/drbdsetup.c	2007-05-22 13:12:31 UTC (rev 2902)
@@ -307,6 +307,7 @@
 		 { "rr-conflict",'R',	T_rr_conflict,EH(rrcf_n,RR_CONFLICT) },
 		 { "ping-timeout",'p',  T_ping_timeo,	   EN(PING_TIMEO,1,"1/10 seconds") },
 		 { "discard-my-data",'D', T_want_lose,     EB },
+		 { "preheat-cache",'h',   T_preheat_cache, EB },
 		 CLOSE_OPTIONS }} }, },
 
 	{"disconnect", P_disconnect, F_CONFIG_CMD, {{NULL, NULL}} },
@@ -393,7 +394,9 @@
 	EM(PauseFlagAlreadyClear) = "Sync-pause flag is already cleared",
 	EM(DiskLowerThanOutdated) = "Disk state is lower than outdated",
 	EM(HaveNoDiskConfig) = "Device does not have a disk-config",
-	EM(ProtocolCRequired) = "Protocol C required"
+	EM(ProtocolCRequired) = "Protocol C required",
+	EM(PreHeatAndTwoPrimaries) = "Preheat-cache and allow-two-primaries"
+	"may not be set concurrently"
 };
 #define MAX_ERROR (sizeof(error_messages)/sizeof(*error_messages))
 const char * error_to_string(int err_no)



More information about the drbd-cvs mailing list