From drbd-cvs at lists.linbit.com  Fri May  4 15:41:32 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri May  4 15:41:33 2007
Subject: [DRBD-cvs] svn commit by phil - r2867 - branches/drbd-0.7/drbd -
	Make DRBD-0.7 to compile on newer ubuntu distros. 
Message-ID: <20070504134132.39C582E0374A@mail.linbit.com>

Author: phil
Date: 2007-05-04 15:41:31 +0200 (Fri, 04 May 2007)
New Revision: 2867

Modified:
   branches/drbd-0.7/drbd/Makefile
Log:
Make DRBD-0.7 to compile on newer ubuntu distros.


Modified: branches/drbd-0.7/drbd/Makefile
===================================================================
--- branches/drbd-0.7/drbd/Makefile	2007-04-27 11:11:02 UTC (rev 2866)
+++ branches/drbd-0.7/drbd/Makefile	2007-05-04 13:41:31 UTC (rev 2867)
@@ -56,6 +56,11 @@
    )
 else
   # called from command line in current directory
+
+  # for some reason some of the commands below only work correctly in bash,
+  # and not in e.g. dash. I'm too lazy to fix it to be compatible.
+  SHELL=/bin/bash
+
   DRBDSRC := $(shell pwd)
   CONFIG_BLK_DEV_DRBD := m
   export DRBDSRC CONFIG_BLK_DEV_DRBD

From drbd-cvs at lists.linbit.com  Fri May  4 22:54:41 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri May  4 22:54:43 2007
Subject: [DRBD-cvs] svn commit by phil - r2868 - in branches/drbd-0.7: drbd
	drbd/linux scripts - Get rid of this "kmem_cache_t is
	depricated" warning. 
Message-ID: <20070504205442.1364F2E08754@mail.linbit.com>

Author: phil
Date: 2007-05-04 22:54:40 +0200 (Fri, 04 May 2007)
New Revision: 2868

Modified:
   branches/drbd-0.7/drbd/drbd_compat_types.h
   branches/drbd-0.7/drbd/drbd_int.h
   branches/drbd-0.7/drbd/drbd_main.c
   branches/drbd-0.7/drbd/linux/drbd_config.h
   branches/drbd-0.7/scripts/adjust_drbd_config_h.sh
Log:
Get rid of this "kmem_cache_t is depricated" warning.


Modified: branches/drbd-0.7/drbd/drbd_compat_types.h
===================================================================
--- branches/drbd-0.7/drbd/drbd_compat_types.h	2007-05-04 13:41:31 UTC (rev 2867)
+++ branches/drbd-0.7/drbd/drbd_compat_types.h	2007-05-04 20:54:40 UTC (rev 2868)
@@ -314,8 +314,16 @@
 #define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
 #endif
 
+typedef kmem_cache_t drbd_kmem_cache_t;
+
 #else // LINUX 2.6
 
+#ifdef USE_KMEM_CACHE_S
+typedef struct kmem_cache_s drbd_kmem_cache_t;
+#else
+typedef struct kmem_cache drbd_kmem_cache_t;
+#endif
+
 typedef struct bio drbd_bio_t;
 
 #define REQ_NEXT bi_next

Modified: branches/drbd-0.7/drbd/drbd_int.h
===================================================================
--- branches/drbd-0.7/drbd/drbd_int.h	2007-05-04 13:41:31 UTC (rev 2867)
+++ branches/drbd-0.7/drbd/drbd_int.h	2007-05-04 20:54:40 UTC (rev 2868)
@@ -1028,8 +1028,8 @@
 // drbd_main.c
 extern drbd_dev *drbd_conf;
 extern int minor_count;
-extern kmem_cache_t *drbd_request_cache;
-extern kmem_cache_t *drbd_ee_cache;
+extern drbd_kmem_cache_t *drbd_request_cache;
+extern drbd_kmem_cache_t *drbd_ee_cache;
 extern mempool_t *drbd_request_mempool;
 
 // drbd_req

Modified: branches/drbd-0.7/drbd/drbd_main.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_main.c	2007-05-04 13:41:31 UTC (rev 2867)
+++ branches/drbd-0.7/drbd/drbd_main.c	2007-05-04 20:54:40 UTC (rev 2868)
@@ -162,8 +162,8 @@
 STATIC int *drbd_sizes;
 )
 struct Drbd_Conf *drbd_conf;
