[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