drbd: Run the fence-peer helper asynchronously
authorPhilipp Reisner <philipp.reisner@linbit.com>
Fri, 11 Jun 2010 11:56:33 +0000 (13:56 +0200)
committerPhilipp Reisner <philipp.reisner@linbit.com>
Thu, 14 Oct 2010 12:58:36 +0000 (14:58 +0200)
Since we can not thaw the transfer log, the next logical step is
to allow reconnects while the fence-peer handler runs.

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_nl.c
drivers/block/drbd/drbd_receiver.c

index 03cc975b9e6cb366b5a6345a19fe00fae9b8640b..ab20c0062d2119e67acfe934e882016092211465 100644 (file)
@@ -1423,7 +1423,8 @@ extern void resync_after_online_grow(struct drbd_conf *);
 extern void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int) __must_hold(local);
 extern int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role,
                int force);
-enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev);
+extern enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev);
+extern void drbd_try_outdate_peer_async(struct drbd_conf *mdev);
 extern int drbd_khelper(struct drbd_conf *mdev, char *cmd);
 
 /* drbd_worker.c */
index cda7cb3202b9bc86791a8125558bc9d0a0687657..32d00720470ba4b2277d3dc3088ec89207452aab 100644 (file)
@@ -38,6 +38,8 @@
 #include <asm/unaligned.h>
 #include <linux/drbd_tag_magic.h>
 #include <linux/drbd_limits.h>
+#include <linux/compiler.h>
+#include <linux/kthread.h>
 
 static unsigned short *tl_add_blob(unsigned short *, enum drbd_tags, const void *, int);
 static unsigned short *tl_add_str(unsigned short *, enum drbd_tags, const char *);
@@ -256,6 +258,25 @@ enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev)
        return nps;
 }
 
+static int _try_outdate_peer_async(void *data)
+{
+       struct drbd_conf *mdev = (struct drbd_conf *)data;
+       enum drbd_disk_state nps;
+
+       nps = drbd_try_outdate_peer(mdev);
+       drbd_request_state(mdev, NS(pdsk, nps));
+
+       return 0;
+}
+
+void drbd_try_outdate_peer_async(struct drbd_conf *mdev)
+{
+       struct task_struct *opa;
+
+       opa = kthread_run(_try_outdate_peer_async, mdev, "drbd%d_a_helper", mdev_to_minor(mdev));
+       if (IS_ERR(opa))
+               dev_err(DEV, "out of mem, failed to invoke fence-peer helper\n");
+}
 
 int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force)
 {
index 72bc1a130645827174cafe5767bf08889b9cab95..101ad186244cf0a86dc513c537f336288bca88a1 100644 (file)
@@ -3747,12 +3747,8 @@ static void drbd_disconnect(struct drbd_conf *mdev)
                put_ldev(mdev);
        }
 
-       if (mdev->state.role == R_PRIMARY) {
-               if (fp >= FP_RESOURCE && mdev->state.pdsk >= D_UNKNOWN) {
-                       enum drbd_disk_state nps = drbd_try_outdate_peer(mdev);
-                       drbd_request_state(mdev, NS(pdsk, nps));
-               }
-       }
+       if (mdev->state.role == R_PRIMARY && fp >= FP_RESOURCE && mdev->state.pdsk >= D_UNKNOWN)
+               drbd_try_outdate_peer_async(mdev);
 
        spin_lock_irq(&mdev->req_lock);
        os = mdev->state;