-kmem_cache_t *drbd_request_cache;
-kmem_cache_t *drbd_ee_cache;
+drbd_kmem_cache_t *drbd_request_cache;
+drbd_kmem_cache_t *drbd_ee_cache;
 mempool_t *drbd_request_mempool;
 
 STATIC struct block_device_operations drbd_ops = {

Modified: branches/drbd-0.7/drbd/linux/drbd_config.h
===================================================================
--- branches/drbd-0.7/drbd/linux/drbd_config.h	2007-05-04 13:41:31 UTC (rev 2867)
+++ branches/drbd-0.7/drbd/linux/drbd_config.h	2007-05-04 20:54:40 UTC (rev 2868)
@@ -71,4 +71,9 @@
 
 //#define NO_MORE_DEV_FS
 
+// 2.6.something has deprecated kmem_cache_t
+// some older still use it.
+// some have it defined as struct kmem_cache_s, some as struct kmem_cache
+//#define USE_KMEM_CACHE_S
+
 #endif

Modified: branches/drbd-0.7/scripts/adjust_drbd_config_h.sh
===================================================================
--- branches/drbd-0.7/scripts/adjust_drbd_config_h.sh	2007-05-04 13:41:31 UTC (rev 2867)
+++ branches/drbd-0.7/scripts/adjust_drbd_config_h.sh	2007-05-04 20:54:40 UTC (rev 2868)
@@ -90,7 +90,8 @@
   else
     have_mm_inline_h=0
   fi
-    no_more_dev_fs=0
+  no_more_dev_fs=0
+  have_kmem_cache_s=0
 else
     # 2.6. kernel. just leave it alone...
     need_sighand_hack=0
@@ -99,6 +100,12 @@
     have_find_next_bit=0
     have_mm_inline_h=0
     no_more_dev_fs=1
+    
+    if grep_q "typedef.*kmem_cache_s" $KDIR/include/linux/slab.h ; then
+      have_kmem_cache_s=1
+    else
+      have_kmem_cache_s=0
+    fi
 fi
 
 test -e ./linux/drbd_config.h.orig || cp ./linux/drbd_config.h{,.orig}
@@ -115,7 +122,9 @@
  s{.*(#define HAVE_MM_INLINE_H.*)}
   { ( $have_mm_inline_h ? '' : '//' ) . \$1}e;
  s{.*(#define NO_MORE_DEV_FS.*)}
-  { ( $no_more_dev_fs ? '' : '//' ) . \$1}e;" \
+  { ( $no_more_dev_fs ? '' : '//' ) . \$1}e;
+ s{.*(#define USE_KMEM_CACHE_S.*)}
+  { ( $have_kmem_cache_s ? '' : '//' ) . \$1}e;" \
 	  < ./linux/drbd_config.h \
 	  > ./linux/drbd_config.h.new
 

From drbd-cvs at lists.linbit.com  Fri May  4 22:56:18 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri May  4 22:56:19 2007
Subject: [DRBD-cvs] svn commit by phil - r2869 - branches/drbd-0.7/drbd -
	Removed an unused variable called "empty" ; ) 
Message-ID: <20070504205618.7773C2E0879B@mail.linbit.com>

Author: phil
Date: 2007-05-04 22:56:17 +0200 (Fri, 04 May 2007)
New Revision: 2869

Modified:
   branches/drbd-0.7/drbd/drbd_receiver.c
Log:
Removed an unused variable called "empty" ;)


Modified: branches/drbd-0.7/drbd/drbd_receiver.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_receiver.c	2007-05-04 20:54:40 UTC (rev 2868)
+++ branches/drbd-0.7/drbd/drbd_receiver.c	2007-05-04 20:56:17 UTC (rev 2869)
@@ -2312,7 +2312,6 @@
 	int received = 0;
 	int expect   = sizeof(Drbd_Header);
 	int cmd      = -1;
-	int empty;
 
 	static struct asender_cmd asender_tbl[] = {
 		[Ping]      ={ sizeof(Drbd_Header),           got_Ping },

From drbd-cvs at lists.linbit.com  Sun May  6 22:02:09 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Sun May  6 22:02:13 2007
Subject: [DRBD-cvs] svn commit by phil - r2870 - trunk/documentation - A
	number spelling fixes in the documentation. 
Message-ID: <20070506200209.27D182E110A5@mail.linbit.com>

Author: phil
Date: 2007-05-06 22:02:07 +0200 (Sun, 06 May 2007)
New Revision: 2870

Modified:
   trunk/documentation/drbd.conf.sgml
   trunk/documentation/drbdadm.sgml
   trunk/documentation/drbddisk.sgml
   trunk/documentation/drbdmeta.sgml
   trunk/documentation/drbdsetup.sgml
Log:
A number spelling fixes in the documentation.


Modified: trunk/documentation/drbd.conf.sgml
===================================================================
--- trunk/documentation/drbd.conf.sgml	2007-05-04 20:56:17 UTC (rev 2869)
+++ trunk/documentation/drbd.conf.sgml	2007-05-06 20:02:07 UTC (rev 2870)
@@ -55,14 +55,14 @@
  The device which runs
  on host <replaceable>thost1</replaceable> uses
  <replaceable>/dev/drbd1</replaceable> as devices for its application, and
- <replaceable>/dev/hda7</replaceable> as low level storage for the data.
- The IP addresses are used to specify the networking interfaces to use.
+ <replaceable>/dev/hda7</replaceable> as low-level storage for the data.
+ The IP addresses are used to specify the networking interfaces to be used.
  An eventually running resyncprocess should use about 10MByte/second of IO
- bandwith.
+ bandwidth.
  </para>
  <para>
  There may be multiple resource sections in a single drbd.conf file.
- For more examples please have a look at the
+ For more examples, please have a look at the
  <ulink url="http://www.linux-ha.org/DRBD/QuickStart07">
  <citetitle>DRBD Quickstart Guide</citetitle></ulink>.
  </para>
@@ -83,7 +83,7 @@
   A parameter starts with the identifier of the parameter followed
   by whitespace. Every subsequent character
   is considered
-  as part of the parameters value. A special case are Boolean
+  as part of the parameter's value. A special case are Boolean
   parameters which only consist of the identifier.
   Parameters are terminated by a semicolon (<quote>;</quote>).
   </para>
@@ -105,7 +105,7 @@
   <indexterm><primary>drbd.conf</primary><secondary>skip</secondary></indexterm>
     Comments out chunks of text, even spanning more than one line.
     Characters between the keyword <option>skip</option> and the opening
-    brace (<quote>{</quote>)are ignored. Everything enclosed by the braces
+    brace (<quote>{</quote>) are ignored. Everything enclosed by the braces
     is skipped.
     This comes in handy, if you just want to comment out
     some 'resource [name] {...}' section: just precede it with 'skip'.
@@ -131,7 +131,7 @@
   <listitem><para>
   <indexterm><primary>drbd.conf</primary><secondary>common</secondary></indexterm>
     All resources interhit the options set in this section.
-    The common section might have a
+    The common section might have 
     a <option>startup</option>,
     a <option>syncer</option>,
     a <option>handlers</option>,
@@ -193,7 +193,7 @@
   <indexterm><primary>drbd.conf</primary><secondary>net</secondary></indexterm>
     This section is used to fine tune DRBD's properties. Please
     refer to <citerefentry><refentrytitle>drbdsetup</refentrytitle>
-    <manvolnum>8</manvolnum></citerefentry> for detailed description
+    <manvolnum>8</manvolnum></citerefentry> for a detailed description
     of this section's parameters.
     Optional parameters:
     <option>sndbuf-size</option>, <option>timeout</option>,
@@ -214,7 +214,7 @@
   <indexterm><primary>drbd.conf</primary><secondary>startup</secondary></indexterm>
     This section is used to fine tune DRBD's properties. Please
     refer to <citerefentry><refentrytitle>drbdsetup</refentrytitle>
-    <manvolnum>8</manvolnum></citerefentry> for detailed description
+    <manvolnum>8</manvolnum></citerefentry> for a detailed description
     of this section's parameters.
     Optional parameters:
     <option>wfc-timeout</option>, <option>degr-wfc-timeout</option>.
@@ -229,7 +229,7 @@
     This section is used to fine tune the synchronisation daemon
     for the device. Please
     refer to <citerefentry><refentrytitle>drbdsetup</refentrytitle>
-    <manvolnum>8</manvolnum></citerefentry> for detailed description
+    <manvolnum>8</manvolnum></citerefentry> for a detailed description
     of this section's parameters.
     Optional parameters:
     <option>rate</option>, <option>after</option>, <option>al-extents</option>.
@@ -241,7 +241,7 @@
   <term><option>handlers</option></term>
   <listitem><para>
   <indexterm><primary>drbd.conf</primary><secondary>handlers</secondary></indexterm>
-    In this section can define handlers (executables) that are executed
+    In this section you can define handlers (executables) that are executed
     by the DRBD system in response to certain events.
     Optional parameters:
     <option>pri-on-incon-degr</option>, <option>pri-lost-after-sb</option>,
@@ -268,7 +268,7 @@
   <para>Use <replaceable>minor-count</replaceable>
    if you want to define massively more resources later without reloading
    the DRBD kernel
-   module. Per default the module loads with 11 more than you have currently
+   module. Per default the module loads with 11 more resources than you have currently
    in your config but at least 32.</para>
    </listitem>
 </varlistentry>
@@ -279,9 +279,9 @@
   <indexterm><primary>drbd.conf</primary><secondary>dialog-refresh </secondary></indexterm>
     <replaceable>time</replaceable> may be 0 or a positive number.
   </para>
-  <para>The user dialog redraws the second count every
+  <para>The user dialogue redraws the second count every
    <replaceable>time</replaceable> seconds (or does no redraws if
-   <replaceable>time</replaceable> is zero). The default is 1.</para>
+   <replaceable>time</replaceable> is 0). The default value is 1.</para>
    </listitem>
 </varlistentry>
 
@@ -291,7 +291,7 @@
   <indexterm><primary>drbd.conf</primary><secondary>disable-ip-verification</secondary></indexterm>
   <para>Use <replaceable>disable-ip-verification</replaceable>
    if, for some obscure reasons, drbdadm can/might not use ip or ifconfig
-   to do a sanity check for the IP address, you can disable it with this
+   to do a sanity check for the IP address. You can disable the IP verification  with 
    this option.
    </para>
    </listitem>
@@ -331,7 +331,7 @@
   <listitem><para>
   <indexterm><primary>drbd.conf</primary><secondary>incon-degr-cmd</secondary></indexterm>
     In case a node starts up in degraded mode (degr-wfc-timeout is set) and
-    its local replica of the data is inconsistent it executes the
+    its local replica of the data is inconsistent, it executes the
     <replaceable>command</replaceable>. If the command exits without
     error, drbddisk expects the DRBD device to be in primary state.
   </para>
@@ -349,13 +349,13 @@
   </para>
   <para>
     The device nodes must have the same major number as the DRBD
-    driver has. With the current implementation major 147 is used
+    driver. With the current implementation major 147 is used
     and the corresponding device nodes are usually named
     <option>/dev/drbd0</option>, <option>/dev/drbd1</option>, etc.
     ( All releases before drbd-0.7.1 used major 43 and the device
     files /dev/nb*. )
   </para>
-  <para>Installation scripts of the DRBD package provide, that
+  <para>Installation scripts of the DRBD package require that
   <option>/dev/drbd0</option> to <option>/dev/drbd8</option> are
   predefined in your system. To be sure, issue something like ls /dev/drbd*.
   </para>
@@ -400,9 +400,9 @@
   <listitem><para>
   <indexterm><primary>drbd.conf</primary><secondary>meta-disk</secondary></indexterm>
   <indexterm><primary>drbd.conf</primary><secondary>flexible-meta-disk</secondary></indexterm>
-    internal means, that the last part of the backing device are used to store
+    Internal means that the last part of the backing device is used to store
     the meta-data. You must not use <replaceable>[index]</replaceable> with
-    internal. Note: Regardless if you use the <option>meta-disk</option> or
+    internal. Note: Regardless of whether you use the <option>meta-disk</option> or
     the <option>flexible-meta-disk</option> keyword, it will always be of
     the size needed for the remaining storage size.
   </para>
@@ -439,10 +439,9 @@
   </para>
   <para>pass_on: Report the io-error to the upper layers. On Primary report
   it to the mounted file system. On Secondary ignore it.</para>
-  <para>call-local-io-error: Thall the handler script
+  <para>call-local-io-error: Call the handler script
          <option>local-io-error</option>.</para>
-  <para>detach: The node drops its low level device, and continues in disk
-  less mode.</para>
+  <para>detach: The node drops its low level device, and continues in diskless mode.</para>
   </listitem>
 </varlistentry>
 
@@ -450,7 +449,7 @@
   <term><option>fencing <replaceable>fencing_policy</replaceable></option></term>
   <listitem><para>
   <indexterm><primary>drbd.conf</primary><secondary>fencing</secondary></indexterm>
-  Under <option>fencing</option> we understand preventative
+  Under <option>fencing</option> we understand preventive
   measures to avoid situations where both nodes are primary
   and disconnected (AKA split brain).
   </para>
@@ -462,21 +461,21 @@
       </para></listitem></varlistentry>
     <varlistentry><term><option>resource-only</option></term>
       <listitem><para>
-	If a node becomes a disconnected primary it tries to outdate
+	If a node becomes a disconnected primary, it tries to outdate
 	the peer's disk. This is done by calling the outdate-peer
 	handler. The handler is supposed to reach the other node over
-	alternative communication pathes and call 'drbdadm outdate
+	alternative communication paths and call 'drbdadm outdate
 	res' there.
       </para></listitem></varlistentry>
     <varlistentry><term><option>resource-and-stonith</option></term>
       <listitem><para>
-	If a node becomes a disconnected primary it freezes all
+	If a node becomes a disconnected primary, it freezes all
 	its IO operations and calls its outdate-peer handler. The
-	outdate-peer hander is supposed to reach the peer over
-	alternative communicaton pathes and call 'drbdadm outdate
-	res' there. In case it can not reach the peer it should
+	outdate-peer handler is supposed to reach the peer over
+	alternative communicaton paths and call 'drbdadm outdate
+	res' there. In case it cannot reach the peer it should
 	stonith the peer. IO is resumed as soon as the situation
-	is resolved. In case your handler fails you can resume
+	is resolved. In case your handler fails, you can resume
 	IO with the <option>resume-io</option> command.
       </para></listitem></varlistentry>
     </variablelist>
@@ -488,17 +487,17 @@
   <listitem>
   <indexterm><primary>drbd.conf</primary><secondary>use-bmbv</secondary></indexterm>
     <para>
-      In case the backing storage's driver has a merge_bvec_fn() function
-      (At time of writing the only known drivers which have such a function
+      In case the backing storage's driver has a merge_bvec_fn() function,
+       DRBD has to pretend that it can only process IO requests in
+      units not lager than 4kByte. (At time of writing the only known drivers which have such a function
       are: md (software raid driver), dm (device mapper - LVM) and DRBD
-      itself) drbd has to pretend that it can only process IO requests in
-      units not lager than 4kByte.</para>
+      itself)</para>
     <para>
       To get best performance out of DRBD on top of software raid (or any
       other driver with a merge_bvec_fn() function) you might enable this
-      function, iff you know for sure that the merge_bvec_fn() function will
+      function, if you know for sure that the merge_bvec_fn() function will
       deliver the same results on all nodes of your cluster. I.e. the
-      physical disks of the software raid are of the exact same type.  USE
+      physical disks of the software raid are of exactly the same type.  USE
       THIS OPTION ONLY IF YOU KNOW WHAT YOU ARE DOING.</para>
    </listitem>
 </varlistentry>
@@ -507,10 +506,10 @@
   <term><option>sndbuf-size <replaceable>size</replaceable></option></term>
   <listitem><para>
   <indexterm><primary>drbd.conf</primary><secondary>sndbuf-size </secondary></indexterm>
-  <replaceable>size</replaceable> is size of the TCP socket send buffer.
-  Default is 128K. You can specify smaller or larger values. Larger values
+  <replaceable>size</replaceable> is the size of the TCP socket send buffer.
+  The default value is 128K. You can specify smaller or larger values. Larger values
   are appropriate for reasonable write throughput with protocol A over high
-  latency networks. Very large values like 1M may cause problems. Even values
+  latency networks. Very large values like 1M may cause problems. Also values
   below 32K do not make much sense.
   </para>
   </listitem>
@@ -553,9 +552,9 @@
   <term><option>ping-timeout <replaceable>time</replaceable></option></term>
   <listitem><para>
   <indexterm><primary>drbd.conf</primary><secondary>ping-timeout</secondary></indexterm>
-    The time the peer has time to answer to a keep-alive packet, it. In case
+    The time the peer has time to answer to a keep-alive packet. In case
     the peer's reply is not received within this time period, it is
-    considered as dead. The default is 500ms, the default unit is 100ms.
+    considered as dead. The default value is 500ms, the default unit is 100ms.
   </para></listitem>
 </varlistentry>
 
@@ -563,12 +562,12 @@
   <term><option>max-buffers <replaceable>number</replaceable></option></term>
   <listitem><para>
   <indexterm><primary>drbd.conf</primary><secondary>max-buffers </secondary></indexterm>
-  Maximal number of requests to be allocated by DRBD. Unit is PAGE_SIZE,
+  Maximum number of requests to be allocated by DRBD. Unit is PAGE_SIZE,
   which is 4 KB on most systems.
   The minimum is hardcoded to 32 (=128 KB).
-  For high performance installations it might help, if you
+  For high-performance installations it might help, if you
   increase that number. These buffers are used to hold
-  datablocks while they are written to disk.
+  data blocks while they are written to disk.
   </para></listitem>
 </varlistentry>
 
@@ -580,7 +579,7 @@
 	      request for <replaceable>count</replaceable> times the
 	      <replaceable>timeout</replaceable>, it is expelled from the
 	      cluster. (I.e. the primary node goes into StandAlone mode.)
-	      The default is 0, which disables this feature.
+	      The default value is 0, which disables this feature.
   </para></listitem>
 </varlistentry>
 
@@ -589,7 +588,7 @@
   <listitem><para>
   <indexterm><primary>drbd.conf</primary><secondary>max-epoch-size </secondary></indexterm>
   The highest number of data blocks between two write barriers.
-  If you set this smaller than 10 you might decrease your performance.
+  If you set this smaller than 10, you might decrease your performance.
   </para></listitem>
 </varlistentry>
 
@@ -597,10 +596,10 @@
   <term><option>allow-two-primaries</option></term>
   <listitem><para>
   <indexterm><primary>drbd.conf</primary><secondary>allow-two-primaries</secondary></indexterm>
-    With this option set you might make both nodes primary. You only should
-    use this options if you use a shared storage file system on top of
+    With this option set you may assign primary role to both nodes. You only should
+    use this option if you use a shared storage file system on top of
     DRBD. At the time of writing the only ones are: OCFS2 and GFS. If you
-    use this option with any other filesystem you are goint to crash your
+    use this option with any other file system, you are going to crash your
     nodes and to corrupt your data!
   </para></listitem>
 </varlistentry>
@@ -614,7 +613,7 @@
       (secondary) node exceeds the unplug-watermark, we trigger
       the request processing of our backing storage device.
       Some storage controllers deliver better performance with small
-      values, other deliver best performance when it is set to
+      values, others deliver best performance when the value is set to
       the same value as max-buffers. Minimum 16, default 128, maximum
       131072.
     </para>
@@ -625,10 +624,10 @@
   <term><option>cram-hmac-alg</option></term>
   <listitem><para>
   <indexterm><primary>drbd.conf</primary><secondary>cram-hmac-alg</secondary></indexterm>
-    You need to specifying the HMAC algorithm to enable peer authentication
-    at all. It is strongly enouraged to use peer authentication. The HMAC
-    algorithm which will be used for the challenge response authentication
-    of the peer. You might specify any digest algorithm that is named in
+    You need to specify the HMAC algorithm to enable peer authentication
+    at all. You are strongly enouraged to use peer authentication. The HMAC
+    algorithm will be used for the challenge response authentication
+    of the peer. You may specify any digest algorithm that is named in
     /proc/crypto.
   </para></listitem>
 </varlistentry>
@@ -655,13 +654,12 @@
 		</para></listitem></varlistentry>
 	        <varlistentry><term><option>discard-younger-primary</option></term>
 		<listitem><para>
-		  Auto sync from the node that was primary before the split
-		  brain situation happened.
+		  Auto sync from the node that was primary before the split-brain situation happened.
 		</para></listitem></varlistentry>
 		<varlistentry><term><option>discard-older-primary</option></term>
 		<listitem><para>
 		Auto sync from the node that became primary as second during
-		the split brain situation.
+		the split-brain situation.
 		</para></listitem></varlistentry>
 		<varlistentry><term><option>discard-zero-changes</option></term>
 		<listitem><para>
@@ -701,18 +699,18 @@
 	        <varlistentry><term><option>consensus</option></term>
 		<listitem><para>
 		  Discard the version of the secondary if the outcome
-                  if the <option>after-sb-0pri</option> algorithm would also
+                  of the <option>after-sb-0pri</option> algorithm would also
 		  destroy the current secondary's data. Otherwise disconnect.
 		</para></listitem></varlistentry>
 		<varlistentry><term><option>violently-as0p</option></term>
 		<listitem><para>
-                  Always take the decission of the <option>after-sb-0pri</option>
-                  algorithm. Even if that causes case an erratic change of
-                  the primarie's view of the data.  This is only usefull if
-                  you use an 1node FS (i.e.  not OCFS2 or GFS) with the
-                  allow-two-primaries flag, _AND_ you really know what you
+                  Always take the decision of the <option>after-sb-0pri</option>
+                  algorithm. Even if that causes an erratic change of
+                  the primary's view of the data.  This is only useful if
+                  you use a 1node FS (i.e.  not OCFS2 or GFS) with the
+                  allow-two-primaries flag, _AND_ if you really know what you
                   are doing.  This is DANGEROUS and MAY CRASH YOUR MACHINE
-                  if you have a FS mounted on the primary node.
+                  if you have an FS mounted on the primary node.
 		</para></listitem></varlistentry>
 		<varlistentry><term><option>discard-secondary</option></term>
 		<listitem><para>
@@ -721,7 +719,7 @@
 		<varlistentry><term><option>call-pri-lost-after-sb</option></term>
 		<listitem><para>
 		  Always honour the outcome of the <option>after-sb-0pri
-		  </option> algorithm. In case it decides the the current
+		  </option> algorithm. In case it decides the current
 		  secondary has the right data, it calls the "pri-lost-after-sb"
 		  handler on the current primary.
 		</para></listitem></varlistentry>
@@ -743,19 +741,19 @@
 		</para></listitem></varlistentry>
               <varlistentry><term><option>violently-as0p</option></term>
 	        <listitem><para>
-                  Always take the decission of the <option>after-sb-0pri</option>
-                  algorithm. Even if that causes case an erratic change of
-                  the primarie's view of the data.  This is only usefull if
-                  you use an 1node FS (i.e.  not OCFS2 or GFS) with the
-                  allow-two-primaries flag, _AND_ you really know what you
+                  Always take the decision of the <option>after-sb-0pri</option>
+                  algorithm. Even if that causes an erratic change of
+                  the primary's view of the data.  This is only useful if
+                  you use a 1node FS (i.e.  not OCFS2 or GFS) with the
+                  allow-two-primaries flag, _AND_ if you really know what you
                   are doing.  This is DANGEROUS and MAY CRASH YOUR MACHINE
-                  if you have a FS mounted on the primary node.
+                  if you have an FS mounted on the primary node.
 		</para></listitem></varlistentry>
 	        <varlistentry><term><option>call-pri-lost-after-sb</option></term>
 		<listitem><para>
                    Call the "pri-lost-after-sb" helper program on one of the
     	           machines. This program is expected to reboot the
-    	           machine. (I.e. make it secondary.)
+    	           machine, i.e. make it secondary.
 		</para></listitem></varlistentry>
               </variablelist>
 	  </listitem>
@@ -766,14 +764,14 @@
 	  <listitem>
 	    <para>
 	      Normally the automatic after-split-brain policies are only 
-	      used if current state of the UUIDs do not indicate the 
+	      used if current states of the UUIDs do not indicate the 
 	      presence of a third node.
 	    </para>
 	    <para>
 	      With this option you request that the automatic 
 	      after-split-brain policies are used as long as the data
 	      sets of the nodes are somehow related. This might cause
-	      a full sync, if the UUIDs indicates the presence of a third
+	      a full sync, if the UUIDs indicate the presence of a third
 	      node. (Or double faults led to strange UUID sets.)
 	    </para>
 	  </listitem>
@@ -784,8 +782,8 @@
 	  <listitem>
   <indexterm><primary>drbd.conf</primary><secondary>rr-conflict </secondary></indexterm>
 	    <para>
-	    To solve the cases when the outcome of the resync decission is
-	    incompatible to the current role assignment in the cluster.
+	    To solve the cases when the outcome of the resync decision is
+	    incompatible with the current role assignment in the cluster.
 	    </para>
             <variablelist>
               <varlistentry><term><option>disconnect</option></term>
@@ -795,14 +793,14 @@
               <varlistentry><term><option>violently</option></term>
 	        <listitem><para>
                    Sync to the primary node is allowed, violating the
-    	           assumption that data on a block device is stable for one
+    	           assumption that data on a block device are stable for one
     	           of the nodes. DANGEROUS, DO NOT USE.
 		</para></listitem></varlistentry>
 	        <varlistentry><term><option>call-pri-lost</option></term>
 		<listitem><para>
                    Call the "pri-lost" helper program on one of the
     	           machines. This program is expected to reboot the
-    	           machine. (I.e. make it secondary.)
+    	           machine, i.e. make it secondary.
 		</para></listitem></varlistentry>
               </variablelist>
 	  </listitem>
@@ -815,10 +813,10 @@
   The init script <citerefentry><refentrytitle>drbd</refentrytitle>
   <manvolnum>8</manvolnum></citerefentry> blocks the boot process
   until the DRBD resources are connected.
-  This is so when the cluster manager starts later,
+  When the cluster manager starts later,
   it does not see a resource with internal split-brain.
   In case you want to limit the wait time, do it here.
-  Default is 0, which means unlimited. Unit is seconds.
+  Default is 0, which means unlimited. The unit is seconds.
   </para></listitem>
 </varlistentry>
 
@@ -831,7 +829,7 @@
   is rebooted, this timeout value is used instead of wfc-timeout,
   because the peer is less likely to show up in time,
   if it had been dead before.
-  Default is 60, unit is seconds. Value 0 means unlimited.
+  The default value is 60, the unit is seconds. Value 0 means unlimited.
   </para>
   </listitem>
 </varlistentry>
@@ -840,9 +838,9 @@
   <term><option>rate <replaceable>rate</replaceable></option></term>
   <listitem><para>
   <indexterm><primary>drbd.conf</primary><secondary>rate </secondary></indexterm>
-  To ensure smooth operation of the application on top of DRBD,
+  To ensure a smooth operation of the application on top of DRBD,
   it is possible to limit the bandwidth which may be used by
-  background synchronizations. The default is 250 KB/sec, the
+  background synchronisations. The default is 250 KB/sec, the
   default unit is KB/sec. Optional suffixes K, M, G are allowed.
   </para>
   </listitem>
@@ -852,10 +850,10 @@
   <term><option>after <replaceable>res-name</replaceable></option></term>
   <listitem><para>
   <indexterm><primary>drbd.conf</primary><secondary>after </secondary></indexterm>
-  By default resynchronization of all devices would run in parallel.
-  By defining an sync-after dependency the resynchronisation of this
-  resource will start only if the resoruce <replaceable>res-name</replaceable>
-  is already in connected state (=finished its resynchronisation).
+  By default, resynchronisation of all devices would run in parallel.
+  By defining a sync-after dependency, the resynchronisation of this
+  resource will start only if the resource <replaceable>res-name</replaceable>
+  is already in connected state (= finished its resynchronisation).
   </para></listitem>
 </varlistentry>
 
@@ -863,10 +861,10 @@
   <term><option>al-extents <replaceable>extents</replaceable></option></term>
   <listitem><para>DRBD automatically performs hot area detection. With this
   <indexterm><primary>drbd.conf</primary><secondary>al-extents </secondary></indexterm>
-  parameter you control how big the hot area (=active set) can
-  get. Each extent marks 4M of the backing storage (=low level device).
-  In case a primary node leaves the cluster unexpectedly the areas covered
-  by the active set must be resynced upon rejoin of the failed
+  parameter you control how big the hot area (= active set) can
+  get. Each extent marks 4M of the backing storage (= low-level device).
+  In case a primary node leaves the cluster unexpectedly, the areas covered
+  by the active set must be resynced upon rejoining of the failed
   node. The data structure is stored in the meta-data area, therefore each
   change of the active set is a write operation
   to the meta-data device. A higher number of extents gives
@@ -881,22 +879,22 @@
   <term><option>pri-on-incon-degr <replaceable>cmd</replaceable></option></term>
   <listitem><para> This handler is called if the node is primary, degraded
   <indexterm><primary>drbd.conf</primary><secondary>pri-on-incon-degr </secondary></indexterm>
-  and the local copy of the data is inconsistent.</para></listitem>
+  and if the local copy of the data is inconsistent.</para></listitem>
   </varlistentry>
 
 <varlistentry>
   <term><option>pri-lost-after-sb <replaceable>cmd</replaceable></option></term>
   <listitem><para> The node is currently primary, but lost the after split
   <indexterm><primary>drbd.conf</primary><secondary>pri-lost-after-sb </secondary></indexterm>
-  brain auto recovery procedure. As as consequence it should go away.
+  brain auto recovery procedure. As as consequence, it should be abandoned.
   </para></listitem> </varlistentry>
 
 <varlistentry>
   <term><option>pri-lost <replaceable>cmd</replaceable></option></term>
   <listitem><para> The node is currently primary, but DRBD's algorithm
   <indexterm><primary>drbd.conf</primary><secondary>pri-lost </secondary></indexterm>
-  thinks, that it should become sync target, as consequence it should
-  give up its primary state.
+  thinks that it should become sync target. As a consequence it should
+  give up its primary role.
   </para></listitem> </varlistentry>
 
 <varlistentry>
@@ -904,7 +902,7 @@
   <listitem><para> The handler is part of the <option>fencing</option>
   <indexterm><primary>drbd.conf</primary><secondary>outdate-peer </secondary></indexterm>
   mechanism.  This handler is called in case the node needs to outdate the
-  peer's disk. It should use other communication pathes then DRBD's network
+  peer's disk. It should use other communication paths than DRBD's network
   link.  </para></listitem> </varlistentry>
 
 <varlistentry>

Modified: trunk/documentation/drbdadm.sgml
===================================================================
--- trunk/documentation/drbdadm.sgml	2007-05-04 20:56:17 UTC (rev 2869)
+++ trunk/documentation/drbdadm.sgml	2007-05-06 20:02:07 UTC (rev 2870)
@@ -89,7 +89,7 @@
         <term>detach</term>
         <listitem><para>
         <indexterm><primary>drbdadm</primary><secondary>detach</secondary></indexterm>
-          Removes the backing storage device from a DRBD resources's device.
+          Removes the backing storage device from a DRBD resource's device.
         </para></listitem>
       </varlistentry>
       <varlistentry>
@@ -105,14 +105,14 @@
         <listitem><para>
 	<indexterm><primary>drbdadm</primary><secondary>disconnect</secondary></indexterm>
           Removes the network configuration from the resource. The device
-	  will go into StandAllone state.
+	  will go into StandAlone state.
         </para></listitem>
       </varlistentry>
       <varlistentry>
         <term>syncer</term>
         <listitem><para>
 	<indexterm><primary>drbdadm</primary><secondary>syncer</secondary></indexterm>
-          Loads the resynchronization parameters into the device.
+          Loads the resynchronisation parameters into the device.
         </para></listitem>
       </varlistentry>
       <varlistentry>
@@ -134,16 +134,16 @@
         <listitem><para>
 	<indexterm><primary>drbdadm</primary><secondary>primary</secondary></indexterm>
           Switch the resource's device into primary state. You need to do
-	  this before you may mount a filesystem onto the device.
+	  this before you mount a filesystem onto the device.
         </para></listitem>
       </varlistentry>
       <varlistentry>
         <term>secondary</term>
         <listitem><para>
 	<indexterm><primary>drbdadm</primary><secondary>secondary</secondary></indexterm>
-          Brings the device back into secondary state. This is needed since in
-	  a connected DRBD device pair there might only be one of the two peers
-	  in primary state.
+          Brings the device back into secondary role. This is needed since in
+	  a connected DRBD device pair,  only one of the two peers may have
+	  primary role.
         </para></listitem>
       </varlistentry>
       <varlistentry>
@@ -151,7 +151,7 @@
         <listitem><para>
 	<indexterm><primary>drbdadm</primary><secondary>invalidate</secondary></indexterm>
           This forces DRBD to consider the data on the local backing
-	  storage device as out-of-sync. Therefor DRBD will copy each
+	  storage device as out-of-sync. Therefore DRBD will copy each
 	  and every block over from its peer, to bring the local storage
 	  device back in sync.
         </para></listitem>
@@ -160,7 +160,7 @@
         <term>invalidate_remote</term>
         <listitem><para>
 	<indexterm><primary>drbdadm</primary><secondary>invalidate_remote</secondary></indexterm>
-          This command is similar to the invalidate command, but the
+          This command is similar to the invalidate command, however, the
 	  backing storage of the peer is invalidated and hence rewritten
 	  with the data of the local node.
         </para></listitem>
@@ -169,7 +169,7 @@
         <term>resize</term>
         <listitem><para>
 	<indexterm><primary>drbdadm</primary><secondary>resize</secondary></indexterm>
-          DRBD will reexamine all sizing constraints, and re-size the
+          DRBD will reexamine all sizing constraints, and resize the
 	  resource's device accordingly. E.g. in case you increased the
 	  size of your backing storage devices (on both nodes of course),
 	  then DRBD will adopt to the new size after you called
@@ -180,7 +180,7 @@
         <term>create-md</term>
         <listitem><para>
 	<indexterm><primary>drbdadm</primary><secondary>create-md</secondary></indexterm>
-          Create-md initializes the meta data storage. This needs to be
+          Create-md initialises the meta data storage. This needs to be
 	  done before a DRBD resource can be taken online for the first
 	  time.
         </para></listitem>
@@ -190,7 +190,7 @@
         <listitem><para>
 	<indexterm><primary>drbdadm</primary><secondary>get-gi</secondary></indexterm>
           Get-gi shows a short textual repesentation of the data generation
-	  identifier.
+	  identifiers.
 	</para></listitem>
       </varlistentry>
       <varlistentry>
@@ -205,7 +205,7 @@
         <term>dump-md</term>
         <listitem><para>
 	<indexterm><primary>drbdadm</primary><secondary>dump-md</secondary></indexterm>
-          Dumps the whole contents of the meta data storage including
+          Dumps the whole contents of the meta data storage, including
 	  the stored bit-map and activity-log, in a textual representation.
         </para></listitem>
       </varlistentry>
@@ -220,7 +220,7 @@
         <term>adjust</term>
         <listitem><para>
 	<indexterm><primary>drbdadm</primary><secondary>adjust</secondary></indexterm>
-          Synchronizes the configuration of device with your configuration
+          Synchronises the configuration of the device with your configuration
 	  file. You should always examine the output of the dry-run
 	  mode before actually executing this command.
         </para></listitem>
@@ -244,14 +244,14 @@
         <term>cstate</term>
         <listitem><para>
 	<indexterm><primary>drbdadm</primary><secondary>cstate</secondary></indexterm>
-	  Shows the current connection status of the devices.
+	  Shows the current connection state of the devices.
 	</para></listitem>
       </varlistentry>
       <varlistentry>
         <term>dump</term>
         <listitem><para>
 	<indexterm><primary>drbdadm</primary><secondary>dump</secondary></indexterm>
-          Just parse the configuration file and dump it to stdout. Might
+          Just parse the configuration file and dump it to stdout. May
 	  be used to check the configuration file for syntactical correctness.
         </para></listitem>
       </varlistentry>
@@ -270,7 +270,7 @@
         <listitem><para>
 	<indexterm><primary>drbdadm</primary><secondary>pause-sync</secondary></indexterm>
           Temporarily suspend an ongoing resynchronisation by setting the
-          local pause flag. Resync only progresses if neighter the local
+          local pause flag. Resync only progresses if neither the local
           nor the remote pause flag is set. It might be desirable to
           postpone DRBD's resynchronisation after eventual
           resynchronisation of the backing storage's RAID setup.
@@ -289,14 +289,14 @@
         <term>dstate</term>
         <listitem><para>
 	<indexterm><primary>drbdadm</primary><secondary>dstate</secondary></indexterm>
-  	  Show the current state of the backing storeage devices. (local/peer)
+  	  Show the current state of the backing storage devices. (local/peer)
         </para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term>hidden-commands</term>
         <listitem><para>
-  	  Shows all on purpose undocumented commands.
+  	  Shows all commands undocumented on purpose.
         </para></listitem>
       </varlistentry>
 

Modified: trunk/documentation/drbddisk.sgml
===================================================================
--- trunk/documentation/drbddisk.sgml	2007-05-04 20:56:17 UTC (rev 2869)
+++ trunk/documentation/drbddisk.sgml	2007-05-06 20:02:07 UTC (rev 2870)
@@ -31,7 +31,7 @@
    The <option>/etc/ha.d/resource.d/drbddisk</option> script
    brings the local device of <replaceable>resource</replaceable> into
    primary state. It is designed to be
-   used by heartbeat.
+   used by Heartbeat.
   </para>
   <para>
     In order to use <option>/etc/ha.d/resource.d/drbddisk</option> you must

Modified: trunk/documentation/drbdmeta.sgml
===================================================================
--- trunk/documentation/drbdmeta.sgml	2007-05-04 20:56:17 UTC (rev 2869)
+++ trunk/documentation/drbdmeta.sgml	2007-05-06 20:02:07 UTC (rev 2870)
@@ -32,12 +32,12 @@
     <para>
       Drbdmeta is used to create, display and modify the contents of
       DRBD's meta data storage. Usually you do not want to use this
-      command directly but use it through the front end drbdadm.
+      command directly, but use it through the front end drbdadm.
     </para>
     <para>
       This command only works if the DRBD resource is currently down,
       or at least detached from its backing stoage. The first parameter
-      is the device node assosiated to the resource. With the second
+      is the device node associated to the resource. With the second
       parameter you select which the version of the meta data. Currently
       all major DRBD releases (0.6, 0.7 and 0.8) are supported.
     </para>
@@ -49,7 +49,7 @@
         <term>create-md</term>
         <listitem><para>
 	<indexterm><primary>drbdmeta</primary><secondary>create-md</secondary></indexterm>
-          Create-md initializes the meta data storage. This needs to be
+          Create-md initialises the meta data storage. This needs to be
 	  done before a DRBD resource can be taken online for the first
 	  time. In case there is already a meta data signature of an
 	  older format in place, drbdmeta will ask you if it should
@@ -61,8 +61,8 @@
         <listitem><para>
 	<indexterm><primary>drbdmeta</primary><secondary>get-gi</secondary></indexterm>
           Get-gi shows a short textual repesentation of the data generation
-	  identifier. In version 0.6 and 0.7 this are generation counters,
-	  while in version 0.8 this is a set of UUIDs.
+	  identifier. In version 0.6 and 0.7 these are generation counters,
+	  while in version 0.8 it is a set of UUIDs.
 	</para></listitem>
       </varlistentry>
       <varlistentry>
@@ -86,7 +86,7 @@
         <listitem><para>
 	<indexterm><primary>drbdmeta</primary><secondary>outdate</secondary></indexterm>
           Sets the outdated flag in the meta data. This is used by the
-	  peer node when it wants to become primary, but can not reach
+	  peer node when it wants to become primary, but cannot
 	  communicate with the DRBD stack on this host.
         </para></listitem>
       </varlistentry>
@@ -94,7 +94,7 @@
         <term>dstate</term>
         <listitem><para>
 	<indexterm><primary>drbdmeta</primary><secondary>dstate</secondary></indexterm>
-          Prints the state of the backing storag's data. The output
+          Prints the state of the data on the  backing storage. The output
 	  is always followed by '/DUnknown' since drbdmeta only looks
 	  at the local meta data.
         </para></listitem>
@@ -106,10 +106,10 @@
     <title>Expert's commands</title>
     <para>
       Drbdmeta allows you to modifiy the meta data as well. This is
-      intetionally omitted for the commad's usage output, since you
-      should only use this if you really know what you are doing.
-      By setting the generation identifiers to wrong values you
-      risk to overwrite your up-to-data data by an older version
+      intentionally omitted for the command's usage output, since you
+      should only use it if you really know what you are doing.
+      By setting the generation identifiers to wrong values, you
+      risk to overwrite your up-to-data data with an older version
       of your data.
     </para>
     <variablelist>
@@ -128,7 +128,7 @@
         <listitem><para>
 	<indexterm><primary>drbdmeta</primary><secondary>restore-md </secondary></indexterm>
           Reads the <replaceable>dump_file</replaceable> and writes
-	  the it to the meta data.
+	  it to the meta data.
 	</para></listitem>
       </varlistentry>
     </variablelist>

Modified: trunk/documentation/drbdsetup.sgml
===================================================================
--- trunk/documentation/drbdsetup.sgml	2007-05-04 20:56:17 UTC (rev 2869)
+++ trunk/documentation/drbdsetup.sgml	2007-05-06 20:02:07 UTC (rev 2870)
@@ -198,7 +198,7 @@
     <title>Note</title>
     <para>
       drbdsetup is a low level tool of the DRBD program suite. It is
-      used by the datadisk and drbd scripts to communicate with
+      used by the data disk and drbd scripts to communicate with
       the device driver.
     </para>
   </refsect1>
@@ -251,7 +251,7 @@
 	The <option>-d</option> (or <option>--disk-size</option>) should
 	only be used if you wish not to use as much as possible from the
 	backing block devices.
-	If you do not use <option>-d</option> the <replaceable>device</replaceable>
+	If you do not use <option>-d</option>, the <replaceable>device</replaceable>
 	is only ready for use as soon as it was connected to its peer once.
 	(See the <option>net</option> command.)
       </para>
@@ -278,9 +278,9 @@
 	      If the driver of the <replaceable>lower_device</replaceable>
 	      reports an error to DRBD, DRBD will either pass the error
 	      to the upper layers of the operating system, call a helper
-	      program, or detaches the device from its backing storage and
+	      program, or detach the device from its backing storage and
 	      perform all futher IO by requesting it from the peer. The
-	      valid <replaceable>err_handler</replaceable> are:
+	      valid <replaceable>err_handlers</replaceable> are:
 	      <option>pass_on</option>, <option>call-local-io-error</option>
 	      and <option>detach</option>.
 	    </para>
@@ -306,21 +306,21 @@
 		</para></listitem></varlistentry>
 	        <varlistentry><term><option>resource-only</option></term>
 		<listitem><para>
-		  If a node becomes a disconnected primary it tries to outdate
+		  If a node becomes a disconnected primary. it tries to outdate
 		  the peer's disk. This is done by calling the outdate-peer
 		  handler. The handler is supposed to reach the other node over
-		  alternative communication pathes and call 'drbdadm outdate
+		  alternative communication paths and call 'drbdadm outdate
 		  res' there.
 		</para></listitem></varlistentry>
 		<varlistentry><term><option>resource-and-stonith</option></term>
 		<listitem><para>
-		  If a node becomes a disconnected primary it freezes all
+		  If a node becomes a disconnected primary, it freezes all
 		  its IO operations and calls its outdate-peer handler. The
-		  outdate-peer hander is supposed to reach the peer over
-		  alternative communicaton pathes and call 'drbdadm outdate
-		  res' there. In case it can not reach the peer it should
+		  outdate-peer handler is supposed to reach the peer over
+		  alternative communicaton paths and call 'drbdadm outdate
+		  res' there. In case it cannot reach the peer, it should
 		  stonith the peer. IO is resumed as soon as the situation
-		  is resolved. In case your handler fails you can resume
+		  is resolved. In case your handler fails, you can resume
 		  IO with the <option>resume-io</option> command.
 		</para></listitem></varlistentry>
               </variablelist>
@@ -332,18 +332,19 @@
 	  <listitem>
 	    <para>
 	      In case the backing storage's driver has a merge_bvec_fn()
-	      function (At time of writing the only known drivers which
-	      have such a function are: md (software raid driver),
-	      dm (device mapper - LVM) and DRBD itself) drbd has to
+	      function,  DRBD has to
 	      pretend that it can only process IO requests in units
-	      not lager than 4kByte.</para>
+	      not lager than 4kByte. (At time of writing the only known 
+	      drivers which
+	      have such a function are: md (software raid driver),
+	      dm (device mapper - LVM) and DRBD itself)</para>
 	    <para>
 	      To get best performance out of DRBD on top of software
 	      raid (or any other driver with a merge_bvec_fn() function)
-	      you might enable this function, iff you know for sure
+	      you might enable this function, if you know for sure
 	      that the merge_bvec_fn() function will deliver the same
 	      results on all nodes of your cluster. I.e. the physical
-	      disks of the software raid are of the exact same type.
+	      disks of the software raid are exactly of the same type.
               USE THIS OPTION ONLY IF YOU KNOW WHAT YOU ARE DOING.</para>
 	  </listitem>
 	</varlistentry>
@@ -388,7 +389,7 @@
 	      If the TCP/IP connection linking a DRBD device pair is idle
 	      for more than <replaceable>time</replaceable> seconds, DRBD
 	      will generate a keep-alive packet to check if its partner is
-	      still alive. The default is 10 seconds, the unit is 1 second.
+	      still alive. The default value is 10 seconds, the unit is 1 second.
 	      </para>
 	  </listitem>
 	</varlistentry>
@@ -401,7 +402,7 @@
 	      within <replaceable>val</replaceable>
 	      10<superscript>ths</superscript> of a second, the partner node
 	      is considered dead and therefore the TCP/IP connection is
-	      abandoned. The default value is 60 = 6 seconds.
+	      abandoned. The default value is 60 (= 6 seconds).
 	    </para>
 	  </listitem>
 	</varlistentry>
@@ -418,7 +419,7 @@
 	      and secondary nodes. But keep in mind that more asynchronism
 	      is synonymous with more data loss in the case of a primary
 	      node failure. The default <replaceable>size</replaceable> is
-	      128 KB. Default unit is KB.
+	      128 KB, the default unit is KB.
 	    </para>
 	  </listitem>
 	</varlistentry>
@@ -442,8 +443,8 @@
 	    <para>
 	      With this option the maximal number of write requests between
 	      two barriers is limited. Should be set to the same as
-	      <option>--max-buffers </option>. Values smaller then 100 can
-	      lead to degraded performace. The default is 2048.
+	      <option>--max-buffers </option>. Values smaller than 100 can
+	      lead to degraded performance. The default value is 2048.
 	      </para>
 	  </listitem>
 	</varlistentry>
@@ -455,7 +456,7 @@
 	      With this option the maximal number of buffer pages allocated
 	      by DRBD's receiver thread is limited. Should be set to the
 	      same as <option>--max-epoch-size </option>. Small values
-	      could lead to degraded performace. (Minimum 32) The default is
+	      could lead to degraded performance. (Minimum 32) The default value is
 	      2048.
 	    </para>
 	  </listitem>
@@ -469,7 +470,7 @@
 	      (secondary) node exceeds the unplug-watermark, we trigger
 	      the request processing of our backing storage device.
 	      Some storage controllers deliver better performance with small
-	      values, other deliver best performance when it is set to
+	      values, others deliver best performance when the value is set to
 	      the same value as max-buffers. Minimum 16, default 128, maximum
 	      131072.
 	    </para>
@@ -480,11 +481,11 @@
 	  <option>--allow-two-primaries </option></term>
 	  <listitem>
 	    <para>
-	      With this option set you might make both nodes primary. You
-	      only should use this options if you use a shared storage
+	      With this option set you may assign primary role to both nodes. You
+	      only should use this option if you use a shared storage
 	      file system on top of DRBD. At the time of writing the only
 	      ones are: OCFS2 and GFS. If you use this option with any
-	      other filesystem you are goint to crash your nodes and to
+	      other file system, you are going to crash your nodes and to
 	      corrupt your data!
 	    </para>
 	  </listitem>
@@ -494,11 +495,11 @@
 	  <option>--cram-hmac-alg </option><replaceable>alg</replaceable></term>
 	  <listitem>
 	    <para>
-	      You need to specifying the HMAC algorithm to enable peer
-	      authentication at all. It is strongly enouraged to use
+	      You need to specify the HMAC algorithm to enable peer
+	      authentication at all. You are strongly enouraged to use
 	      peer authentication.
-	      The HMAC algorithm which will be used for the challenge
-	      response authentication of the peer. You might specify any
+	      The HMAC algorithm will be used for the challenge
+	      response authentication of the peer. You may specify any
 	      digest algorithm that is named in /proc/crypto.
 	    </para>
 	  </listitem>
@@ -527,13 +528,12 @@
 		</para></listitem></varlistentry>
 	        <varlistentry><term><option>discard-younger-primary</option></term>
 		<listitem><para>
-		  Auto sync from the node that was primary before the split
-		  brain situation happened.
+		  Auto sync from the node that was primary before the split-		brain situation occurred.
 		</para></listitem></varlistentry>
 		<varlistentry><term><option>discard-older-primary</option></term>
 		<listitem><para>
 		Auto sync from the node that became primary as second during
-		the split brain situation.
+		the split-brain situation.
 		</para></listitem></varlistentry>
 		<varlistentry><term><option>discard-zero-changes</option></term>
 		<listitem><para>
@@ -573,7 +573,7 @@
 	        <varlistentry><term><option>consensus</option></term>
 		<listitem><para>
 		  Discard the version of the secondary if the outcome
-                  if the <option>after-sb-0pri</option> algorithm would also
+                  of the <option>after-sb-0pri</option> algorithm would also
 		  destroy the current secondary's data. Otherwise disconnect.
 		</para></listitem></varlistentry>
 		<varlistentry><term><option>discard-secondary</option></term>
@@ -583,14 +583,14 @@
 		<varlistentry><term><option>call-pri-lost-after-sb</option></term>
 		<listitem><para>
 		  Always honour the outcome of the <option>after-sb-0pri
-		  </option> algorithm. In case it decides the the current
+		  </option> algorithm. In case it decides the current
 		  secondary has the right data, call the
 		  <option>pri-lost-after-sb</option> on the current primary.
 		</para></listitem></varlistentry>
 		<varlistentry><term><option>violently-as0p</option></term>
 		<listitem><para>
 		  Always honour the outcome of the <option>after-sb-0pri
-		  </option> algorithm. In case it decides the the current
+		  </option> algorithm. In case it decides the current
 		  secondary has the right data, accept a possible instantaneous
 		  change of the primary's data.
 		</para></listitem></varlistentry>
@@ -613,14 +613,14 @@
 		<varlistentry><term><option>call-pri-lost-after-sb</option></term>
 		<listitem><para>
 		  Always honour the outcome of the <option>after-sb-0pri
-		  </option> algorithm. In case it decides the the current
+		  </option> algorithm. In case it decides the current
 		  secondary has the right data, call the
 		  <option>pri-lost-after-sb</option> on the current primary.
 		</para></listitem></varlistentry>
 		<varlistentry><term><option>violently-as0p</option></term>
 		<listitem><para>
 		  Always honour the outcome of the <option>after-sb-0pri
-		  </option> algorithm. In case it decides the the current
+		  </option> algorithm. In case it decides the current
 		  secondary has the right data, accept a possible instantaneous
 		  change of the primary's data.
 		</para></listitem></varlistentry>
@@ -634,15 +634,15 @@
 	  <listitem>
 	    <para>
 	      Normally the automatic after-split-brain policies are only 
-	      used if current state of the UUIDs do not indicate the 
+	      used if current states of the UUIDs do not indicate the 
 	      presence of a third node.
 	    </para>
 	    <para>
 	      With this option you request that the automatic 
 	      after-split-brain policies are used as long as the data
 	      sets of the nodes are somehow related. This might cause
-	      a full sync, if the UUIDs indicates the presence of a third
-	      node. (Or double faults led to strange UUID sets.)
+	      a full sync, if the UUIDs indicate the presence of a third
+	      node. (Or double faults have led to strange UUID sets.)
 	    </para>
 	  </listitem>
 	</varlistentry>
@@ -659,16 +659,16 @@
 	      <option>call-pri-lost</option> and
 	      <option>violently</option>. While <option>disconnect</option>
 	      speaks for itself, with the <option>call-pri-lost</option>
-	      setting the <option>pri-lost</option> handler gets called
-	      witch is expeced to either change the role of the node to
+	      setting the <option>pri-lost</option> handler is called
+	      which is expected to either change the role of the node to
 	      secondary, or remove the node from the cluster.
 	      The default is <option>disconnect</option>.</para>
 	    <para>
 	      With the <option>violently</option> setting you allow DRBD
 	      to force a primary node into SyncTarget state. This means
-	      that with that action the data exposed by DRBD changes to
-	      the SyncSource's version of the data instantaneous.
-	      USE THIS ONLY IF YOU KNOW WHAT YOU ARE DOING.
+	      that with that action the data exposed by DRBD change to
+	      the SyncSource's version of the data instantaneously.
+	      USE THIS OPTION ONLY IF YOU KNOW WHAT YOU ARE DOING.
 	    </para>
 	  </listitem>
 	</varlistentry>
@@ -678,9 +678,8 @@
 	  <option>--ping-timeout </option><replaceable>ping_timeout</replaceable></term>
 	  <listitem>
 	    <para>
-	      The time the peer has time to answer to a keep-alive packet,
-	      it. In case the peer's reply is not received within this
-	      time period, it is considered as dead. The default is 500ms,
+	      The time the peer has to answer to a keep-alive packet. In case the peer's reply is not received within this
+	      time period, it is considered as dead. The default value is 500ms,
 	      the default unit is 100ms.
 	    </para>
 	  </listitem>
@@ -691,11 +690,10 @@
 	  <option>--discard-my-data </option></term>
 	  <listitem>
 	    <para>
-	      Use this option to manually recover from a split brain
-	      situation. In case you do not have any automatic after
-	      split brain policies selected, the nodes refuse to
+	      Use this option to manually recover from a split-brain
+	      situation. In case you do not have any automatic after-split-brain policies selected, the nodes refuse to
 	      connect. By passing this option you make a node to
-	      sync target immediatly after sucessfull connect.
+	      sync target immediately after sucessful connect.
 	    </para>
 	  </listitem>
 	</varlistentry>
@@ -706,7 +704,7 @@
       <title>syncer</title>
       <indexterm><primary>drbdsetup</primary><secondary>syncer</secondary></indexterm>
       <para>
-	Changes the synchronization daemon parameters of
+	Changes the synchronisation daemon parameters of
 	<replaceable>device</replaceable> at runtime.
       </para>
       <variablelist>
@@ -716,8 +714,8 @@
 	  <listitem>
 	    <para>
 	      To ensure smooth operation of the application on top of DRBD,
-	      it is possible to limit the bandwidth which may be used by
-	      background synchronizations. The default is 250 KB/sec, the
+	      it is possible to limit the bandwidth that  may be used by
+	      background synchronisation. The default is 250 KB/sec, the
 	      default unit is KB/sec.
 	    </para>
 	  </listitem>
@@ -729,7 +727,7 @@
 	    <para>
 	      Start resync on this device only if the device with
 	      <replaceable>minor</replaceable> is already in connected
-	      state. Other wise this device wait in SyncPause state.
+	      state. Otherwise this device waits in SyncPause state.
 	  </para>
 	  </listitem>
 	</varlistentry>
@@ -741,8 +739,8 @@
 	      DRBD automatically performs hot area detection. With this
 	      parameter you control how big the hot area (=active set) can
 	      get. Each extent marks 4M of the backing storage. In case a
-	      primary node leaves the cluster unexpectedly the areas covered
-	      by the active set must be resynced upon rejoin of the failed
+	      primary node leaves the cluster unexpectedly, the areas covered
+	      by the active set must be resynced upon rejoining of the failed
 	      node. The data structure is stored in the meta-data area,
 	      therefore each change of the active set is a write operation
 	      to the meta-data device. A higher number of extents gives
@@ -758,15 +756,15 @@
       <title>primary</title>
       <indexterm><primary>drbdsetup</primary><secondary>primary</secondary></indexterm>
       <para>
-	Sets the <replaceable>device</replaceable> into primary state, this
+	Sets the <replaceable>device</replaceable> into primary role. This
 	means that applications (e.g. a file system) may open the
 	<replaceable>device</replaceable> for read and write access. Data
-	written to the <replaceable>device</replaceable> in primary state is
-	mirrored to the device in secondary state.
+	written to the <replaceable>device</replaceable> in primary role are
+	mirrored to the device in secondary role.
       </para>
       <para>
 	It is not possible to set both devices of a connected DRBD device
-	pair to primary state.
+	pair to primary role.
       </para>
       <variablelist>
 	<varlistentry>
@@ -834,11 +832,11 @@
 	  <listitem>
 	    <para>
 	      This command will fail if the
-	      <replaceable>device</replaceable> can not communicate with its
+	      <replaceable>device</replaceable> cannot communicate with its
 	      partner for <replaceable>timeout</replaceable>
-	      seconds. If the peer was working before this node got
-	      rebootet, the wfc_timeout is used. If the peer was already
-	      down before this node got rebooted, the degr_wfc_timeout
+	      seconds. If the peer was working before this node was
+	      rebooted, the wfc_timeout is used. If the peer was already
+	      down before this node was rebooted, the degr_wfc_timeout
 	      is used.
 	      The default value for <replaceable>wfc_timeout</replaceable>
 	      is 0 which means to wait forever. The default for
@@ -853,7 +851,7 @@
       <indexterm><primary>drbdsetup</primary><secondary>wait_sync</secondary></indexterm>
       <para>
 	Returns as soon as the <replaceable>device</replaceable> leaves any
-	synchronization state and returns into connected state. The options
+	synchronisation into connected state. The options
 	are the same as with the <replaceable>wait_connect</replaceable>
 	command.
       </para>
@@ -865,7 +863,7 @@
 	Removes the information set by the <option>net</option> command
 	from the <replaceable>device</replaceable>. This means
 	that the <replaceable>device</replaceable> goes into unconnected
-	state and that it will no longer listen for incoming connections.
+	state and will no longer listen for incoming connections.
       </para>
     </refsect2>
     <refsect2>
@@ -899,7 +897,7 @@
       <title>cstate</title>
       <indexterm><primary>drbdsetup</primary><secondary>cstate</secondary></indexterm>
       <para>
-	Shows the current connection states of the
+	Shows the current connection state of the
 	<replaceable>device</replaceable>.
       </para>
     </refsect2>
@@ -907,7 +905,7 @@
       <title>dstate</title>
       <indexterm><primary>drbdsetup</primary><secondary>dstate</secondary></indexterm>
       <para>
-	Show the current state of the backing storeage devices. (local/peer)
+	Shows the current states of the backing storage devices. (local/peer)
       </para>
     </refsect2>
     <refsect2>
@@ -926,7 +924,7 @@
       <indexterm><primary>drbdsetup</primary><secondary>pause-sync</secondary></indexterm>
       <para>
         Temporarily suspend an ongoing resynchronisation by setting the local
-	pause flag. Resync only progresses if neighter the local nor the
+	pause flag. Resync only progresses if neither the local nor the
 	remote pause flag is set. It might be desirable to postpone DRBD's
 	resynchronisation after eventual resynchronisation of the backing
 	storage's RAID setup.
@@ -952,14 +950,14 @@
       <title>show-gi</title>
       <indexterm><primary>drbdsetup</primary><secondary>show-gi</secondary></indexterm>
       <para>
-        Displays the device's data generaion identifiers verbosily.
+        Displays the device's data generation identifiers verbosely.
       </para>
     </refsect2>
     <refsect2>
       <title>get-gi</title>
       <indexterm><primary>drbdsetup</primary><secondary>get-gi</secondary></indexterm>
       <para>
-        Displays the device's data generaion identifiers.
+        Displays the device's data generation identifiers.
       </para>
     </refsect2>
     <refsect2>
@@ -982,7 +980,7 @@
       <title>resume-io</title>
       <indexterm><primary>drbdsetup</primary><secondary>resume-io</secondary></indexterm>
       <para>
-	In the the outdate-peer handler fails to stonith the peer node,
+	If the outdate-peer handler fails to stonith the peer node,
 	and your <option>fencing</option> policy is set to
 	resource-and-stonith, you can unfreeze IO operations with this
 	command.
@@ -994,8 +992,8 @@
       <indexterm><primary>drbdsetup</primary><secondary>events</secondary></indexterm>
       <para>
       	Displays every state change of DRBD and all calls to helper
-	programs. This might be used to get notifies of DRBD's state
-	changes by piping the output to an other program.
+	programs. This might be used to get notified of DRBD's state
+	changes by piping the output to another program.
 
 	<variablelist>
 	  <varlistentry>
@@ -1013,7 +1011,7 @@
 	    <option>--unfiltered</option></term>
 	    <listitem>
 	      <para>
-		This is an debugging aid, and displays the content of
+		This is a debugging aid that displays the content of
 		all received netlink messages.
 	      </para>
 	    </listitem>
@@ -1026,7 +1024,7 @@
   <refsect1>
     <title>Examples</title>
       <para>
-      For examples please have a look at the
+      For examples, please have a look at the
       <ulink url="http://www.linux-ha.org/DRBD/QuickStart07">
       <citetitle>DRBD Quickstart Guide</citetitle></ulink>.
       </para>

From drbd-cvs at lists.linbit.com  Mon May  7 11:59:25 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon May  7 11:59:26 2007
Subject: [DRBD-cvs] svn commit by lars - r2871 - trunk/drbd - fix for a
	potential access-after-free in _drbd_send_zc_
Message-ID: <20070507095925.C05412DEACD5@mail.linbit.com>

Author: lars
Date: 2007-05-07 11:59:24 +0200 (Mon, 07 May 2007)
New Revision: 2871

Modified:
   trunk/drbd/drbd_req.c
   trunk/drbd/drbd_req.h
Log:
fix for a potential access-after-free in _drbd_send_zc_bio due to a race contition in _req_may_be_done

Modified: trunk/drbd/drbd_req.c
===================================================================
--- trunk/drbd/drbd_req.c	2007-05-06 20:02:07 UTC (rev 2870)
+++ trunk/drbd/drbd_req.c	2007-05-07 09:59:24 UTC (rev 2871)
@@ -33,6 +33,32 @@
 #include "drbd_int.h"
 #include "drbd_req.h"
 
+/* outside of the ifdef
+ * because of the _print_rq_state(,FIXME) in barrier_acked */
+void _print_rq_state(drbd_request_t *req, const char *txt)
+{
+	const unsigned long s = req->rq_state;
+	drbd_dev *mdev = req->mdev;
+	const int rw = (req->master_bio == NULL ||
+			bio_data_dir(req->master_bio) == WRITE) ?
+		'W' : 'R';
+
+	INFO("%s %p %c L%c%c%cN%c%c%c%c%c %u (%llus +%u) %s\n",
+	     txt, req, rw,
+	     s & RQ_LOCAL_PENDING ? 'p' : '-',
+	     s & RQ_LOCAL_COMPLETED ? 'c' : '-',
+	     s & RQ_LOCAL_OK ? 'o' : '-',
+	     s & RQ_NET_PENDING ? 'p' : '-',
+	     s & RQ_NET_QUEUED ? 'q' : '-',
+	     s & RQ_NET_SENT ? 's' : '-',
+	     s & RQ_NET_DONE ? 'd' : '-',
+	     s & RQ_NET_OK ? 'o' : '-',
+	     req->epoch,
+	     (unsigned long long)req->sector,
+	     req->size,
+	     conns_to_name(mdev->state.conn));
+}
+
 //#define VERBOSE_REQUEST_CODE
 #if defined(VERBOSE_REQUEST_CODE) || defined(ENABLE_DYNAMIC_TRACE)
 void _print_req_mod(drbd_request_t *req,drbd_req_event_t what)
@@ -66,30 +92,6 @@
 	INFO("_req_mod(%p %c ,%s)\n", req, rw, rq_event_names[what]);
 }
 
-void _print_rq_state(drbd_request_t *req, const char *txt)
-{
-	const unsigned long s = req->rq_state;
-	drbd_dev *mdev = req->mdev;
-	const int rw = (req->master_bio == NULL ||
-			bio_data_dir(req->master_bio) == WRITE) ?
-		'W' : 'R';
-
-	INFO("%s %p %c L%c%c%cN%c%c%c%c%c %u (%llus +%u) %s\n",
-	     txt, req, rw,
-	     s & RQ_LOCAL_PENDING ? 'p' : '-',
-	     s & RQ_LOCAL_COMPLETED ? 'c' : '-',
-	     s & RQ_LOCAL_OK ? 'o' : '-',
-	     s & RQ_NET_PENDING ? 'p' : '-',
-	     s & RQ_NET_QUEUED ? 'q' : '-',
-	     s & RQ_NET_SENT ? 's' : '-',
-	     s & RQ_NET_DONE ? 'd' : '-',
-	     s & RQ_NET_OK ? 'o' : '-',
-	     req->epoch,
-	     (unsigned long long)req->sector,
-	     req->size,
-	     conns_to_name(mdev->state.conn));
-}
-
 # ifdef ENABLE_DYNAMIC_TRACE
 #  define print_rq_state(R,T) MTRACE(TraceTypeRq,TraceLvlMetrics,_print_rq_state(R,T);)
 #  define print_req_mod(T,W)  MTRACE(TraceTypeRq,TraceLvlMetrics,_print_req_mod(T,W);)
@@ -255,6 +257,16 @@
 	print_rq_state(req, "_req_may_be_done");
 	MUST_HOLD(&mdev->req_lock)
 
+	/* we must not complete the master bio, while it is
+	 *	still being processed by _drbd_send_zc_bio (drbd_send_dblock)
+	 *	not yet acknowledged by the peer
+	 *	not yet completed by the local io subsystem
+	 * these flags may get cleared in any order by
+	 *	the worker,
+	 *	the receiver,
+	 *	the bio_endio completion callbacks.
+	 */
+	if (s & RQ_NET_QUEUED) return;
 	if (s & RQ_NET_PENDING) return;
 	if (s & RQ_LOCAL_PENDING) return;
 
@@ -662,9 +674,7 @@
 		D_ASSERT(req->rq_state & RQ_NET_PENDING);
 		dec_ap_pending(mdev);
 		req->rq_state &= ~RQ_NET_PENDING;
-		if (req->rq_state & RQ_NET_SENT)
-			_req_may_be_done(req,error);
-		/* else: done by handed_over_to_network */
+		_req_may_be_done(req,error);
 		break;
 
 	case neg_acked:
@@ -673,8 +683,7 @@
 		req->rq_state &= ~(RQ_NET_OK|RQ_NET_PENDING);
 		/* FIXME THINK! is it DONE now, or is it not? */
 		req->rq_state |= RQ_NET_DONE;
-		if (req->rq_state & RQ_NET_SENT)
-			_req_may_be_done(req,error);
+		_req_may_be_done(req,error);
 		/* else: done by handed_over_to_network */
 		break;
 
@@ -686,23 +695,7 @@
 			/* barrier came in before all requests have been acked.
 			 * this is bad, because if the connection is lost now,
 			 * we won't be able to clean them up... */
-			const unsigned long s = req->rq_state;
-			INFO("%s %p %c L%c%c%cN%c%c%c%c%c %u (%llus +%u) %s\n",
-			     "FIXME", req,
-			     /* in fact, it can only be a WRITE, but anyways */
-			     bio_data_dir(req->master_bio) == WRITE ? 'W' : 'R',
-			     s & RQ_LOCAL_PENDING ? 'p' : '-',
-			     s & RQ_LOCAL_COMPLETED ? 'c' : '-',
-			     s & RQ_LOCAL_OK ? 'o' : '-',
-			     s & RQ_NET_PENDING ? 'p' : '-',
-			     s & RQ_NET_QUEUED ? 'q' : '-',
-			     s & RQ_NET_SENT ? 's' : '-',
-			     s & RQ_NET_DONE ? 'd' : '-',
-			     s & RQ_NET_OK ? 'o' : '-',
-			     req->epoch,
-			     (unsigned long long)req->sector,
-			     req->size,
-			     conns_to_name(mdev->state.conn));
+			_print_rq_state(req, "FIXME (barrier_acked but pending)");
 		}
 		D_ASSERT(req->rq_state & RQ_NET_SENT);
 		req->rq_state |= RQ_NET_DONE;
@@ -714,11 +707,7 @@
 		dec_ap_pending(mdev);
 		req->rq_state &= ~RQ_NET_PENDING;
 		req->rq_state |= (RQ_NET_OK|RQ_NET_DONE);
-		/* can it happen that we receive the DataReply
-		 * before the send DataRequest function returns? */
-		if (req->rq_state & RQ_NET_SENT)
-			_req_may_be_done(req,error);
-		/* else: done by handed_over_to_network */
+		_req_may_be_done(req,error);
 		break;
 	};
 }

Modified: trunk/drbd/drbd_req.h
===================================================================
--- trunk/drbd/drbd_req.h	2007-05-06 20:02:07 UTC (rev 2870)
+++ trunk/drbd/drbd_req.h	2007-05-07 09:59:24 UTC (rev 2871)
@@ -165,10 +165,16 @@
 	 * no longer occur. */
 	__RQ_NET_QUEUED,
 
-	/* well, actually only "handed over to the network stack" */
+	/* well, actually only "handed over to the network stack".
+	 *
+	 * TODO can potentially be dropped because of the similar meaning
+	 * of RQ_NET_SENT and ~RQ_NET_QUEUED.
+	 * however it is not exactly the same. before we drop it
+	 * we must ensure that we can tell a request with network part
+	 * from a request without, regardless of what happens to it. */
 	__RQ_NET_SENT,
 
-	/* when set, the request may be freed.
+	/* when set, the request may be freed (if RQ_NET_QUEUED is clear).
 	 * in (C) this happens when WriteAck is received,
 	 * in (B,A) when the corresponding BarrierAck is received */
 	__RQ_NET_DONE,
@@ -180,6 +186,9 @@
 
 	/* peer called drbd_set_in_sync() for this write */
 	__RQ_NET_SIS,
+
+	/* keep this last, its for the RQ_NET_MASK */
+	__RQ_NET_MAX,
 };
 
 #define RQ_LOCAL_PENDING   (1UL << __RQ_LOCAL_PENDING)
@@ -195,7 +204,7 @@
 #define RQ_NET_OK          (1UL << __RQ_NET_OK)
 #define RQ_NET_SIS         (1UL << __RQ_NET_SIS)
 
-#define RQ_NET_MASK        (((RQ_NET_OK << 1)-1) & ~RQ_LOCAL_MASK) /* 0xf8 */
+#define RQ_NET_MASK        (((1UL << __RQ_NET_MAX)-1) & ~RQ_LOCAL_MASK) /* 0x1f8 */
 
 /* epoch entries */
 static inline struct hlist_head* ee_hash_slot(drbd_dev *mdev, sector_t sector)

From drbd-cvs at lists.linbit.com  Mon May  7 13:31:14 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon May  7 13:31:16 2007
Subject: [DRBD-cvs] svn commit by lars - r2872 - trunk/tools - merge back
	changes made in the linux-ha repository 
Message-ID: <20070507113114.841322E03721@mail.linbit.com>

Author: lars
Date: 2007-05-07 13:30:58 +0200 (Mon, 07 May 2007)
New Revision: 2872

Modified:
   trunk/tools/dopd.c
   trunk/tools/dopd.h
   trunk/tools/drbd-peer-outdater.c
Log:
merge back changes made in the linux-ha repository

Modified: trunk/tools/dopd.c
===================================================================
--- trunk/tools/dopd.c	2007-05-07 09:59:24 UTC (rev 2871)
+++ trunk/tools/dopd.c	2007-05-07 11:30:58 UTC (rev 2872)
@@ -1,4 +1,3 @@
-/* $Id$ */
 /* drbd outdate peer daemon
  * Copyright (C) 2006-2007 LINBIT <http://www.linbit.com/>
  * Written by Rasto Levrinc <rasto@linbit.com>
@@ -20,7 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <portability.h>
+#include <lha_internal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>

Modified: trunk/tools/dopd.h
===================================================================
--- trunk/tools/dopd.h	2007-05-07 09:59:24 UTC (rev 2871)
+++ trunk/tools/dopd.h	2007-05-07 11:30:58 UTC (rev 2872)
@@ -1,4 +1,3 @@
-/* $Id$ */
 /* drbd outdate peer daemon
  * Copyright (C) 2006-2007 LINBIT <http://www.linbit.com/>
  * Written by Rasto Levrinc <rasto@linbit.at>

Modified: trunk/tools/drbd-peer-outdater.c
===================================================================
--- trunk/tools/drbd-peer-outdater.c	2007-05-07 09:59:24 UTC (rev 2871)
+++ trunk/tools/drbd-peer-outdater.c	2007-05-07 11:30:58 UTC (rev 2872)
@@ -1,4 +1,3 @@
-/* $Id$ */
 /* drbd-peer-outdater
  * Copyright (C) 2006-2007 LINBIT <http://www.linbit.com/>
  * Written by Rasto Levrinc <rasto@linbit.com>
@@ -20,7 +19,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#include <portability.h>
+#include <lha_internal.h>
 
 #include <sys/param.h>
 
@@ -36,7 +35,7 @@
 #include <dopd.h>
 
 #define OPTARGS      "hVt:p:r:"
-#define DEFAULT_TIMEOUT 60 // timeout in seconds
+#define DEFAULT_TIMEOUT 60 /* timeout in seconds */
 
 typedef struct dop_client_s
 {
@@ -90,6 +89,7 @@
 	rc = strtol(rc_string, &ep, 10);
 	if (errno != 0 || *ep != EOS) {
 		fprintf(stderr, "unknown message: %s from server", rc_string);
+		client->rc = 20; /* "officially undefined", unspecified error */
 		ha_msg_del(msg);
 		if (client->mainloop != NULL &&
 		    g_main_is_running(client->mainloop))
@@ -99,8 +99,10 @@
 
 	ha_msg_del(msg);
 
+	/* ok, peer returned something useful */
+	client->rc = rc;
+
 	if (client->mainloop != NULL && g_main_is_running(client->mainloop)) {
-		client->rc = rc;
 		g_main_quit(client->mainloop);
 	} else
 		dop_exit(client);
@@ -193,7 +195,7 @@
 	crm_malloc0(new_client, sizeof(dop_client_t));
 	new_client->timeout = timeout;
 	new_client->mainloop = g_main_new(FALSE);
-	new_client->rc = 5;
+	new_client->rc = 5; /* default: down/unreachable */
 
 	/* Connect to the IPC server */
 	src = init_client_ipc_comms(T_OUTDATER, outdate_callback,
@@ -201,7 +203,7 @@
 
 	if (ipc_server == NULL) {
 		fprintf(stderr, "Could not connect to "T_OUTDATER" channel\n");
-		dop_exit(new_client); // unreachable
+		dop_exit(new_client); /* unreachable */
 	}
 
 	/* send message with drbd resource to dopd */
@@ -222,7 +224,7 @@
 
 	g_main_run(new_client->mainloop);
 	dop_exit(new_client);
-	return 5;
+	return 20; /* not reached */
 }
 
 static void

From drbd-cvs at lists.linbit.com  Mon May  7 14:43:54 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon May  7 14:43:56 2007
Subject: [DRBD-cvs] svn commit by phil - r2873 - in branches/drbd-0.7: .
	debian drbd/linux - Preparing 0.7.24 
Message-ID: <20070507124355.48E132DEACD5@mail.linbit.com>

Author: phil
Date: 2007-05-07 14:43:53 +0200 (Mon, 07 May 2007)
New Revision: 2873

Modified:
   branches/drbd-0.7/ChangeLog
   branches/drbd-0.7/debian/changelog
   branches/drbd-0.7/drbd/linux/drbd_config.h
Log:
Preparing 0.7.24


Modified: branches/drbd-0.7/ChangeLog
===================================================================
--- branches/drbd-0.7/ChangeLog	2007-05-07 11:30:58 UTC (rev 2872)
+++ branches/drbd-0.7/ChangeLog	2007-05-07 12:43:53 UTC (rev 2873)
@@ -6,6 +6,12 @@
  Cumulative changes since last tarball.
  For even more detail, use "svn log" and "svn diff".
 
+0.7.24 (api:79/proto:74)
+-----
+ * Fixed leakage of bios in case we are diskless.
+ * A fix to the device name guessing code.
+ * Made it to compile on 2.6.21 and gcc-4.1 without warnings.
+
 0.7.23 (api:79/proto:74)
 -----
  * Made it to compile on 2.6.19.

Modified: branches/drbd-0.7/debian/changelog
===================================================================
--- branches/drbd-0.7/debian/changelog	2007-05-07 11:30:58 UTC (rev 2872)
+++ branches/drbd-0.7/debian/changelog	2007-05-07 12:43:53 UTC (rev 2873)
@@ -1,3 +1,9 @@
+drbd (0.7.24-0) unstable; urgency=low
+
+  * New upstream release
+
+ -- Philipp Reisner <phil@linbit.com>  Mon,  7 May 2007 14:32:04 +0200
+
 drbd (0.7.23-0) unstable; urgency=low
 
   * New upstream release

Modified: branches/drbd-0.7/drbd/linux/drbd_config.h
===================================================================
--- branches/drbd-0.7/drbd/linux/drbd_config.h	2007-05-07 11:30:58 UTC (rev 2872)
+++ branches/drbd-0.7/drbd/linux/drbd_config.h	2007-05-07 12:43:53 UTC (rev 2873)
@@ -22,7 +22,7 @@
 
 extern const char * drbd_buildtag(void);
 
-#define REL_VERSION "0.7.23"
+#define REL_VERSION "0.7.24"
 #define API_VERSION 79
 #define PRO_VERSION 74
 

From drbd-cvs at lists.linbit.com  Mon May  7 14:46:05 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon May  7 14:46:06 2007
Subject: [DRBD-cvs] svn commit by phil - r2874 - tags - Tagging 0.7.24 
Message-ID: <20070507124605.D59782DEACD5@mail.linbit.com>

Author: phil
Date: 2007-05-07 14:46:04 +0200 (Mon, 07 May 2007)
New Revision: 2874

Added:
   tags/drbd-0.7.24/
Log:
Tagging 0.7.24


Copied: tags/drbd-0.7.24 (from rev 2873, branches/drbd-0.7)

From drbd-cvs at lists.linbit.com  Mon May  7 14:53:05 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon May  7 14:53:07 2007
Subject: [DRBD-cvs] svn commit by phil - r2875 - branches/drbd-0.7 - *
	Missing drbd.spec.in * Our shell code is intended to 
Message-ID: <20070507125305.A007C2DEACD5@mail.linbit.com>

Author: phil
Date: 2007-05-07 14:53:03 +0200 (Mon, 07 May 2007)
New Revision: 2875

Modified:
   branches/drbd-0.7/Makefile
   branches/drbd-0.7/drbd.spec.in
Log:
* Missing drbd.spec.in
* Our shell code is intended to be executed on bash, not dash.


Modified: branches/drbd-0.7/Makefile
===================================================================
--- branches/drbd-0.7/Makefile	2007-05-07 12:46:04 UTC (rev 2874)
+++ branches/drbd-0.7/Makefile	2007-05-07 12:53:03 UTC (rev 2875)
@@ -20,6 +20,10 @@
 # TODO move some of the more cryptic bash scriptlets here into scripts/*
 # and call those from here.	-- lge 
 
+# for some reason some of the commands below only work correctly in bash,
+# and not in e.g. dash. I'm too lazy to fix it to be compatible.
+SHELL=/bin/bash
+
 #PREFIX      = /usr/local
 
 SUBDIRS     = user scripts documentation drbd #testing #benchmark

Modified: branches/drbd-0.7/drbd.spec.in
===================================================================
--- branches/drbd-0.7/drbd.spec.in	2007-05-07 12:46:04 UTC (rev 2874)
+++ branches/drbd-0.7/drbd.spec.in	2007-05-07 12:53:03 UTC (rev 2875)
@@ -188,6 +188,12 @@
 /sbin/depmod -a -F /boot/System.map-%{kernelversion} %{kernelversion} >/dev/null 2>&1 || true
 
 %changelog
+* Mon May  7 2007 14:32:04 +0200 Philipp Reisner <phil@linbit.com>
+- drbd (0.7.24-1)
+ * Fixed leakage of bios in case we are diskless.
+ * A fix to the device name guessing code.
+ * Made it to compile on 2.6.21 and gcc-4.1 without warnings.
+
 * Fri Jan 12 2007 13:21:28 +0200 Philipp Reisner <phil@linbit.com>
 - drbd (0.7.23-1)
  * Made it to compile on 2.6.19.

From drbd-cvs at lists.linbit.com  Mon May  7 14:54:06 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon May  7 14:54:08 2007
Subject: [DRBD-cvs] svn commit by phil - r2876 - tags - net yet. 
Message-ID: <20070507125406.A3E192DEACD5@mail.linbit.com>

Author: phil
Date: 2007-05-07 14:54:06 +0200 (Mon, 07 May 2007)
New Revision: 2876

Removed:
   tags/drbd-0.7.24/
Log:
net yet.


From drbd-cvs at lists.linbit.com  Mon May  7 14:54:22 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon May  7 14:54:24 2007
Subject: [DRBD-cvs] svn commit by phil - r2877 - tags - Tagging 0.7.24 
Message-ID: <20070507125423.04AAC2E03721@mail.linbit.com>

Author: phil
Date: 2007-05-07 14:54:22 +0200 (Mon, 07 May 2007)
New Revision: 2877

Added:
   tags/drbd-0.7.24/
Log:
Tagging 0.7.24


Copied: tags/drbd-0.7.24 (from rev 2876, branches/drbd-0.7)

From drbd-cvs at lists.linbit.com  Mon May  7 17:12:51 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon May  7 17:12:53 2007
Subject: [DRBD-cvs] svn commit by phil - r2878 - in trunk: . debian
	drbd/linux - Preparing 8.0.3 release 
Message-ID: <20070507151251.C162F2DEACD5@mail.linbit.com>

Author: phil
Date: 2007-05-07 17:12:50 +0200 (Mon, 07 May 2007)
New Revision: 2878

Modified:
   trunk/ChangeLog
   trunk/debian/changelog
   trunk/drbd.spec.in
   trunk/drbd/linux/drbd_config.h
Log:
Preparing 8.0.3 release


Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2007-05-07 12:54:22 UTC (rev 2877)
+++ trunk/ChangeLog	2007-05-07 15:12:50 UTC (rev 2878)
@@ -4,6 +4,16 @@
  Cumulative changes since last tarball.
  For even more detail, use "svn log" and "svn diff".
 
+8.0.3 (api:86/proto:86)
+--------
+ * Fixed a race condition that could cause us to continue to traverse a bio
+   after it was freed. (led to an OOPS)
+ * Fixed a race condition that could cause us to use members of an ee, after
+   it was freed. (led to various weirdness)
+ * Language fixes for the man pages.
+ * The drbdsetup commands (events, wait-connect,...) release the lock now.
+ * Minor fixes and updates to the user land tools and to the peer outdater.
+
 8.0.2 (api:86/proto:86)
 --------
  * Removed a bug that could cause an OOPS in drbd_al_to_on_disk_bm()

Modified: trunk/debian/changelog
===================================================================
--- trunk/debian/changelog	2007-05-07 12:54:22 UTC (rev 2877)
+++ trunk/debian/changelog	2007-05-07 15:12:50 UTC (rev 2878)
@@ -1,3 +1,9 @@
+drbd8 (8.0.3-0) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Philipp Reisner <phil@linbit.com>  Fri, 7 May 2007 17:10:14 +0200
+
 drbd8 (8.0.2-0) unstable; urgency=low
 
   * New upstream release.

Modified: trunk/drbd/linux/drbd_config.h
===================================================================
--- trunk/drbd/linux/drbd_config.h	2007-05-07 12:54:22 UTC (rev 2877)
+++ trunk/drbd/linux/drbd_config.h	2007-05-07 15:12:50 UTC (rev 2878)
@@ -22,7 +22,7 @@
 
 extern const char * drbd_buildtag(void);
 
-#define REL_VERSION "8.0.2"
+#define REL_VERSION "8.0.3"
 #define API_VERSION 86
 #define PRO_VERSION 86
 

Modified: trunk/drbd.spec.in
===================================================================
--- trunk/drbd.spec.in	2007-05-07 12:54:22 UTC (rev 2877)
+++ trunk/drbd.spec.in	2007-05-07 15:12:50 UTC (rev 2878)
@@ -191,6 +191,16 @@
 /sbin/depmod -a -F /boot/System.map-%{kernelversion} %{kernelversion} >/dev/null 2>&1 || true
 
 %changelog
+* Mon May 7 2007 17:10:14 +0200 Philipp Reisner <phil@linbit.com>
+- drbd (8.0.3-1)
+ * Fixed a race condition that could cause us to continue to traverse a bio
+   after it was freed. (led to an OOPS)
+ * Fixed a race condition that could cause us to use members of an ee, after
+   it was freed. (led to various weirdness)
+ * Language fixes for the man pages.
+ * The drbdsetup commands (events, wait-connect,...) release the lock now.
+ * Minor fixes and updates to the user land tools and to the peer outdater.
+
 * Fri Apr 6 2007 21:32:39 +0200 Philipp Reisner <phil@linbit.com>
 - drbd (8.0.2-1)
  * Removed a bug that could cause an OOPS in drbd_al_to_on_disk_bm()

From drbd-cvs at lists.linbit.com  Mon May  7 17:17:48 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon May  7 17:17:50 2007
Subject: [DRBD-cvs] svn commit by phil - r2879 - tags - tagging 8.0.3 
Message-ID: <20070507151748.4C06E2DEACD5@mail.linbit.com>

Author: phil
Date: 2007-05-07 17:17:47 +0200 (Mon, 07 May 2007)
New Revision: 2879

Added:
   tags/drbd-8.0.3/
Log:
tagging 8.0.3


Copied: tags/drbd-8.0.3 (from rev 2878, trunk)

From drbd-cvs at lists.linbit.com  Mon May  7 17:21:04 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon May  7 17:21:05 2007
Subject: [DRBD-cvs] svn commit by phil - r2880 - tags - dash... 
Message-ID: <20070507152104.D3D7A2DEACD5@mail.linbit.com>

Author: phil
Date: 2007-05-07 17:21:04 +0200 (Mon, 07 May 2007)
New Revision: 2880

Removed:
   tags/drbd-8.0.3/
Log:
dash...



From drbd-cvs at lists.linbit.com  Mon May  7 17:21:34 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon May  7 17:21:36 2007
Subject: [DRBD-cvs] svn commit by phil - r2881 - trunk - Make everything
	work on ubunty-feisty 
Message-ID: <20070507152134.CAA542DEACD5@mail.linbit.com>

Author: phil
Date: 2007-05-07 17:21:34 +0200 (Mon, 07 May 2007)
New Revision: 2881

Modified:
   trunk/Makefile
Log:
Make everything work on ubunty-feisty


Modified: trunk/Makefile
===================================================================
--- trunk/Makefile	2007-05-07 15:21:04 UTC (rev 2880)
+++ trunk/Makefile	2007-05-07 15:21:34 UTC (rev 2881)
@@ -24,6 +24,10 @@
 # TODO move some of the more cryptic bash scriptlets here into scripts/*
 # and call those from here.	-- lge
 
+# for some reason some of the commands below only work correctly in bash,
+# and not in e.g. dash. I'm too lazy to fix it to be compatible.
+SHELL=/bin/bash
+
 #PREFIX      = /usr/local
 
 SUBDIRS     = user scripts documentation drbd #testing #benchmark

From drbd-cvs at lists.linbit.com  Mon May  7 17:21:51 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon May  7 17:21:53 2007
Subject: [DRBD-cvs] svn commit by phil - r2882 - tags - 2nd try to tag 8.0.3
Message-ID: <20070507152152.10F1D2DEACD5@mail.linbit.com>

Author: phil
Date: 2007-05-07 17:21:51 +0200 (Mon, 07 May 2007)
New Revision: 2882

Added:
   tags/drbd-8.0.3/
Log:
2nd try to tag 8.0.3


Copied: tags/drbd-8.0.3 (from rev 2881, trunk)

From drbd-cvs at lists.linbit.com  Tue May  8 11:10:49 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue May  8 11:10:50 2007
Subject: [DRBD-cvs] svn commit by lars - r2883 - in branches/drbd-0.7/drbd:
	. linux - we forgot about our kernel 2.4 compatibility :( 
Message-ID: <20070508091049.828DE2E0376A@mail.linbit.com>

Author: lars
Date: 2007-05-08 11:10:48 +0200 (Tue, 08 May 2007)
New Revision: 2883

Modified:
   branches/drbd-0.7/drbd/drbd_req.c
   branches/drbd-0.7/drbd/linux/drbd_config.h
Log:
we forgot about our kernel 2.4 compatibility :(

Modified: branches/drbd-0.7/drbd/drbd_req.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_req.c	2007-05-07 15:21:51 UTC (rev 2882)
+++ branches/drbd-0.7/drbd/drbd_req.c	2007-05-08 09:10:48 UTC (rev 2883)
@@ -269,10 +269,12 @@
 		    (volatile int) mdev->cstate > WFBitMapT);
 
 	local = inc_local(mdev);
+	ONLY_IN_26(
 	if (!local) {
 		bio_put(req->private_bio); /* or we get a bio leak */
 		req->private_bio = NULL;
 	}
+	)
 	NOT_IN_26( if (rw == READA) rw=READ );
 	if (rw == READ || rw == READA) {
 		if (local) {
@@ -298,8 +300,10 @@
 				 * local io stack.
 				 */
 				local = 0;
+				ONLY_IN_26(
 				bio_put(req->private_bio);
 				req->private_bio = NULL;
+				)
 				dec_local(mdev);
 			}
 		}

Modified: branches/drbd-0.7/drbd/linux/drbd_config.h
===================================================================
--- branches/drbd-0.7/drbd/linux/drbd_config.h	2007-05-07 15:21:51 UTC (rev 2882)
+++ branches/drbd-0.7/drbd/linux/drbd_config.h	2007-05-08 09:10:48 UTC (rev 2883)
@@ -69,7 +69,7 @@
 // but more recent kernels define it in arch/um/include/mem.h
 #define HAVE_UML_TO_VIRT
 
-//#define NO_MORE_DEV_FS
+#define NO_MORE_DEV_FS
 
 // 2.6.something has deprecated kmem_cache_t
 // some older still use it.

From drbd-cvs at lists.linbit.com  Thu May 10 14:54:51 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Thu May 10 14:54:52 2007
Subject: [DRBD-cvs] svn commit by lars - r2884 - trunk/drbd - (untested) fix
	for null pointer dereference in drbd_al_
Message-ID: <20070510125451.61DA02E03744@mail.linbit.com>

Author: lars
Date: 2007-05-10 14:54:50 +0200 (Thu, 10 May 2007)
New Revision: 2884

Modified:
   trunk/drbd/drbd_actlog.c
Log:
(untested) fix for null pointer dereference in drbd_al_to_on_disk_bm

Modified: trunk/drbd/drbd_actlog.c
===================================================================
--- trunk/drbd/drbd_actlog.c	2007-05-08 09:10:48 UTC (rev 2883)
+++ trunk/drbd/drbd_actlog.c	2007-05-10 12:54:50 UTC (rev 2884)
@@ -515,31 +515,6 @@
 	return 1;
 }
 
-void drbd_al_to_on_disk_bm_slow(struct Drbd_Conf *mdev)
-{
-	int i;
-	unsigned int enr;
-
-	WARN("Using the slow drbd_al_to_on_disk_bm()\n");
-
-	wait_event(mdev->al_wait, lc_try_lock(mdev->act_log));
-
-	if (inc_local_if_state(mdev,Attaching)) {
-		for(i=0;i<mdev->act_log->nr_elements;i++) {
-			enr = lc_entry(mdev->act_log,i)->lc_number;
-			if(enr == LC_FREE) continue;
-			/* Really slow: if we have al-extents 16..19 active,
-			 * sector 4 will be written four times! Synchronous! */
-			drbd_bm_write_sect(mdev, enr/AL_EXT_PER_BM_SECT );
-		}
-
-		dec_local(mdev);
-	} else D_ASSERT(0);
-
-	lc_unlock(mdev->act_log);
-	wake_up(&mdev->al_wait);
-}
-
 struct drbd_atodb_wait {
 	atomic_t           count;
 	struct completion  io_done;
@@ -618,7 +593,7 @@
 
 	if(bio_add_page(bio, *page, MD_HARDSECT, *page_offset)!=MD_HARDSECT) {
 		/* no memory leak, page gets cleaned up by caller */
-		return -EIO;
+		return -EINVAL;
 	}
 
 	if(!allocated_page) get_page(*page);
@@ -631,9 +606,8 @@
 	atomic_inc(&wc->count);
 	/* we already know that we may do this...
 	 * inc_local_if_state(mdev,Attaching);
-	 * so just get the extra reference, so that the local_cnt 
-	 * reflects the number of pending IO requests DRBD at its
-	 * backing device.
+	 * just get the extra reference, so that the local_cnt reflects
+	 * the number of pending IO requests DRBD at its backing device.
 	 */
 	atomic_inc(&mdev->local_cnt);
 	return 0;
@@ -654,74 +628,65 @@
 	unsigned int page_offset=PAGE_SIZE;
 	struct drbd_atodb_wait wc;
 
+	ERR_IF (!inc_local_if_state(mdev,Attaching))
+		return; /* sorry, I don't have any act_log etc... */
+
 	wait_event(mdev->al_wait, lc_try_lock(mdev->act_log));
 
 	nr_elements = mdev->act_log->nr_elements;
 
 	bios = kzalloc(sizeof(struct bio*) * nr_elements, GFP_KERNEL);
+	if(!bios) goto submit_one_by_one;
 
-	if(!bios) {
-		lc_unlock(mdev->act_log);
+	atomic_set(&wc.count,0);
+	init_completion(&wc.io_done);
+	wc.mdev = mdev;
+	wc.error = 0;
 
-		drbd_al_to_on_disk_bm_slow(mdev);
-		return;
+	for(i=0;i<nr_elements;i++) {
+		enr = lc_entry(mdev->act_log,i)->lc_number;
+		if(enr == LC_FREE) continue;
+		/* next statement also does atomic_inc wc.count */
+		if(atodb_prepare_unless_covered(mdev,bios,&page,
+						&page_offset,
+						enr/AL_EXT_PER_BM_SECT,
+						&wc))
+			goto free_bios_submit_one_by_one;
 	}
 
-	if (inc_local_if_state(mdev,Attaching)) {
-		atomic_set(&wc.count,0);
-		init_completion(&wc.io_done);
-		wc.mdev = mdev;
-		wc.error = 0;
+	/* unneccessary optimization? */
+	lc_unlock(mdev->act_log);
+	wake_up(&mdev->al_wait);
 
-		for(i=0;i<nr_elements;i++) {
-			enr = lc_entry(mdev->act_log,i)->lc_number;
-			if(enr == LC_FREE) continue;
-			/* next statement also does atomic_inc wc.count */
-			if(atodb_prepare_unless_covered(mdev,bios,&page,
-							&page_offset,
-							enr/AL_EXT_PER_BM_SECT,
-							&wc))
-				goto abort;
+	/* all prepared, submit them */
+	for(i=0;i<nr_elements;i++) {
+		if (bios[i]==NULL) break;
+		if (FAULT_ACTIVE( mdev, DRBD_FAULT_MD_WR )) {
+			bios[i]->bi_rw = WRITE;
+			bio_endio(bios[i],bios[i]->bi_size,-EIO);
+		} else {
+			submit_bio(WRITE, bios[i]);
 		}
 
-		lc_unlock(mdev->act_log);
-		wake_up(&mdev->al_wait);
+	}
 
-		/* all prepared, submit them */
-		for(i=0;i<nr_elements;i++) {
-			if (bios[i]==NULL) break;
-			if (FAULT_ACTIVE( mdev, DRBD_FAULT_MD_WR )) {
-				bios[i]->bi_rw = WRITE;
-				bio_endio(bios[i],bios[i]->bi_size,-EIO);
-			} else {
-				submit_bio(WRITE, bios[i]);
-			}
+	drbd_blk_run_queue(bdev_get_queue(mdev->bc->md_bdev));
 
-		}
+	// In case we did not submit a single IO do not wait for
+	// them to complete. ( Because we would wait forever here. )
+	//
+	// In case we had IOs and they are already complete, there
+	// is not point in waiting anyways.
+	// Therefore this if() ...
+	if(atomic_read(&wc.count)) wait_for_completion(&wc.io_done);
 
-		drbd_blk_run_queue(bdev_get_queue(mdev->bc->md_bdev));
+	dec_local(mdev);
 
-		// In case we did not submit a single IO do not wait for
-		// them to complete. ( Because we would wait forever here. )
-		//
-		// In case we had IOs and they are already complete, there
-		// is not point in waiting anyways.
-		// Therefore this if() ...
-		if(atomic_read(&wc.count)) wait_for_completion(&wc.io_done);
-
-		dec_local(mdev);
-
-		if(wc.error) drbd_io_error(mdev, TRUE);
-
-	} else D_ASSERT(0);
-
+	if(wc.error) drbd_io_error(mdev, TRUE);
 	kfree(bios);
 	return;
 
- abort:
-	lc_unlock(mdev->act_log);
-	wake_up(&mdev->al_wait);
-
+ free_bios_submit_one_by_one:
 	// free everything by calling the endio callback directly.
 	for(i=0;i<nr_elements;i++) {
 		if(bios[i]==NULL) break;
@@ -729,9 +694,21 @@
 		atodb_endio(bios[i], MD_HARDSECT, 0);
 	}
 	kfree(bios);
-	dec_local(mdev);
 
-	drbd_al_to_on_disk_bm_slow(mdev); //.. and take the slow path.
+ submit_one_by_one:
+	WARN("Using the slow drbd_al_to_on_disk_bm()\n");
+
+	for(i=0;i<mdev->act_log->nr_elements;i++) {
+		enr = lc_entry(mdev->act_log,i)->lc_number;
+		if(enr == LC_FREE) continue;
+		/* Really slow: if we have al-extents 16..19 active,
+		 * sector 4 will be written four times! Synchronous! */
+		drbd_bm_write_sect(mdev, enr/AL_EXT_PER_BM_SECT );
+	}
+
+	lc_unlock(mdev->act_log);
+	wake_up(&mdev->al_wait);
+	dec_local(mdev);
 }
 
 /**

From drbd-cvs at lists.linbit.com  Thu May 10 17:04:28 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Thu May 10 17:04:30 2007
Subject: [DRBD-cvs] svn commit by phil - r2889 - trunk/benchmark - dm is now
	also able to transport data with a specified 
Message-ID: <20070510150428.AC9752DEAC7A@mail.linbit.com>

Author: phil
Date: 2007-05-10 17:04:27 +0200 (Thu, 10 May 2007)
New Revision: 2889

Modified:
   trunk/benchmark/dm.c
Log:
dm is now also able to transport data with a specified bandwidth.


Modified: trunk/benchmark/dm.c
===================================================================
--- trunk/benchmark/dm.c	2007-05-10 14:59:25 UTC (rev 2888)
+++ trunk/benchmark/dm.c	2007-05-10 15:04:27 UTC (rev 2889)
@@ -33,6 +33,7 @@
 #include <getopt.h>
 #include <string.h>
 #include <errno.h>
+#include <poll.h>
 
 #define min(a,b) ( (a) < (b) ? (a) : (b) )
 
@@ -101,6 +102,7 @@
 		"   --o_direct          -x\n"
 		"     should be given first to affect\n"
 	        "     -i/-o given later on the command line\n"
+		"   --bandwidth         -w val byte/second \n"
 		"   --sync              -y\n"
 		"   --progress          -m\n"
 		"   --performance       -p\n"
@@ -119,6 +121,7 @@
 	unsigned long long size = -1, rsize;
 	int in_fd = 0, out_fd = 1;
 	unsigned long buffer_size = 65536;
+	unsigned long long target_bw = 0;
 	int o_direct = 0;
 	int do_sync = 0;
 	int show_progress = 0;
@@ -139,12 +142,13 @@
 		{"seek-output", required_argument, 0, 'l'},
 		{"size", required_argument, 0, 's'},
 		{"o_direct", no_argument, 0, 'x'},
+		{"bandwidth", required_argument, 0, 'w'},
 		{"sync", no_argument, 0, 'y'},
 		{"progress", no_argument, 0, 'm'},
 		{"performance", no_argument, 0, 'p'},
 		{"dialog", no_argument, 0, 'd'},
 		{"help", no_argument, 0, 'h'},
-		{"show-input-size", no_argument, 0, 'w'},
+		{"show-input-size", no_argument, 0, 'z'},
 		{0, 0, 0, 0}
 	};
 
@@ -152,7 +156,7 @@
 		usage(argv[0]);
 
 	while (1) {
-		c = getopt_long(argc, argv, "i:o:b:k:l:s:xympha:dw", options, 0);
+		c = getopt_long(argc, argv, "i:o:b:k:l:s:w:xympha:dz", options, 0);
 		if (c == -1)
 			break;
 		switch (c) {
@@ -210,9 +214,13 @@
 		case 'd':
 			dialog = 1;
 			break;
-		case 'w':
+		case 'z':
 			show_input_size = 1;
 			break;
+		case 'w':
+			target_bw = m_strtol(optarg);
+			break;
+
 		}
 	}
 
@@ -310,6 +318,35 @@
 				last_percentage = new_percentage;
 			}
 		}
+
+		if (target_bw) {
+			gettimeofday(&tv2, NULL);
+
+			long sec = tv2.tv_sec - tv1.tv_sec;
+			long usec = tv2.tv_usec - tv1.tv_usec;
+			double bps;
+			double time_should;
+			int time_wait;
+
+			if (usec < 0) {
+				sec--;
+				usec += 1000000;
+			}
+
+			bps = ((double)(size - rsize)) /
+				(sec + ((double)usec) / 1000000);
+
+			if ( bps > target_bw ) {
+				time_should = ((double)(size - rsize)) *
+					1000 / target_bw; // mili seconds.
+
+				time_wait = (int)
+					(time_should - 
+					 (sec*1000 + ((double)usec) / 1000));
+				poll(NULL,0,time_wait);
+			}
+		}
+
 		if (ww != rr)
 			break;
 	}

From drbd-cvs at lists.linbit.com  Fri May 18 09:27:20 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri May 18 09:27:22 2007
Subject: [DRBD-cvs] svn commit by phil - r2897 - branches - This is the 8.0
	branch, trunk shall be 8.1 from now on.
Message-ID: <20070518072720.3676C2E08420@mail.linbit.com>

Author: phil
Date: 2007-05-18 09:27:19 +0200 (Fri, 18 May 2007)
New Revision: 2897

Added:
   branches/drbd-8.0/
Log:
This is the 8.0 branch, trunk shall be 8.1 from now on...


Copied: branches/drbd-8.0 (from rev 2896, trunk)

From drbd-cvs at lists.linbit.com  Fri May 18 09:59:55 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri May 18 09:59:59 2007
Subject: [DRBD-cvs] svn commit by phil - r2898 - trunk - Started the 8.1
	roadmap. 
Message-ID: <20070518075955.722D22E08420@mail.linbit.com>

Author: phil
Date: 2007-05-18 09:59:54 +0200 (Fri, 18 May 2007)
New Revision: 2898

Modified:
   trunk/ROADMAP
Log:
Started the 8.1 roadmap.


Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2007-05-18 07:27:19 UTC (rev 2897)
+++ trunk/ROADMAP	2007-05-18 07:59:54 UTC (rev 2898)
@@ -1,613 +1,27 @@
-DRBD 0.8 Roadmap
+DRBD 8.1 Roadmap
 ----------------
 
-1 Drop support for linux-2.4.x.
-  Do all size calculations on the base of sectors (512 Byte) as it
-  is common in Linux-2.6.x.
-  (Currently they are done on a 1k base, for 2.4.x compatibility)
-  90% DONE
+New items for 8.1:
+==================
 
-2 Drop the Drbd_Parameter_Packet.
-  Replace the Drbd_Parameter_Packet by 4 small packets:
-  Protocol, GenCnt, Sizes and State.
-  The receiving code of these small packets is sane, compared
-  to that huge receive_params() function we had before.
-  40% DONE
+8.1 will be wire protocol compatible to 8.0. The netlink protocol should
+be compatlibe to 8.0.
 
-3 Authenticate the peer upon connect by using a shared secret.
-  Configuration file syntax:  net { cram-hmac-alg "sha1";
-  shared-secret "secret-word"; }
-  Using a challenge-response authentication.
-  99% DONE
+1  Integrate the "many devices patch".
 
-4 Consolidate state changes into a central function, that makes
-  sure that the new state is valid. Replace set_cstate() with
-  a force_state() and a request_state() function. Make all
-  state changes atomic, and consolidate the many differenct
-  cstate-error states into a single "NetworkFailure" state.
-  50% DONE
+2  New drbdmeta rewrite
 
-5 Three configuration options, to allow more fine grained definition
-  of DRBDs behaviour after a split-brain situation:
+3  page cache preloading on the secondary
 
-  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.
+4  DRBD's own data checksums. This is to identify broken NICs (drivers)
+   with broken TSO engines during a clusters test phase. For production
+   this should be turned off of course.
 
-  In case both nodes are secondary you can control DRBD's
-  auto recovery strategy by the "after-sb-0pri" options. The
-  default is to disconnect.
-     "disconnect" ... No automatic resynchronisation, simply disconnect.
-     "discard-younger-primary"
-                      Auto sync from the node that was primary before
-                      the split brain situation happened.
-     "discard-older-primary"
-                      Auto sync from the node that became primary
-                      as second during the split brain situation.
-                      If discard-younger-primary and discard-older-primary
-		      can not find a decissions, they fall back to
-                      discard-least-changes.
-     "discard-zero-changes"
-                      Auto sync from the node that modified
-                      blocks during the split brain situation, but only
-		      if the target not did not touched a single block.
-                      If both nodes touched their data, this policy
-		      falls back to disconnect.
-     "discard-least-changes"
-                      Auto sync from the node that touched more
-                      blocks during the split brain situation.
-     "discard-node-NODENAME"
-                      Auto sync _to_ the named node.
 
-  In one of the nodes is already primary, then the auto-recovery
-  strategie is controled by the "after-sb-1pri" options.
-     "disconnect" ... always disconnect
-     "consensus"  ... discard the version of the secondary if the outcome
-                      of the "after-sb-0pri" algorithm would also destroy
-                      the current secondary's data. Otherwise disconnect.
-     "violently-as0p" Always take the decission of the "after-sb-0pri"
-                      algorithm. Even if that causes case an erratic change
-		      of the primarie's view of the data.
-	              This is only usefull if you use an 1node FS (i.e.
-		      not OCFS2 or GFS) with the allow-two-primaries
-		      flag, _AND_ you really know what you are doing.
-		      This is DANGEROUS and MAY CRASH YOUR MACHINE if you
-		      have a FS mounted on the primary node.
-     "discard-secondary"
-                      discard the version of the secondary.
-     "call-pri-lost-after-sb"
-                      Always honour the outcome of the "after-sb-2sc"
-                      algorithm. In case it decides that the current
-                      secondary has the right data, it tries to make
-                      the current primary secondary, if that fails
-                      it calls the "pri-lost-after-sb" helper program
-                      on the current primary. That helper program is
-                      expected to halt the machine.
+Open Items from 8.0 (I am not shure if it makes sense to address this at all):
+===================
 
-  In case both nodes are primary you control DRBD's strategy by
-  the "after-sb-2pri" option.
-     "disconnect" ... Go to StandAlone mode on both sides.
-     "violently-as0p" Always take the decission of the "after-sb-0pri"
-                      algorithm. Even if that causes case an erratic change
-		      of the primarie's view of the data.
-	              This is only usefull if you use an 1node FS (i.e.
-		      not OCFS2 or GFS) with the allow-two-primaries
-		      flag, _AND_ you really know what you are doing.
-		      This is DANGEROUS and MAY CRASH YOUR MACHINE if you
-		      have a FS mounted on the primary node.
-     "call-pri-lost-after-sb"
-	              Honor the outcome of the "after-sb-0pri" algorithm
-                      and calls the "pri-lost-after-sb" program on the
-		      other node. That helper program is expected to
-                      halt the machine.
-
-  Defaults:
-  after-sb-0pri = disconnect;
-  after-sb-1pri = disconnect;
-  after-sb-2pri = disconnect;
-
-  DRBD-07 was:
-  after-sb-0pri = discard-younger-primary;
-  after-sb-1pri = consensus;
-  after-sb-2pri = disconnect;
-
-  NB: To allow the user to resolve from such situations manually
-      the "drbdadm connect" command (this is the "drbdsetup net"
-      command) gets a short-living flag called "--discard-my-data".
-  99% DONE
-
-6 It is possible that a secondary node crashes a primary by
-  returning invalid block_ids in ACK packets. [This might be
-  either caused by faulty hardware, or by a hostile modification
-  of DRBD on the secondary node]
-
-  Proposed solution:
-
-  Have a hash table (hlist_head style), add the collision
-  member (hlist_node) to drbd_request.
-
-  Use the sector number of the drbd_request as key to the hash, each
-  drbd_request is also put into this hash table. We still use the
-  pointer as block_id.
-
-  When we get an ACK packet, we lookup the hash table with the
-  block_id, and may find the drbd_request there. Otherwise it
-  was a forged ACK.
-
-  Note: The actual key to the hash should be (sector & ~0x7).
-        See item 9 for more details.
-  99% DONE
-
-7 Handle split brain situations; Support IO fencing;
-
-  New commands:
-    drbdadm outdate r0
-
-    When the device is configured this works via an ioctl() call.
-    In the other case it modifies the meta data directly by
-    calling drbdmeta.
-
-  remove option: on-disconnect
-
-  New meta-data flag: "Outdated"
-
-  introduce:
-  disk {
-    fencing [ dont-care | resource-only | resource-and-stonith ];
-  }
-
-  handlers {
-    outdate-peer "some script";
-  }
-
-  If the disk state of the peer is unknown, drbd calls this
-  handler (yes a call to userspace from kernel space). The handler's
-  returncodes are:
-
-  3 -> peer is inconsistent
-  4 -> peer is outdated (this handler outdated it) [ resource fencing ]
-  5 -> peer was down / unreachable
-  6 -> peer is primary
-  7 -> peer got stonithed [ node fencing ]
-
-  Let us assume that we have two boxes (N1 and N2) and that these
-  two boxes are connected by two networks (net and cnet [ clinets'-net ]).
-
-  Net is used by DRBD, while heartbeat uses both, net and cnet
-
-  I know that you are talking about fencing by STONITH, but DRBD is
-  not limited to that. Here comes my understanding of how resource fencing
-  should works with DRBDv8 :
-
-   N1  net   N2
-   P/S ---  S/P     everything up and running.
-   P/? - -  S/?     network breaks ; N1 freezes IO
-   P/? - -  S/?     N1 fences N2:
-                    In the STONITH case: turn off N2.
-                    In the resource fencing case:
-                    N1 asks N2 to fence itself from the storage via cnet.
-                    HB calls "drbdadm outdate r0" on N2.
-                    N2 replies to N1 that fencing is done via cnet.
-                    The outdate-peer script on N1 returns sucess to DRBD.
-   P/D - -  S/?     N1 thaws IO
-
-  N2 got the the "Outdated" flag set in its meta-data, by the outdate
-  command.
-
-  The fencing is set to resource-only enables this behaviour. In the
-  resource-only case the outdate-peer handler should have a return
-  value of 3, 4, 5 or 6, but should not return 7.
-
-  In case "fencing" is set to "resource-and-stonith", all IO operations
-  get immediately frozen (even all currently outstanding IO operations
-  will not finish) upon loss of connection.
-
-  Then the "outdate-peer" handler is started. In this configuration
-  the outdate peer handler might return any of the documented return
-  values.
-
-  When the outdate-peer handler returns IO is resumed.
-
-  Notes:
-  * Why do we need to freeze IO in the "resource-and-stonith" case:
-      Stonith protects you when all communication pathes fail. In
-      that case both (isolated) nodes try to stonith each other.
-      If the current primary would continue to allow IO it could
-      accept transactions, but could get stonithed by the
-      currently secondary node.
-      -> Therefore others could see commited transactions that
-         would be gone after the successfull stonith operation.
-
-  * The outedate peer handler also gets called if an unconnected
-    secondary wants to become primary.
-    In other words it only may become primary when it knows that
-    the peer is outdated/inconsistent.
-
-  * We need to store the fact that the peer is outdated/inconsistent
-    in the meta-data. To allow an stand allone primary to be rebooted.
-
-  * The outdate-peer program gets two environment variables:
-    DRBD_RESOURCE the name of the DRBD-resource and DRBD_PEER
-    the host name of the peer.
-
-  99% DONE
-
-8 New command drbdmeta
-
-  We move the read_gc.pl/write_gc.pl to the user directory.
-  Make them to one C program: drbdmeta
-   -> in the future the module never creates the meta data
-      block. One can use drbdmeta to create, read and
-      modify the drbdmeta block. drbdmeta refuses to write
-      to it as long as the module is loaded (configured).
-
-  drbdsetup gets the ability to read the gc values while DRBD
-  is set up via an ioctl() call. -- drbdmeta refuses to run
-  if DRBD is configured.
-
-  drbdadm is the nice front end. It always uses the right
-  back end (drbdmeta or drbdsetup)...
-
-  drbdadm set-gi 1:2:3:4:5:6 r0
-  drbdadm get-gi r0
-  drbdadm md-create r0
-
-  md-create would ask nasty questions about whether you are really
-  sure and so on, and do some plausibility checks first.
-  md-set would be undocumented and for wizards only.
-  80% DONE
-
-9 Support shared disk semantics  ( for GFS, OCFS etc... )
-
-    All the thoughts in this area, imply that the cluster deals
-    with split brain situations as discussed in item 6.
-
-  In order to offer a shared disk mode for GFS, we allow both
-  nodes to become primary. (This needs to be enabled with the
-  config statement net { allow-two-primaries; } )
-
- Read after write dependencies
-
-  The shared mode is available to clusters using protocol C.
-  It is not usable with protocol A or B.
-
- Global write order
-
-  [ Description of GFS-mode-arbitration2.pdf ]
-
-  1. Basic mirroring with protocol C.
-    The file system on N2 issues a write request towards DRBD,
-    which is written to the local disk and sent to N1. Then
-    the data bock is written to the local disk here and and
-    acknowledge packet is sent back. As soon as both the
-    write to the local disk and the ACK from N1 reach N2,
-    DRBD signals the completion of IO to the file system.
-
-    The major pitfall is the handling of concurrent writes to the
-    same block. (Concurrent writes to the same blocks should not
-    happen, but we have to assume that it is possible that the
-    synchronisation methods of our upper layer [i.e. openGFS]
-    may fail.)
-
-    There are many cases in which such concurrent writes would
-    lead to different data on our two copies of the block.
-
-  *** FIXME ***
-  description of algorithm here is out of date,
-  we handle things slightly differently now in the code.
-
-  2. Concurrent writes, network latency is lower than disk latency
-    As we can see on the left side in figure two this could lead
-    to N1 has the blue version (=data from FS on N2) while N2
-    ends with having the green version (=data from FS on N1).
-    The solution is to flag one node (in the example N2 has the
-    discard-concurrent-writes-flag).
-    As we can see on the right side, now both nodes ends with
-    the blue data.
-
-  3. Concurrent writes, high latency for data packets.
-    The problem now is that N2 does can not detect that this was
-    a concurrent write, since it got the ACK before the conflicting
-    data packets comes in.
-    This can happens since in DRBD, data packets and ACK packets are
-    transmitted via two independent TCP connections, therefore the
-    ACK packet can overtakes a data packet.
-    The solution is to send with the ACK packet a discard info packet,
-    which identifies the data packet by it sequence number.
-    N2 will keep this discard info as long as it has not seen higher
-    sequence numbers by now.
-    With this both nodes will end with the blue data.
-
-  4. Concurrent writes, high latency for data packets.
-    This is the inverse case to case3 and already handled by the means
-    introduced with item 1.
-
-  5. New write while processing a write from the peer.
-    Without further measures this would lead to an inconsistency in
-    our mirror as the figure on the left side shows.
-    If we currently write a conflicting block from the peer, we simply
-    discard the write request from our FS and signal IO completion
-    immediately.
-
-  6. High disk latency on N2.
-    By IO reordering in the layers below us this could lead to
-    having the blue data on N2 and the green data on N1.
-    The solution to this case is the delay the write to the local
-    disk on N2 until the local write is done. This is different from
-    case two since we already got the write ACK to the conflicting
-    block.
-
-  7. An data packet overtakes an ACK packet on the network.
-    Although this case is quite unlikely, we have to take int into
-    account. From N2's point of fiew this looks a lot like case 4,
-    but N2 should not delete the data packet now!
-
- Proposed solution
-
-  We arbitrary select one node (e.g. the node that did the first
-  accept() in the drbd_connect() function) and mark it withe the
-  discard-concurrent-writes-flag.
-
-  Each data packet and each ACK packet gets a sequence
-  number, which is increased which every packet sent.
-  (This is a common space of sequence numbers)
-
-  The algorithm which is performed upon the reception of a
-  data packet [drbd_receiver].
-
-  *  If the sequence number of the data packet is higher than
-     last_seq+1 sleep until last_seq+1 == seq_num(data packet)
-     [needed to satisfy example case 7]
-
-  1. If the packet's sequence number is on the discard list,
-     simply drop it.
-     [ ex.c. 3]
-  2. Do we have a concurrent request? (i.e. Do I have a request
-     to the same block in my transfer log.) If not -> write now.
-     [ default ]
-  3. Have I already got an ACK packet for the concurrent
-     request ? (Has the request the RQ_DRBD_SENT bit already set)
-     If yes -> write the data from the data packet afterwards.
-     [ ex.c. 6]
-  4. Do I have the "discard-concurrent-write-flag" ?
-     If yes -> discard the data packet.
-     If no -> Write data from the data packet afterwards and set
-              the RQ_DRBD_SENT bit in the request object ( Since
-              will will not get an ACK from our peer). Mark the
-	      ee to prepend the ACK packet with a discard info
-	      packet.
-     [ ex.c. *]
-
-  The algorithm which is performed upon the reception of an
-  ACK packet [drbd_asender]
-
-  * If we get an ACK, store the sequence number in last_seq.
-
-  The algorithm which is performed upon the reception of an
-  discard info packet [drbd_asender]
-
-  * if the current last_seq is lower the the packet that should
-    be discarded, store it in the to discard list.
-
-  BTW, each time we have a concurrent write access, we print
-  a warning to the syslog, since this indicates that the layer
-  above us is broken!
-
-  Note: In Item 6 we created a hash table over all requests in the
-        transfer log, keyed with (sector & ~0x7). This allows us
-        to find IO operations starting in the same 4k block of
-        data quickly. -> With two lookups the hash table we can
-	find any concurrent access.
-  99% DONE
-
-10 Change Sync-groups to sync-after
-
-  Sync groups turned out to be hard to configure and more
-  complex setups, hard to implement right and last not least they
-  are not flexible enough to cover all real world scenarios.
-
-  E.g. Two physical disks should be mirrored with DRBD. On one
-       of the disks there is only a single partition, while the
-       other one is divided into many (e.g. 4 smaller) partitions.
-       One would want to sync the big one in parallel to the
-       4 small ones. While the resync process of the 4 small
-       ones need to be serialized.
-       -> With the current sync groups you can not express
-          this requirement.
-
-  Remove config options   syncer { group <number>; }
-  Introduce config options   syncer { after <resource>; }
-  99% DONE
-      Finished the implementation. Tested.
-
-11 Take into account that the two systems could have different
-  PAGE_SIZE.
-
-  At least we should negotiate the PAGE_SIZE used by the peers,
-  and use it. In case the PAGE_SIZE is not the same inform
-  the user about the fact.
-
-  Probably a general high performance implementation for this
-  issue is not necessary, since clusters of machines with
-  different PAGE_SIZE are of academic interest only.
-  100% DONE by item 15
-
-12 Introduce a "common" section in the config file. Option
-  section (like handlers, startup, disk, net and syncer)
-  are inherited from the common section, if they are not
-  defined in a resource section.
-  99% DONE
-
-13 Introduce an UUID (universally unique identifier) in the
-  meta data. One purpose is to tag the bitmap with this UUID.
-  If the peer's UUID is different to what we expect we know that
-  we have to do a full sync....
-  99% DONE
-  -> Will be go out again, and become replaced by UUID for data
-     generations. See item 16
-
-14 Sanitize ioctls to inlcude a standard device information struct
-  at the beginning, including the expected API version.
-  Consider using DRBD ioctls with some char device similar to
-  /dev/mapper/control
-
-  The new interface is now based on netlink (actually connector).
-  It is based on the concept of tag lists. The idea is that on the
-  interface we pass lists (actually arrays) of tags. Where each
-  tag identifies the following sniplet of data.
-  Each tag also states if it is mandatory.
-
-  In case we have to add a new value to the interface, the
-  existing userland tools continue to work with newer kernel
-  modules and vice versa. (Only the older part of the two will
-  inform the user with a warning, that there was a unknown
-  tag on the interface, and that the unknown tag got ignored)
-  But the basic functionality stays intact!
-
-  While implementing this, we also implemented dynamic device allocation.
-
-  drbdsetup is basically call compatible to its ioctl based
-  ancestor, but has two now options:
-
-    --create-device ___ create the device in case int does not exist yet.
-    --set-defaults ____ set all not mentioned options to it's default values.
-
-  Things to do:
-
-  * Locking in userspace, to prevent multiple instances of drbdsetup
-  * Think about locking in kernel space ( device_mutex? )
-
-  80% DONE
-
-15 Accept BIOs bigger than one page, probabely up to 32k (8 pages)
-  currently.
-  * Normal Requsts. -> DONE
-  * Make the syncer to commulate adjacent bits into bigger requests. -> DONE
-  * Make the bitmap more coarse grained. -> TODO
-  66% DONE
-
-16 Displace the current generation-counters with a data-generation-UUID
-   concept.
-  The current generation counters have various weaknesses:
-   * In a split braine'd cluster the appliance of the same events
-     to both cluster nodes could lead to equal generation-counters
-     on both nodes, while the data is not in sync for sure.
-   * They are completely unsuitable if a 3rd node is used for
-     e.g. weekly snapshots.
-   * Gracefull takeover while disconnected not possible.
-
-  We associate each data generation with an unique UUID (=64 bit random
-  number). A new data generation is created if a primary node is
-  disconnected from its secondary and when a degraded secondary
-  becomes primary for the first time.
-
-  In the meta-data we store a few generations-UUIDs:
-   * current
-   * bitmap
-   * history[2]
-
-  As well as the currently known flags:
-   Consistent, WasUpToDate, LastState, ConnectedInd, WantFullSync
-
-  When the cluster is in Connected state, then the bitmpat gen-UUID
-  is set to 0 (Since the Bitmap is empty). When we create a new current
-  gen-UUID while we are disconencted the (old) current gets backed-up
-  to the bitmap gen-UUID. (This allowes us to identify the base of
-  of the bitmap later)
-
-  Special UUID values:
-  JustCreated [JC] ___  4
-
-  ALGORITHMS
-
-  Upon Connect:
-      self   peer   action
-  1.  C=JC   C=JC   No Sync
-  2.  C=JC   C!=JC  I am SyncTarget setting BM
-  3. C!=JC   C=JC   I am SyncSource setting BM
-  4.   C   =   C    Common power [off|failure](Examine the roles at crash time)
-  4.1  sec   sec    Common power off, no sync.
-  4.2  pri   sec    Common power failure, I am SyncSource using BM
-  4.3  sec   pri    Common power failure, I am SyncTarget using BM
-  4.4  pri   pri    Common power failure, resync in arbitrary direction.
-  5.   C   =   B    I am SyncTarget using BM
-  6.   C   = H1|H2  I am SyncTarget setting BM
-  7.   B   =   C    I am SyncSource using BM
-  8. H1|H2 =   C    I am SyncSource setting BM
-  9.   B   =   B    [ and B != 0 ] SplitBrain, try auto recover strategies.
-  10 H1|H2 = H1|H2  SplitBrain, disconnect.
-  11.               Warn about unrelated Data, disconnect.
-
-  Upon Disconnect:
-   Primary:
-      Copy the current-UUID over to the bitmap-UUID, create a new
-      current-UUID.
-   Secondary:
-      Nothing to do.
-
-  Upon becomming Primary:
-   In case we are disconnected and the bitmap-UUID is emptry, copy the
-   current-UUID over to the bitmap-UUID and create a new current-UUID.
-   Special-case: primary with --do-what-I-say, clearing the inconsistent
-                 flag causes a new UUID to be generated.
-
-  Upon start of resync:
-   Clear the consistent-flag on the SyncTarget. Generate a new UUID for
-   the bitmap-UUID of the SyncSource and the current-UUID of the SyncTarget.
-
-  Upon finish of resync:
-   Set the bitmap-UUID to 0. The SyncTarget addopts the current-UUID
-   of the SyncSource, and sets its consistent-flag.
-
-  When the bitmap-UUID gets cleared, move the previous value to H1.
-  In case H1 was already set copy its previous value to H2. Etc..
-
-  For the auto recover strategies after split brain (see item 5)
-  it is neccessary to embedd the node's role into the UUIDs.
-  This is masked out of course when the UUIDs are compared.
-
-  * Note1: Discontinue the --human and --timout options when
-           becoming primary.
-           NB: If they are needed, I think they can be implemented
-               as special UUID values.
-
-  99% DONE. Kernel part is implemented, userland parts are implemented,
-	    --humand and --timeout-expired are removed.
-	    Everything seems to work so far.
-
-  Known issues: we have to define behaviour for two-primaries case,
-  and for connection loss when Primary with local disk != UpToDate.
-
-17 Something like
-
-   drbdx: WARNING disk sizes more than 10% different
-
-  would be nice at (initial) full sync.
-  drbdx: WARNING disk sizes more than 10% different
-
-18 Connection-Teardown Packet. Currently the new state-checks
-  disallows "drbdadm disconnect res" on the primary node of a
-  connected cluster.
-  Thes Teardown Packet causes the secondary-node to outdate
-  its data and to close the connection in one go.
-  99% DONE.
-
-19 Make the updates to the bitmap transactional. Esp for resizing.
-  Make updates to the superblock transactional
-
-20 There are quite a number of parameters that must be set equal
-   (or some reciprocal) on the two nodes. We need to ensure that
-   the config is valid, from a viewpoint of the whole cluster.
-   E.g.
-   protocol				equal
-   after-sb-0pri / discard-local/remote	equal / reciprocal
-   after-sb-1pri			equal
-   after-sb-2pri			equal
-   want_lose				reciprocal
-   two_primaries			equal
-  99% DONE
-
-21 Write barriers in the kernel
+1 Write barriers in the kernel
   In Linux-2.6 write barriers in the block-io layer are represented as
   REQ_SOFTBARRIER, REQ_HARDBARRIER and REQ_NOMERGE flags on requests.
   In the BIO layer this is BIO_RW_BARRIER, which is usually set on
@@ -724,218 +138,18 @@
 
   90% DONE [ Not tested yet. ]
 
-22 Reboot notifier.
+2  Increase the number of UUID history slots.
 
-23 External imposed SyncPause states.
-   There are two new commands: 'drbdadm pause-sync res'
-                               'drbdadm resume-sync res'
-   These may be used to suspend the resynchronisation process while
-   e.g. the backing storages' raid controller does its resynchronisation.
-
-   While implementing this, I also made shure that in a 3 node
-   setup the two peers of a connection will agree if a resynchronisation
-   is paused under all conditions you can think of, if there are more
-   than two nodes!
-
-   99% DONE
-
-24 Make it possible to hot-add disk drives == Atomic configuration changes.
-
-   99% DONE
-
-25 Add reserved fields to DRBD-meta-data, add a bytes per bit field to
-   metadata.
-
-   99% DONE
-
-26 Implement a kind of "dstate" command to make integration with
-   Heartbeat-2.0's master/slave-support possible.
-
-   99% DONE
-
-27 Remove all explicit drbd_md_write() calls, and create a mechanism,
-   that always keeps the on disk-metadata up-to-date implicit.
-   Calling drbd_md_write() explicit is too errorprone.
-
-   99% DONE
-
-28 Implement a kind of 'call home', a single HTTP get request, that
-   gets counted in a data base. The initiator calculates a simple
-   hash over the machine and resource names. Each time a meta-data
-   set gets generated, the 'call home' is initiated. The user might
-   of course opt out of this.
-
-   99% DONE
-
-29 Make drbdadm to have 'hidden-commands' command to also show
-   the hidden sub-commands in the ussage.
-
-   99% DONE
-
-30 The current drbdadm_scanner is 1MB in source and as binary.
-   Use a _basic_ flex scanner, and a hand written parser for superb
-   errror reporting.
-
-   99% DONE
-
-31 Resizing several GB results in ko-count timeouts, maybe since the
-   secondary node does the enlargement of the bitmap in the receiver (?)
-
-   DONE, by using the async bitmap IO code.
-
-32 drbdmeta: with internal meta-data v07 and v08 meta-data super blocks
-   are in different places. -> It is possible to have v07 AND v08 meta
-   data on one device.
-   => drbdmeta should make sure that it overwrites the other location
-      in case it create a meta-data block.
-
-   99% DONE
-
-33 Serialize state changes like secondary -> primary and
-   Connected -> SyncSource in the cluster.
-
-      role <- primary
-      conn <- StartingSyncT (disk <- inconsistent)
-      conn <- StartingSyncS (pdsk <- inconsistent)
-      disk <- Diskless (as long as it happens as administrative command)
-      pdsk <- Outdated (= a 'disconnect' issued on a primary node)
-
-   * When a state change might sleep ( reuqest_state() ) and it is
-     to be cluster wide atomic ( pre_state_checks() determines this!).
-	1. Aquire the cluster state change lock (bit & waitqueue) ?
-	2. We send a request_state packet.
-
-   * When a request_state packet is received
-
-	1. * If we are UNIQUE we take the cluster lock (potentially
-	     waiting for it) and try to apply the remote's request
-	     as soon as we have the lock.
-	   * When we are not UNIQUE we try to apply the state change
-	     immediately (without taking the cluster lock).
-	2. We send the ACK / NACK.
-	   ( Do we actually need an ACK/NACK ?
- 		* On the not UNIQUE side, we will fail the request as
-		  soon as the offending state request comes in.
-                * On the UNIQUE side we need to positive ACK to
-		  continue.
-		) I guess for the sake of completeness, we should
-                  have both packets, although currently the need for
-		  the NACK packet is not abvious.
-
-   * When we receive an ACK / NACK we either sucessfully finish or
-     fail the the request_state() call. (Error codes should be passed
-     from the peer.)
-
-   * When the connection failes ( = actually a non-cluster wide state
-     change happens while a cluster wide state change goes on), we
-     need to re-evaluate the pre state change check. In case the
-     pre state change check allows the new state we can procees,
-     otherwise we need to fail the request.
-
-   * How to do the synchronisation form the receive of the ACK / NACK
-     packet to the termination of the request_state() function ?
-       * wait_queue & bit.
-
-   DATA STRUCTURES:
-	* A CLUSTER_STATE_CHANGE bit == the cluster lock bit.
-	* A CL_ST_CHG_SUCCESS  bit set by the receiver.
-	* A CL_ST_CHG_FAIL     bit set by the receiver.
-	* A wait queue.
-
-   TODOS:
-    Evaluate if it is possible to use it for starting resync. (invalidate)
-    Evaluate it for the other cases...
-
-  90 % Is implemented. Changing the role to primary already uses this
-       mechanism. Starting resync with invalidate and invalidate_remote
-       now also uses this method. Detaching now also uses this mechanism.
-
-34 Improve the initial hand-shake, to identify the sockets (and TCP-
-   links) by an initial message, and not only by the connection timming.
-
-   99% DONE
-
-35 Bigger AL-extents (e.g. 16MB)
-
-36 Increase the number of UUID history slots.
-
-37 In case heartbeat (or some one else) makes us primary, we need to
-   check first if the peer is alive.
-   Currently we habe a problem is when heartbeat's dead time is smaller
-   than DRBD's network timeout.
-
-38 Create an other on-io-error hander, that does retry failed read
+3  Create an other on-io-error hander, that does retry failed read
    operations on the peer, but does not detach from the local disk.
    And it sets that block in the bitmap as out-of-date.
 
    Simon works on this.
 
-39 Send mirrored write requests out of the worker context.
-   99% DONE
-
-40 Do something with FLUSHBUFS ioctl.
-
-41 Fix DRBD's behaviour in case of a common power failuer and when
-   both nodes were in primary role.
-
-   See the the Algorithm of Item 16, section 4 to 4.4 .
-
-   Further we need to have the resync rolces conflict  "rr-conflict"
-   strategy option with the following values:
-
-   The available options are:
-     "disconnect" ... No automatic resynchronisation, simply disconnect.
-     "violently" .... Sync to the primary node is allowed, violating the
-	              assumption that data on a block device is stable
-		      for one of the nodes. DANGEROUS, DO NOT USE.
-     "call-pri-lost"
-                      Call this helper program on one of the machines.
-                      This program is expected to halt or reboot the
-                      machine.
-
-   An exception of course is a primary disk-less node that gets a disk
-   attached. Such a nodes becomes sync target, but since it does not
-   show a violently data change, this state transition is always allowed.
-
-   99% DONE
-
-42 Forward port the abilitiy to resume the TL after IO was frozen,
+4  Forward port the abilitiy to resume the TL after IO was frozen,
    in case the connection is reestablished again.
 
-43 Fix indexed meta-data.
+5  Fix indexed meta-data.
 
-44 Callbacks to userspace should run asynchronous.
 
-Maybe:
 
-*  Switch to protocol C in case we are running without a local
-   disk and are configured to use protocol A or B.
-
-*  Dynamic misc char device instead of IOCTLs for configuration. Evaluate
-   if the configuration could be done over a netlink socket as well...
-
-*  A netlink socket to communicate events to userspace.
-   - All state changes
-   - the need to outdate the peer
-
-*  Write some heartbeat glue to do a gracefull switchover in case of
-   a local IO failue. (requires the netlink socket thing)
-
-plus-banches:
-----------------------
-
-1 Make use-csums to use the kernel's crypto API
-
-2 Implement online verification
-
-3 Change the bitmap code to work with unmapped highmem pages, instead
-  of using vmalloc()ed memory. This allows users of 32bit platforms
-  to use drbd on big devices (in the ~3TB range)
-
-4 3 node support. Do and test a 3 node setup (2nd DRBD stacked over
-  a DRBD pair). Enhance the user level tools to support the 3 node
-  setup.
-
-5 Have protocol version 74 available in drbd-0.8, to allow rolling
-  upgrades
-

From drbd-cvs at lists.linbit.com  Tue May 22 14:58:47 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue May 22 14:58:49 2007
Subject: [DRBD-cvs] svn commit by phil - r2899 - branches/drbd-8.0 - Setup
	properties for svnp. 
Message-ID: <20070522125847.BE8712E05EAE@mail.linbit.com>

Author: phil
Date: 2007-05-22 14:58:47 +0200 (Tue, 22 May 2007)
New Revision: 2899

Modified:
   branches/drbd-8.0/
Log:
Setup properties for svnp.



Property changes on: branches/drbd-8.0
___________________________________________________________________
Name: propagate:lo:1
   + ../drbd81
Name: propagate:to:1
   + /drbd/trunk

From drbd-cvs at lists.linbit.com  Tue May 22 14:59:53 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue May 22 15:00:01 2007
Subject: [DRBD-cvs] svn commit by phil - r2900 - trunk - Properties for svnp
Message-ID: <20070522125959.1D9042E05EAE@mail.linbit.com>

Author: phil
Date: 2007-05-22 14:59:53 +0200 (Tue, 22 May 2007)
New Revision: 2900

Modified:
   trunk/
Log:
Properties for svnp



Property changes on: trunk
___________________________________________________________________
Name: propagate:to
   - /drbd/plus-branches/08-10-csums
Name: propagate:at
   - 2291
Name: propagate:lo
   - ../drbd08-p-10
Name: propagate:at:1
   + 2898

From drbd-cvs at lists.linbit.com  Tue May 22 15:04:32 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue May 22 15:04:34 2007
Subject: [DRBD-cvs] svn commit by phil - r2901 - branches/drbd-8.0/drbd -
	Simon identified this: We need to make sure to have a c
Message-ID: <20070522130432.002802E05EAE@mail.linbit.com>

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

Modified:
   branches/drbd-8.0/drbd/drbd_main.c
Log:
Simon identified this:
  We need to make sure to have a connection in these cases.
  


Modified: branches/drbd-8.0/drbd/drbd_main.c
===================================================================
--- branches/drbd-8.0/drbd/drbd_main.c	2007-05-22 12:59:53 UTC (rev 2900)
+++ branches/drbd-8.0/drbd/drbd_main.c	2007-05-22 13:04:31 UTC (rev 2901)
@@ -935,15 +935,17 @@
 	}
 
 	/* Last part of the attaching process ... */
-	if ( os.disk == Attaching && ns.disk == Negotiating ) {
+	if ( ns.conn >= Connected && 
+	     os.disk == Attaching && ns.disk == Negotiating ) {
 		drbd_send_sizes(mdev);  // to start sync...
 		drbd_send_uuids(mdev);
 		drbd_send_state(mdev);
 	}
 
 	/* We want to pause/continue resync, tell peer. */
-	if (  ( os.aftr_isp != ns.aftr_isp ) ||
-	      ( os.user_isp != ns.user_isp ) ) {
+	if ( ns.conn >= Connected && 
+	     (( os.aftr_isp != ns.aftr_isp ) ||
+	      ( os.user_isp != ns.user_isp )) ) {
 		drbd_send_state(mdev);
 	}
 

From drbd-cvs at lists.linbit.com  Tue May 22 15:12:35 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue May 22 15:12:36 2007
Subject: [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 
Message-ID: <20070522131235.BC2C42E05EAE@mail.linbit.com>

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)

From drbd-cvs at lists.linbit.com  Tue May 22 15:13:38 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue May 22 15:13:40 2007
Subject: [DRBD-cvs] svn commit by phil - r2903 - in trunk: . drbd - First
	svnp run from branches/drbd-8.0 to trunk. 
Message-ID: <20070522131338.E9C292E05EAE@mail.linbit.com>

Author: phil
Date: 2007-05-22 15:13:37 +0200 (Tue, 22 May 2007)
New Revision: 2903

Modified:
   trunk/
   trunk/drbd/drbd_main.c
Log:
First svnp run from branches/drbd-8.0 to trunk.



Property changes on: trunk
___________________________________________________________________
Name: propagate:at:1
   - 2898
   + 2902

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2007-05-22 13:12:31 UTC (rev 2902)
+++ trunk/drbd/drbd_main.c	2007-05-22 13:13:37 UTC (rev 2903)
@@ -935,15 +935,17 @@
 	}
 
 	/* Last part of the attaching process ... */
-	if ( os.disk == Attaching && ns.disk == Negotiating ) {
+	if ( ns.conn >= Connected && 
+	     os.disk == Attaching && ns.disk == Negotiating ) {
 		drbd_send_sizes(mdev);  // to start sync...
 		drbd_send_uuids(mdev);
 		drbd_send_state(mdev);
 	}
 
 	/* We want to pause/continue resync, tell peer. */
-	if (  ( os.aftr_isp != ns.aftr_isp ) ||
-	      ( os.user_isp != ns.user_isp ) ) {
+	if ( ns.conn >= Connected && 
+	     (( os.aftr_isp != ns.aftr_isp ) ||
+	      ( os.user_isp != ns.user_isp )) ) {
 		drbd_send_state(mdev);
 	}
 

From drbd-cvs at lists.linbit.com  Tue May 22 15:21:59 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue May 22 15:22:01 2007
Subject: [DRBD-cvs] svn commit by phil - r2904 - in trunk: drbd drbd/linux
	user - Initial checkin of Stanislaw Gruszka's patch. Probably
Message-ID: <20070522132159.5F0B52E05EAE@mail.linbit.com>

Author: phil
Date: 2007-05-22 15:21:56 +0200 (Tue, 22 May 2007)
New Revision: 2904

Modified:
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_nl.c
   trunk/drbd/drbd_proc.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/drbd_req.c
   trunk/drbd/drbd_worker.c
   trunk/drbd/linux/drbd.h
   trunk/drbd/linux/drbd_nl.h
   trunk/user/drbdadm_main.c
   trunk/user/drbdsetup.c
Log:
Initial checkin of Stanislaw Gruszka's patch. Probably we will
change some details later...


Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2007-05-22 13:13:37 UTC (rev 2903)
+++ trunk/drbd/drbd_int.h	2007-05-22 13:21:56 UTC (rev 2904)
@@ -40,7 +40,6 @@
 #include "lru_cache.h"
 
 // module parameter, defined in drbd_main.c
-extern int minor_count;
 extern int allow_oos;
 extern int major_nr;
 extern int use_nbd_major;
@@ -141,7 +140,7 @@
 //       Otherwise this is not portable from gcc-2.95 to gcc-3.3
 #define PRINTK(level,fmt,args...) \
 	printk(level DEVICE_NAME "%d: " fmt, \
-		mdev->minor , ##args)
+		mdev_to_minor(mdev) , ##args)
 
 #define ALERT(fmt,args...) PRINTK(KERN_ALERT, fmt , ##args)
 #define ERR(fmt,args...)  PRINTK(KERN_ERR, fmt , ##args)
@@ -263,7 +262,6 @@
 /* drbd_meta-data.c (still in drbd_main.c) */
 #define DRBD_MD_MAGIC (DRBD_MAGIC+4) // 4th incarnation of the disk layout.
 
-extern struct Drbd_Conf **minor_table;
 
 /***
  * on the wire
@@ -861,22 +859,23 @@
 	atomic_t packet_seq;
 	unsigned int peer_seq;
 	spinlock_t peer_seq_lock;
-	int minor;
 	unsigned long comm_bm_set; // communicated number of set bits.
+
+	struct list_head devs_list;
 };
 
+extern struct semaphore drbd_devs_mutex;
+extern struct list_head drbd_devs_list;
+extern drbd_dev *drbd_find_minor(int minor);
+
 static inline drbd_dev *minor_to_mdev(int minor)
 {
-	drbd_dev *mdev;
-
-	mdev = minor < minor_count ? minor_table[minor] : NULL;
-
-	return mdev;
+	return drbd_find_minor(minor);
 }
 
 static inline int mdev_to_minor(drbd_dev *mdev)
 {
-	return mdev->minor;
+	return mdev->vdisk->first_minor;
 }
 
 /* returns 1 if it was successfull,
@@ -1165,7 +1164,6 @@
  * because of kmem_cache_t weirdness */
 #include "drbd_compat_wrappers.h"
 
-extern int minor_count;
 extern drbd_kmem_cache_t *drbd_request_cache;
 extern drbd_kmem_cache_t *drbd_ee_cache;
 extern mempool_t *drbd_request_mempool;
@@ -1175,8 +1173,10 @@
 extern spinlock_t   drbd_pp_lock;
 extern int          drbd_pp_vacant;
 extern wait_queue_head_t drbd_pp_wait;
+extern unsigned int prealloc_segments;
 
-extern drbd_dev *drbd_new_device(int minor);
+extern int drbd_create_device(int minor);
+extern int drbd_remove_device(drbd_dev *mdev);
 
 // Dynamic tracing framework
 #ifdef ENABLE_DYNAMIC_TRACE

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2007-05-22 13:13:37 UTC (rev 2903)
+++ trunk/drbd/drbd_main.c	2007-05-22 13:21:56 UTC (rev 2904)
@@ -46,6 +46,7 @@
 #include <linux/reboot.h>
 #include <linux/notifier.h>
 #include <linux/byteorder/swabb.h>
+#include <linux/idr.h>
 
 #define __KERNEL_SYSCALLS__
 #include <linux/unistd.h>
@@ -81,15 +82,13 @@
 MODULE_AUTHOR("Philipp Reisner <phil@linbit.com>, Lars Ellenberg <lars@linbit.com>");
 MODULE_DESCRIPTION("drbd - Distributed Replicated Block Device v" REL_VERSION);
 MODULE_LICENSE("GPL");
-MODULE_PARM_DESC(minor_count, "Maximum number of drbd devices (1-255)");
 MODULE_ALIAS_BLOCKDEV_MAJOR(LANANA_DRBD_MAJOR);
 
 #include <linux/moduleparam.h>
 /* allow_open_on_secondary */
 MODULE_PARM_DESC(allow_oos, "DONT USE!");
 /* thanks to these macros, if compiled into the kernel (not-module),
- * this becomes the boot parameter drbd.minor_count */
-module_param(minor_count, int,0);
+ * this becomes the boot parameter */
 module_param(allow_oos, bool,0);
 
 #ifdef DRBD_ENABLE_FAULTS
@@ -105,7 +104,6 @@
 
 // module parameter, defined
 int major_nr = LANANA_DRBD_MAJOR;
-int minor_count = 32;
 
 int allow_oos = 0;
 
@@ -122,11 +120,6 @@
 // global panic flag
 volatile int drbd_did_panic = 0;
 
-/* in 2.6.x, our device mapping and config info contains our virtual gendisks
- * as member "struct gendisk *vdisk;"
- */
-struct Drbd_Conf **minor_table = NULL;
-
 drbd_kmem_cache_t *drbd_request_cache;
 drbd_kmem_cache_t *drbd_ee_cache;
 mempool_t *drbd_request_mempool;
@@ -143,6 +136,10 @@
 int          drbd_pp_vacant;
 wait_queue_head_t drbd_pp_wait;
 
+unsigned int prealloc_segments = 32;
+module_param(prealloc_segments,uint,0664);
+MODULE_PARM_DESC(prealloc_segments, "number of preallocated segments, default 32");
+
 STATIC struct block_device_operations drbd_ops = {
 	.owner =   THIS_MODULE,
 	.open =    drbd_open,
@@ -151,6 +148,12 @@
 
 #define ARRY_SIZE(A) (sizeof(A)/sizeof(A[0]))
 
+DECLARE_MUTEX(drbd_devs_mutex);
+LIST_HEAD(drbd_devs_list);
+
+STATIC DECLARE_MUTEX(_minor_lock);
+STATIC DEFINE_IDR(_minor_idr);
+
 /************************* The transfer log start */
 STATIC int tl_init(drbd_dev *mdev)
 {
@@ -1957,8 +1960,66 @@
 					0 } };
 }
 
-void drbd_init_set_defaults(drbd_dev *mdev)
+STATIC void drbd_list_add(drbd_dev *mdev)
 {
+	list_add_tail(&mdev->devs_list, &drbd_devs_list);
+}
+
+STATIC void drbd_list_del(drbd_dev *mdev)
+{
+	list_del(&mdev->devs_list);
+}
+
+drbd_dev *drbd_find_minor(int minor)
+{
+	return idr_find(&_minor_idr, minor);
+}
+
+STATIC int drbd_get_minor(drbd_dev *mdev, int minor)
+{
+	int r, m;
+
+	if (minor >= (1 << MINORBITS))
+		return MinorInvalid;
+
+	down(&_minor_lock);
+
+	if (idr_find(&_minor_idr, minor)) {
+		r = MinorInUse;
+		goto out;
+	}
+
+	if (!idr_pre_get(&_minor_idr, GFP_KERNEL)) {
+		r = KMallocFailed;
+		goto out;
+	}
+
+	if (idr_get_new_above(&_minor_idr, mdev, minor, &m)) {
+		r = KMallocFailed;
+		goto out;
+	}
+
+	if (m != minor) {
+		idr_remove(&_minor_idr, m);
+		r = MinorInUse;
+		goto out;
+	}
+
+	r = NoError;
+out:
+	up(&_minor_lock);
+	return r;
+}
+
+STATIC void drbd_put_minor(int minor)
+{
+	down(&_minor_lock);
+	idr_remove(&_minor_idr, minor);
+	up(&_minor_lock);
+}
+
+void drbd_init_set_defaults(drbd_dev *mdev, int minor)
+{
 	// the memset(,0,) did most of this
 	// note: only assignments, no allocation in here
 
@@ -2021,6 +2082,26 @@
 	drbd_thread_init(mdev, &mdev->worker, drbd_worker);
 	drbd_thread_init(mdev, &mdev->asender, drbd_asender);
 
+	mdev->rq_queue->queuedata = mdev;
+	mdev->rq_queue->max_segment_size = DRBD_MAX_SEGMENT_SIZE;
+
+	set_disk_ro(mdev->vdisk, TRUE);
+	mdev->vdisk->queue = mdev->rq_queue;
+	mdev->vdisk->major = MAJOR_NR;
+	mdev->vdisk->first_minor = minor;
+	mdev->vdisk->minors = 1;
+	mdev->vdisk->fops = &drbd_ops;
+	sprintf(mdev->vdisk->disk_name, DEVICE_NAME "%d", minor);
+	mdev->this_bdev = bdget(MKDEV(MAJOR_NR,minor));
+
+	// we have no partitions. we contain only ourselves.
+	mdev->this_bdev->bd_contains = mdev->this_bdev;
+	blk_queue_make_request(mdev->rq_queue, drbd_make_request_26);
+	blk_queue_merge_bvec(mdev->rq_queue, drbd_merge_bvec);
+	mdev->rq_queue->queue_lock = &mdev->req_lock; // needed since we use
+	// plugging on a queue, that actually has no requests!
+	mdev->rq_queue->unplug_fn = drbd_unplug_fn;
+
 #ifdef __arch_um__
 	INFO("mdev = 0x%p\n",mdev);
 #endif
@@ -2109,7 +2190,6 @@
 
 }
 
-
 void drbd_destroy_mempools(void)
 {
 	struct page *page;
@@ -2121,7 +2201,7 @@
 		drbd_pp_vacant--;
 	}
 
-	/* D_ASSERT(atomic_read(&drbd_pp_vacant)==0); */
+	/* D_ASSERT(drbd_pp_vacant==0); */
 
 	if (drbd_ee_mempool) mempool_destroy(drbd_ee_mempool);
 	if (drbd_request_mempool) mempool_destroy(drbd_request_mempool);
@@ -2139,7 +2219,7 @@
 int drbd_create_mempools(void)
 {
 	struct page *page;
-	const int number = (DRBD_MAX_SEGMENT_SIZE/PAGE_SIZE) * minor_count;
+	const int number = (DRBD_MAX_SEGMENT_SIZE/PAGE_SIZE) * prealloc_segments;
 	int i;
 
 	// prepare our caches and mempools
@@ -2173,6 +2253,7 @@
 		goto Enomem;
 
 	// drbd's page pool
+	init_waitqueue_head(&drbd_pp_wait);
 	spin_lock_init(&drbd_pp_lock);
 
 	for (i=0;i< number;i++) {
@@ -2203,165 +2284,190 @@
 STATIC struct notifier_block drbd_notifier = {
 	.notifier_call = drbd_notify_sys,
 };
+void drbd_free_device(drbd_dev *mdev)
+{
+	int rr;
 
+	drbd_free_resources(mdev);
 
-STATIC void __exit drbd_cleanup(void)
-{
-	int i, rr;
+	if (mdev->vdisk) {
+		if (mdev->vdisk->private_data)
+			del_gendisk(mdev->vdisk);
+		if (mdev->rq_queue)
+			blk_put_queue(mdev->rq_queue);
+		put_disk(mdev->vdisk);
+	}
+	
+	D_ASSERT(mdev->open_cnt == 0);
+	if (mdev->this_bdev) bdput(mdev->this_bdev);
 
-	unregister_reboot_notifier(&drbd_notifier);
+	tl_cleanup(mdev);
+	if (mdev->bitmap) drbd_bm_cleanup(mdev);
+	if (mdev->resync) lc_free(mdev->resync);
 
-	drbd_nl_cleanup();
+	rr = drbd_release_ee(mdev,&mdev->active_ee);
+	if(rr) ERR("%d EEs in active list found!\n",rr);
 
-	if (minor_table) {
-		if (drbd_proc)
-			remove_proc_entry("drbd",&proc_root);
-		i=minor_count;
-		while (i--) {
-			drbd_dev        *mdev  = minor_to_mdev(i);
-			struct gendisk  **disk = &mdev->vdisk;
-			request_queue_t **q    = &mdev->rq_queue;
+	rr = drbd_release_ee(mdev,&mdev->sync_ee);
+	if(rr) ERR("%d EEs in sync list found!\n",rr);
 
-			if(!mdev) continue;
-			drbd_free_resources(mdev);
+	rr = drbd_release_ee(mdev,&mdev->read_ee);
+	if(rr) ERR("%d EEs in read list found!\n",rr);
 
-			if (*disk) {
-				del_gendisk(*disk);
-				put_disk(*disk);
-				*disk = NULL;
-			}
-			if (*q) blk_put_queue(*q);
-			*q = NULL;
+	rr = drbd_release_ee(mdev,&mdev->done_ee);
+	if(rr) ERR("%d EEs in done list found!\n",rr);
 
-			D_ASSERT(mdev->open_cnt == 0);
-			if (mdev->this_bdev) bdput(mdev->this_bdev);
+	rr = drbd_release_ee(mdev,&mdev->net_ee);
+	if(rr) ERR("%d EEs in net list found!\n",rr);
 
-			tl_cleanup(mdev);
-			if (mdev->bitmap) drbd_bm_cleanup(mdev);
-			if (mdev->resync) lc_free(mdev->resync);
+	ERR_IF (!list_empty(&mdev->data.work.q)) {
+		struct list_head *lp;
+		list_for_each(lp,&mdev->data.work.q) {
+				DUMPP(lp);
+		}
+	};
 
-			rr = drbd_release_ee(mdev,&mdev->active_ee);
-			if(rr) ERR("%d EEs in active list found!\n",rr);
+	if (mdev->md_io_page)
+		__free_page(mdev->md_io_page);
 
-			rr = drbd_release_ee(mdev,&mdev->sync_ee);
-			if(rr) ERR("%d EEs in sync list found!\n",rr);
+	if (mdev->md_io_tmpp)
+		__free_page(mdev->md_io_tmpp);
 
-			rr = drbd_release_ee(mdev,&mdev->read_ee);
-			if(rr) ERR("%d EEs in read list found!\n",rr);
+	if (mdev->act_log) lc_free(mdev->act_log);
 
-			rr = drbd_release_ee(mdev,&mdev->done_ee);
-			if(rr) ERR("%d EEs in done list found!\n",rr);
+	if(mdev->ee_hash) {
+		kfree(mdev->ee_hash);
+		mdev->ee_hash_s = 0;
+		mdev->ee_hash = NULL;
+	}
+	if(mdev->tl_hash) {
+		kfree(mdev->tl_hash);
+		mdev->tl_hash_s = 0;
+		mdev->tl_hash = NULL;
+	}
+	if(mdev->app_reads_hash) {
+		kfree(mdev->app_reads_hash);
+		mdev->app_reads_hash = NULL;
+	}
+	if ( mdev->p_uuid ) {
+		kfree(mdev->p_uuid);
+		mdev->p_uuid = NULL;
+	}
+}
 
-			rr = drbd_release_ee(mdev,&mdev->net_ee);
-			if(rr) ERR("%d EEs in net list found!\n",rr);
+STATIC int drbd_alloc_device(drbd_dev *mdev, int minor)
+{
+	mdev->rq_queue = blk_alloc_queue(GFP_KERNEL);
+	if (!mdev->rq_queue)
+		goto Enomem;
 
-			ERR_IF (!list_empty(&mdev->data.work.q)) {
-				struct list_head *lp;
-				list_for_each(lp,&mdev->data.work.q) {
-					DUMPP(lp);
-				}
-			};
+	mdev->vdisk = alloc_disk(1);
+	if (!mdev->vdisk)
+		goto Enomem;
+	
+	drbd_init_set_defaults(mdev, minor);
 
-			if (mdev->md_io_page)
-				__free_page(mdev->md_io_page);
+	mdev->md_io_page = alloc_page(GFP_KERNEL);
+	if (!mdev->md_io_page)
+		goto Enomem;
 
-			if (mdev->md_io_tmpp)
-				__free_page(mdev->md_io_tmpp);
+	if (drbd_bm_init(mdev))
+		goto Enomem;
+	
+	// FIXME: lock access, if not module initializing ?
+	// no need to lock access, we are still initializing the module.
+	if (!tl_init(mdev))
+		goto Enomem;
 
-			if (mdev->act_log) lc_free(mdev->act_log);
+	mdev->app_reads_hash = kzalloc(APP_R_HSIZE*sizeof(void*),GFP_KERNEL);
+	if (!mdev->app_reads_hash)
+		goto Enomem;
+	
+	return NoError;
 
-			if(mdev->ee_hash) {
-				kfree(mdev->ee_hash);
-				mdev->ee_hash_s = 0;
-				mdev->ee_hash = NULL;
-			}
-			if(mdev->tl_hash) {
-				kfree(mdev->tl_hash);
-				mdev->tl_hash_s = 0;
-				mdev->tl_hash = NULL;
-			}
-			if(mdev->app_reads_hash) {
-				kfree(mdev->app_reads_hash);
-				mdev->app_reads_hash = NULL;
-			}
-			if ( mdev->p_uuid ) {
-				kfree(mdev->p_uuid);
-				mdev->p_uuid = NULL;
-			}
-		}
-		drbd_destroy_mempools();
-	}
+Enomem:
+	drbd_free_device(mdev);
+	return KMallocFailed;
+}
 
-	kfree(minor_table);
+int drbd_remove_device(drbd_dev *mdev)
+{
+	if (mdev->state.disk != Diskless)
+		return HaveDiskConfig;
 
-	if (unregister_blkdev(MAJOR_NR, DEVICE_NAME) != 0)
-		printk(KERN_ERR DEVICE_NAME": unregister of device failed\n");
+	if (mdev->state.conn != StandAlone)
+		return HaveNetConfig; 
 
-	printk(KERN_INFO DEVICE_NAME": module cleanup done.\n");
+	down(&drbd_devs_mutex);
+	drbd_list_del(mdev);
+	up(&drbd_devs_mutex);
+
+	/* wait all work will be finished */
+	drbd_thread_stop(&mdev->receiver);
+	drbd_thread_stop(&mdev->worker);
+
+	drbd_free_device(mdev);
+	drbd_put_minor(mdev_to_minor(mdev));
+	kfree(mdev);
+	module_put(THIS_MODULE);
+
+	return NoError;
 }
 
-drbd_dev *drbd_new_device(int minor)
+int drbd_create_device(int minor)
 {
-	drbd_dev *mdev = NULL;
-	struct gendisk *disk;
-	request_queue_t *q;
+	int rv = KMallocFailed;
+	drbd_dev *mdev;
 
+	if (!try_module_get(THIS_MODULE))
+		goto err0;
+
 	mdev = kzalloc(sizeof(drbd_dev),GFP_KERNEL);
-	if(!mdev) goto Enomem;
+	if (!mdev)
+		goto err1;
 
-	mdev->minor = minor;
+	rv = drbd_get_minor(mdev, minor);
+	if (rv != NoError)
+		goto err2;
 
-	drbd_init_set_defaults(mdev);
+	rv = drbd_alloc_device(mdev, minor);
+	if (rv != NoError)
+		goto err3;
 
-	q = blk_alloc_queue(GFP_KERNEL);
-	if (!q) goto Enomem;
-	mdev->rq_queue = q;
-	q->queuedata   = mdev;
-	q->max_segment_size = DRBD_MAX_SEGMENT_SIZE;
+	down(&drbd_devs_mutex);
+	drbd_list_add(mdev);
+	up(&drbd_devs_mutex);
 
-	disk = alloc_disk(1);
-	if (!disk) goto Enomem;
-	mdev->vdisk = disk;
+	// now any callback can be called
+	mdev->vdisk->private_data = mdev;
+	add_disk(mdev->vdisk);
+	return NoError;
 
-	set_disk_ro( disk, TRUE );
+err3:
+	drbd_put_minor(minor);
+err2:
+	kfree(mdev);
+err1:
+	module_put(THIS_MODULE);
+err0:
+	return rv;
+}
 
-	disk->queue = q;
-	disk->major = MAJOR_NR;
-	disk->first_minor = minor;
-	disk->fops = &drbd_ops;
-	sprintf(disk->disk_name, DEVICE_NAME "%d", minor);
-	disk->private_data = mdev;
-	add_disk(disk);
+STATIC void __exit drbd_cleanup(void)
+{
+	unregister_reboot_notifier(&drbd_notifier);
 
-	mdev->this_bdev = bdget(MKDEV(MAJOR_NR,minor));
-	// we have no partitions. we contain only ourselves.
-	mdev->this_bdev->bd_contains = mdev->this_bdev;
+	drbd_nl_cleanup();
 
-	blk_queue_make_request(q, drbd_make_request_26);
-	blk_queue_merge_bvec(q, drbd_merge_bvec);
-	q->queue_lock = &mdev->req_lock; // needed since we use
-		// plugging on a queue, that actually has no requests!
-	q->unplug_fn = drbd_unplug_fn;
+	if (drbd_proc)
+		remove_proc_entry("drbd",&proc_root);
 
-	mdev->md_io_page = alloc_page(GFP_KERNEL);
-	if(!mdev->md_io_page) goto Enomem;
+	if (unregister_blkdev(MAJOR_NR, DEVICE_NAME) != 0)
+		printk(KERN_ERR DEVICE_NAME": unregister of device failed\n");
 
-	if (drbd_bm_init(mdev)) goto Enomem;
-	// no need to lock access, we are still initializing the module.
-	if (!tl_init(mdev)) goto Enomem;
-
-	mdev->app_reads_hash=kzalloc(APP_R_HSIZE*sizeof(void*),GFP_KERNEL);
-	if (!mdev->app_reads_hash) goto Enomem;
-
-	return mdev;
-
- Enomem:
-	if(mdev) {
-		if(mdev->app_reads_hash) kfree(mdev->app_reads_hash);
-		if(mdev->md_io_page) __free_page(mdev->md_io_page);
-		kfree(mdev);
-	}
-	return NULL;
+	drbd_destroy_mempools();
+	
+	printk(KERN_INFO DEVICE_NAME": module cleanup done.\n");
 }
 
 int __init drbd_init(void)
@@ -2411,16 +2517,6 @@
 		return -EINVAL;
 	}
 
-	if (1 > minor_count||minor_count > 255) {
-		printk(KERN_ERR DEVICE_NAME
-			": invalid minor_count (%d)\n",minor_count);
-#ifdef MODULE
-		return -EINVAL;
-#else
-		minor_count = 8;
-#endif
-	}
-
 	if( (err = drbd_nl_init()) ) {
 		return err;
 	}
@@ -2438,13 +2534,8 @@
 	/*
 	 * allocate all necessary structs
 	 */
-	err = -ENOMEM;
-
-	init_waitqueue_head(&drbd_pp_wait);
-
+	err = -ENOMEM;	
 	drbd_proc = NULL; // play safe for drbd_cleanup
-	minor_table = kzalloc(sizeof(drbd_dev *)*minor_count,GFP_KERNEL);
-	if(!minor_table) goto Enomem;
 
 	if ((err = drbd_create_mempools()))
 		goto Enomem;
@@ -2471,7 +2562,6 @@
 	       API_VERSION,PRO_VERSION);
 	printk(KERN_INFO DEVICE_NAME ": %s\n", drbd_buildtag());
 	printk(KERN_INFO DEVICE_NAME": registered as block device major %d\n", MAJOR_NR);
-	printk(KERN_INFO DEVICE_NAME": minor_table @ 0x%p\n", minor_table);
 
 	return 0; // Success!
 

Modified: trunk/drbd/drbd_nl.c
===================================================================
--- trunk/drbd/drbd_nl.c	2007-05-22 13:13:37 UTC (rev 2903)
+++ trunk/drbd/drbd_nl.c	2007-05-22 13:21:56 UTC (rev 2904)
@@ -354,7 +354,22 @@
 	return r;
 }
 
+STATIC int drbd_nl_create(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			   struct drbd_nl_cfg_reply *reply)
+{
+	reply->ret_code = drbd_create_device(nlp->drbd_minor);
 
+	return 0;
+}
+
+STATIC int drbd_nl_remove(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+			   struct drbd_nl_cfg_reply *reply)
+{
+	reply->ret_code = drbd_remove_device(mdev);
+
+	return 0;
+}
+
 STATIC int drbd_nl_primary(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
 			   struct drbd_nl_cfg_reply *reply)
 {
@@ -1012,7 +1027,7 @@
 STATIC int drbd_nl_net_conf(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
 			    struct drbd_nl_cfg_reply *reply)
 {
-	int i,ns;
+	int ns;
 	enum ret_codes retcode;
 	struct net_conf *new_conf = NULL;
 	struct crypto_hash *tfm = NULL;
@@ -1020,6 +1035,7 @@
 	struct hlist_head *new_ee_hash = NULL;
 	drbd_dev *odev;
 	char hmac_name[HMAC_NAME_L];
+	struct list_head *p;
 
 	if (mdev->state.conn > StandAlone) {
 		retcode=HaveNetConfig;
@@ -1081,9 +1097,10 @@
 #define O_ADDR(A) (((struct sockaddr_in *)&A->peer_addr)->sin_addr.s_addr)
 #define O_PORT(A) (((struct sockaddr_in *)&A->peer_addr)->sin_port)
 	retcode = NoError;
-	for(i=0;i<minor_count;i++) {
-		odev = minor_to_mdev(i);
-		if(!odev || odev == mdev) continue;
+	down(&drbd_devs_mutex);
+	list_for_each(p, &drbd_devs_list) {
+		odev = list_entry(p, struct Drbd_Conf, devs_list);
+		if(odev == mdev) continue;
 		if( inc_net(odev)) {
 			if( M_ADDR(new_conf) == M_ADDR(odev->net_conf) &&
 			    M_PORT(new_conf) == M_PORT(odev->net_conf) ) {
@@ -1094,9 +1111,13 @@
 				retcode=OAAlreadyInUse;
 			}
 			dec_net(odev);
-			if(retcode != NoError) goto fail;
+			if(retcode != NoError) {
+				up(&drbd_devs_mutex);
+				goto fail;
+			}
 		}
 	}
+	up(&drbd_devs_mutex);
 #undef M_ADDR
 #undef M_PORT
 #undef O_ADDR
@@ -1521,27 +1542,10 @@
 
 STATIC drbd_dev *ensure_mdev(struct drbd_nl_cfg_req *nlp)
 {
-	drbd_dev *mdev;
+	drbd_dev *mdev = minor_to_mdev(nlp->drbd_minor);
 
-	mdev = minor_to_mdev(nlp->drbd_minor);
-
-	if(!mdev && (nlp->flags & DRBD_NL_CREATE_DEVICE)) {
-		mdev = drbd_new_device(nlp->drbd_minor);
-
-		spin_lock_irq(&drbd_pp_lock);
-		if( minor_table[nlp->drbd_minor] == NULL) {
-			minor_table[nlp->drbd_minor] = mdev;
-			mdev = NULL;
-		}
-		spin_unlock_irq(&drbd_pp_lock);
-
-		if(mdev) {
-			if(mdev->app_reads_hash) kfree(mdev->app_reads_hash);
-			if(mdev->md_io_page) __free_page(mdev->md_io_page);
-			kfree(mdev);
-			mdev = NULL;
-		}
-
+	if(!mdev && (nlp->flags & DRBD_NL_CREATE_DEVICE)) { 
+		drbd_create_device(nlp->drbd_minor);
 		mdev = minor_to_mdev(nlp->drbd_minor);
 	}
 
@@ -1556,6 +1560,8 @@
 };
 
 static struct cn_handler_struct cnd_table[] = {
+	[ P_create ]		= { &drbd_nl_create,		0 },
+	[ P_remove ]		= { &drbd_nl_remove,		0 },
 	[ P_primary ]		= { &drbd_nl_primary,		0 },
 	[ P_secondary ]		= { &drbd_nl_secondary,		0 },
 	[ P_disk_conf ]		= { &drbd_nl_disk_conf,		0 },
@@ -1591,7 +1597,7 @@
 	struct cn_handler_struct *cm;
 	struct cn_msg *cn_reply;
 	struct drbd_nl_cfg_reply* reply;
-	drbd_dev *mdev;
+	drbd_dev *mdev = NULL;
 	int retcode,rr;
 	int reply_size = sizeof(struct cn_msg)
 		+ sizeof(struct drbd_nl_cfg_reply)
@@ -1601,10 +1607,13 @@
 		printk(KERN_ERR DEVICE_NAME "try_module_get() failed!\n");
 		return;
 	}
-
-	if( !(mdev = ensure_mdev(nlp)) ) {
-		retcode=MinorNotKnown;
-		goto fail;
+	
+	if (nlp->packet_type != P_create) {
+		mdev = ensure_mdev(nlp);
+		if (!mdev) {
+			retcode = MinorNotKnown;
+			goto fail;
+		}
 	}
 
 	TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_packet(data););

Modified: trunk/drbd/drbd_proc.c
===================================================================
--- trunk/drbd/drbd_proc.c	2007-05-22 13:13:37 UTC (rev 2903)
+++ trunk/drbd/drbd_proc.c	2007-05-22 13:21:56 UTC (rev 2904)
@@ -172,9 +172,9 @@
 
 STATIC int drbd_seq_show(struct seq_file *seq, void *v)
 {
-	int i,hole=0;
 	const char *sn;
 	drbd_dev *mdev;
+	struct list_head *p;
 
 	seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d)\n%s\n",
 		    API_VERSION,PRO_VERSION, drbd_buildtag());
@@ -192,28 +192,22 @@
 	  al .. access log write count
 	*/
 
-	for (i = 0; i < minor_count; i++) {
-		mdev = minor_to_mdev(i);
-		if(!mdev) {
-			hole=1;
-			continue;
-		}
-		if( hole ) {
-			hole=0;
-			seq_printf( seq, "\n");
-		}
+	down(&drbd_devs_mutex);
+	list_for_each(p, &drbd_devs_list) {
+		mdev = list_entry(p, struct Drbd_Conf, devs_list);
 
 		sn = conns_to_name(mdev->state.conn);
 
 		if ( mdev->state.conn == StandAlone &&
 		     mdev->state.disk == Diskless) {
-			seq_printf( seq, "%2d: cs:Unconfigured\n", i);
+			seq_printf( seq, "%2d: cs:Unconfigured\n",
+			  mdev_to_minor(mdev));
 		} else {
 			seq_printf( seq,
 			   "%2d: cs:%s st:%s/%s ds:%s/%s %c %c%c%c%c\n"
 			   "    ns:%u nr:%u dw:%u dr:%u al:%u bm:%u "
 			   "lo:%d pe:%d ua:%d ap:%d\n",
-			   i, sn,
+			   mdev_to_minor(mdev), sn,
 			   roles_to_name(mdev->state.role),
 			   roles_to_name(mdev->state.peer),
 			   disks_to_name(mdev->state.disk),
@@ -255,7 +249,7 @@
 #endif
 
 	}
-
+	up(&drbd_devs_mutex);
 	return 0;
 }
 

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2007-05-22 13:13:37 UTC (rev 2903)
+++ trunk/drbd/drbd_receiver.c	2007-05-22 13:21:56 UTC (rev 2904)
@@ -194,7 +194,7 @@
 	int free_it;
 
 	spin_lock_irqsave(&drbd_pp_lock,flags);
-	if (drbd_pp_vacant > (DRBD_MAX_SEGMENT_SIZE/PAGE_SIZE)*minor_count) {
+	if (drbd_pp_vacant > (DRBD_MAX_SEGMENT_SIZE/PAGE_SIZE)*prealloc_segments) {
 		free_it = 1;
 	} else {
 		set_page_private(page, (unsigned long)drbd_pp_pool);

Modified: trunk/drbd/drbd_req.c
===================================================================
--- trunk/drbd/drbd_req.c	2007-05-22 13:13:37 UTC (rev 2903)
+++ trunk/drbd/drbd_req.c	2007-05-22 13:21:56 UTC (rev 2904)
@@ -1099,7 +1099,8 @@
 		/* rather error out here than BUG in bio_split */
 		ERR("bio would need to, but cannot, be split: "
 		    "(vcnt=%u,idx=%u,size=%u,sector=%llu)\n",
-		    bio->bi_vcnt, bio->bi_idx, bio->bi_size, bio->bi_sector);
+		    bio->bi_vcnt, bio->bi_idx, bio->bi_size,
+		    (unsigned long long) bio->bi_sector);
 		bio_endio(bio, bio->bi_size, -EINVAL);
 		return 0;
 	} else {

Modified: trunk/drbd/drbd_worker.c
===================================================================
--- trunk/drbd/drbd_worker.c	2007-05-22 13:13:37 UTC (rev 2903)
+++ trunk/drbd/drbd_worker.c	2007-05-22 13:21:56 UTC (rev 2904)
@@ -714,11 +714,12 @@
 STATIC void drbd_global_lock(void)
 {
 	drbd_dev *mdev;
-	int i;
+	struct list_head *p;
 
+	down(&drbd_devs_mutex);
 	local_irq_disable();
-	for (i=0; i < minor_count; i++) {
-		if(!(mdev = minor_to_mdev(i))) continue;
+	list_for_each(p, &drbd_devs_list) {
+		mdev = list_entry(p, struct Drbd_Conf, devs_list);
 		spin_lock(&mdev->req_lock);
 	}
 }
@@ -726,13 +727,14 @@
 STATIC void drbd_global_unlock(void)
 {
 	drbd_dev *mdev;
-	int i;
+	struct list_head *p;
 
-	for (i=0; i < minor_count; i++) {
-		if(!(mdev = minor_to_mdev(i))) continue;
+	list_for_each(p, &drbd_devs_list) {
+		mdev = list_entry(p, struct Drbd_Conf, devs_list);
 		spin_unlock(&mdev->req_lock);
 	}
 	local_irq_enable();
+	up(&drbd_devs_mutex);;
 }
 
 STATIC int _drbd_may_sync_now(drbd_dev *mdev)
@@ -759,10 +761,11 @@
 STATIC int _drbd_pause_after(drbd_dev *mdev)
 {
 	drbd_dev *odev;
-	int i, rv = 0;
+	struct list_head *p;
+	int rv = 0;
 
-	for (i=0; i < minor_count; i++) {
-		if( !(odev = minor_to_mdev(i)) ) continue;
+	list_for_each(p, &drbd_devs_list) {
+		odev = list_entry(p, struct Drbd_Conf, devs_list); 
 		if (! _drbd_may_sync_now(odev)) {
 			rv |= ( _drbd_set_state(_NS(odev,aftr_isp,1),
 						ChgStateHard|ScheduleAfter)
@@ -782,10 +785,11 @@
 STATIC int _drbd_resume_next(drbd_dev *mdev)
 {
 	drbd_dev *odev;
-	int i, rv = 0;
+	struct list_head *p;
+	int rv = 0;
 
-	for (i=0; i < minor_count; i++) {
-		if( !(odev = minor_to_mdev(i)) ) continue;
+	list_for_each(p, &drbd_devs_list) {
+		odev = list_entry(p, struct Drbd_Conf, devs_list);
 		if ( odev->state.aftr_isp ) {
 			if (_drbd_may_sync_now(odev)) {
 				rv |= ( _drbd_set_state(_NS(odev,aftr_isp,0),

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2007-05-22 13:13:37 UTC (rev 2903)
+++ trunk/drbd/linux/drbd.h	2007-05-22 13:21:56 UTC (rev 2904)
@@ -114,6 +114,9 @@
 	ProtocolCRequired,
 	PreHeatAndTwoPrimaries,
 
+	MinorInUse,
+	MinorInvalid,
+
 	/* insert new ones above this line */
 	AfterLastRetCode
 };

Modified: trunk/drbd/linux/drbd_nl.h
===================================================================
--- trunk/drbd/linux/drbd_nl.h	2007-05-22 13:13:37 UTC (rev 2903)
+++ trunk/drbd/linux/drbd_nl.h	2007-05-22 13:21:56 UTC (rev 2904)
@@ -91,6 +91,9 @@
 	STRING(		38,	T_MAY_IGNORE,	helper,		32)
 )
 
+PACKET(create, 21, )
+PACKET(remove, 22, )
+
 #undef PACKET
 #undef INTEGER
 #undef INT64

Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c	2007-05-22 13:13:37 UTC (rev 2903)
+++ trunk/user/drbdadm_main.c	2007-05-22 13:21:56 UTC (rev 2904)
@@ -85,6 +85,7 @@
 extern int yydebug;
 extern FILE* yyin;
 
+int adm_create(struct d_resource* ,const char* );
 int adm_attach(struct d_resource* ,const char* );
 int adm_connect(struct d_resource* ,const char* );
 int adm_generic_s(struct d_resource* ,const char* );
@@ -134,7 +135,7 @@
 int soi=0;
 volatile int alarm_raised;
 
-struct deferred_cmd *deferred_cmds[3] = { NULL, NULL, NULL };
+struct deferred_cmd *deferred_cmds[4] = { NULL, NULL, NULL, NULL };
 
 void schedule_dcmd( int (* function)(struct d_resource*,const char* ),
 		    struct d_resource* res,
@@ -180,7 +181,8 @@
 {
   return _run_dcmds(deferred_cmds[0]) ||
     _run_dcmds(deferred_cmds[1]) ||
-    _run_dcmds(deferred_cmds[2]);
+    _run_dcmds(deferred_cmds[2]) ||
+    _run_dcmds(deferred_cmds[3]);
 }
 
 struct option admopt[] = {
@@ -194,6 +196,8 @@
 
 struct adm_cmd cmds[] = {
 /*   name, function,                  show, needs res, verify_ips */
+  { "create",		 adm_create,    1,1,0 },
+  { "remove",		 adm_generic_s, 1,1,0 },
   { "attach",            adm_attach,    1,1,0 },
   { "detach",            adm_generic_s, 1,1,0 },
   { "connect",           adm_connect,   1,1,1 },
@@ -759,6 +763,19 @@
     OPT=OPT->next; \
   }
 
+int adm_create(struct d_resource* res,const char* unused __attribute((unused)))
+{
+  char* argv[MAX_ARGS];
+  int argc=0;
+
+  argv[NA(argc)]=drbdsetup;
+  argv[NA(argc)]=res->me->device;
+  argv[NA(argc)]="create";
+  argv[NA(argc)]=0;
+
+  return m_system(argv,SLEEPS_LONG);
+}
+
 int adm_attach(struct d_resource* res,const char* unused __attribute((unused)))
 {
   char* argv[MAX_ARGS];
@@ -995,9 +1012,10 @@
 
 static int adm_up(struct d_resource* res,const char* unused __attribute((unused)))
 {
-  schedule_dcmd(adm_attach,res,NULL,0);
-  schedule_dcmd(adm_syncer,res,NULL,1);
-  schedule_dcmd(adm_connect,res,NULL,2);
+  schedule_dcmd(adm_create,res,NULL,0);
+  schedule_dcmd(adm_attach,res,NULL,1);
+  schedule_dcmd(adm_syncer,res,NULL,2);
+  schedule_dcmd(adm_connect,res,NULL,3);
 
   return 0;
 }

Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2007-05-22 13:13:37 UTC (rev 2903)
+++ trunk/user/drbdsetup.c	2007-05-22 13:21:56 UTC (rev 2904)
@@ -348,6 +348,8 @@
 		wait_cmds_options, w_connected_state } } },
 	{"wait-sync", 0, F_EVENTS_CMD, { .ep = {
 		wait_cmds_options, w_synced_state } } },
+	{"create", P_create, F_CONFIG_CMD, {{NULL, NULL}}},
+	{"remove", P_remove, F_CONFIG_CMD, {{NULL, NULL}}},
 };
 
 #define EM(C) [ C - RetCodeBase ]
@@ -396,7 +398,9 @@
 	EM(HaveNoDiskConfig) = "Device does not have a disk-config",
 	EM(ProtocolCRequired) = "Protocol C required",
 	EM(PreHeatAndTwoPrimaries) = "Preheat-cache and allow-two-primaries"
-	"may not be set concurrently"
+	"may not be set concurrently",
+ 	EM(MinorInUse) = "Minor number in use.",
+ 	EM(MinorInvalid) = "Minor number invalid."
 };
 #define MAX_ERROR (sizeof(error_messages)/sizeof(*error_messages))
 const char * error_to_string(int err_no)
@@ -1173,11 +1177,17 @@
 	cm = find_cmd_by_name("secondary");
 	rv = cm->function(cm,minor,argc,argv);
 	if( rv ) return rv;
+
 	cm = find_cmd_by_name("disconnect");
-	cm->function(cm,minor,argc,argv);
+	rv = cm->function(cm,minor,argc,argv);	
+	if ( rv ) return rv;
+
 	cm = find_cmd_by_name("detach");
-	rv |= cm->function(cm,minor,argc,argv);
+	rv = cm->function(cm,minor,argc,argv);
+	if( rv ) return rv;
 
+	cm = find_cmd_by_name("remove");
+	rv = cm->function(cm,minor,argc,argv);
 	return rv;
 }
 

From drbd-cvs at lists.linbit.com  Tue May 22 17:09:14 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue May 22 17:09:16 2007
Subject: [DRBD-cvs] svn commit by rasto - r2905 - trunk/user - dump xml fix 
Message-ID: <20070522150914.D96B02E089B8@mail.linbit.com>

Author: rasto
Date: 2007-05-22 17:09:13 +0200 (Tue, 22 May 2007)
New Revision: 2905

Modified:
   trunk/user/drbdadm_main.c
Log:
dump xml fix


Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c	2007-05-22 13:21:56 UTC (rev 2904)
+++ trunk/user/drbdadm_main.c	2007-05-22 15:09:13 UTC (rev 2905)
@@ -401,13 +401,13 @@
   if (  !global_options.minor_count
      && !global_options.disable_ip_verification
      &&  global_options.dialog_refresh == 1 ) return;
-  printI("<global>"); ++indent;
+  printI("<global>\n"); ++indent;
   if (global_options.disable_ip_verification)
     printI("<disable-ip-verification/>\n");
   if (global_options.minor_count)
     printI("<minor-count count=\"%i\"/>\n", global_options.minor_count);
   if (global_options.dialog_refresh != 1)
-    printI("<dialog-refresh=\"%i\"\n", global_options.dialog_refresh);
+    printI("<dialog-refresh refresh=\"%i\"/>\n", global_options.dialog_refresh);
   --indent; printI("</global>\n");
 }
 

From drbd-cvs at lists.linbit.com  Wed May 23 14:55:42 2007
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed May 23 14:55:44 2007
Subject: [DRBD-cvs] svn commit by rasto - r2906 - branches/drbd-8.0/user -
	fix in dump xml 
Message-ID: <20070523125543.1B9FA2E051BE@mail.linbit.com>

Author: rasto
Date: 2007-05-23 14:55:41 +0200 (Wed, 23 May 2007)
New Revision: 2906

Modified:
   branches/drbd-8.0/user/drbdadm_main.c
Log:
fix in dump xml


Modified: branches/drbd-8.0/user/drbdadm_main.c
===================================================================
--- branches/drbd-8.0/user/drbdadm_main.c	2007-05-22 15:09:13 UTC (rev 2905)
+++ branches/drbd-8.0/user/drbdadm_main.c	2007-05-23 12:55:41 UTC (rev 2906)
@@ -397,13 +397,13 @@
   if (  !global_options.minor_count
      && !global_options.disable_ip_verification
      &&  global_options.dialog_refresh == 1 ) return;
-  printI("<global>"); ++indent;
+  printI("<global>\n"); ++indent;
   if (global_options.disable_ip_verification)
     printI("<disable-ip-verification/>\n");
   if (global_options.minor_count)
     printI("<minor-count count=\"%i\"/>\n", global_options.minor_count);
   if (global_options.dialog_refresh != 1)
-    printI("<dialog-refresh=\"%i\"\n", global_options.dialog_refresh);
+    printI("<dialog-refresh refresh=\"%i\"/>\n", global_options.dialog_refresh);
   --indent; printI("</global>\n");
 }
 

