drbd: Actually send delay probes
[safe/jmp/linux-2.6] / drivers / block / drbd / drbd_main.c
index 710bfeb..98785d0 100644 (file)
@@ -2207,10 +2207,13 @@ static int drbd_send_delay_probe(struct drbd_conf *mdev, struct drbd_socket *ds)
        }
        mutex_unlock(&ds->mutex);
 
+       mdev->dp_volume_last = mdev->send_cnt;
+       mod_timer(&mdev->delay_probe_timer, jiffies + mdev->sync_conf.dp_interval * HZ / 10);
+
        return ok;
 }
 
-static int drbd_send_dalay_probes(struct drbd_conf *mdev)
+static int drbd_send_delay_probes(struct drbd_conf *mdev)
 {
        int ok;
        atomic_inc(&mdev->delay_seq);
@@ -2350,6 +2353,30 @@ static int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio)
        return 1;
 }
 
+static void consider_delay_probes(struct drbd_conf *mdev)
+{
+       if (mdev->state.conn != C_SYNC_SOURCE)
+               return;
+
+       if (mdev->dp_volume_last + mdev->sync_conf.dp_volume * 2 < mdev->send_cnt)
+               drbd_send_delay_probes(mdev);
+}
+
+static int w_delay_probes(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+{
+       if (!cancel && mdev->state.conn == C_SYNC_SOURCE)
+               drbd_send_delay_probes(mdev);
+
+       return 1;
+}
+
+static void delay_probe_timer_fn(unsigned long data)
+{
+       struct drbd_conf *mdev = (struct drbd_conf *) data;
+
+       drbd_queue_work(&mdev->data.work, &mdev->delay_probe_work);
+}
+
 /* Used to send write requests
  * R_PRIMARY -> Peer   (P_DATA)
  */
@@ -2412,6 +2439,10 @@ int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req)
        }
 
        drbd_put_data_sock(mdev);
+
+       if (ok)
+               consider_delay_probes(mdev);
+
        return ok;
 }
 
@@ -2457,6 +2488,10 @@ int drbd_send_block(struct drbd_conf *mdev, enum drbd_packets cmd,
                ok = _drbd_send_zc_bio(mdev, e->private_bio);
 
        drbd_put_data_sock(mdev);
+
+       if (ok)
+               consider_delay_probes(mdev);
+
        return ok;
 }
 
@@ -2671,17 +2706,23 @@ void drbd_init_set_defaults(struct drbd_conf *mdev)
        INIT_LIST_HEAD(&mdev->md_sync_work.list);
        INIT_LIST_HEAD(&mdev->bm_io_work.w.list);
        INIT_LIST_HEAD(&mdev->delay_probes);
+       INIT_LIST_HEAD(&mdev->delay_probe_work.list);
 
        mdev->resync_work.cb  = w_resync_inactive;
        mdev->unplug_work.cb  = w_send_write_hint;
        mdev->md_sync_work.cb = w_md_sync;
        mdev->bm_io_work.w.cb = w_bitmap_io;
+       mdev->delay_probe_work.cb = w_delay_probes;
        init_timer(&mdev->resync_timer);
        init_timer(&mdev->md_sync_timer);
+       init_timer(&mdev->delay_probe_timer);
        mdev->resync_timer.function = resync_timer_fn;
        mdev->resync_timer.data = (unsigned long) mdev;
        mdev->md_sync_timer.function = md_sync_timer_fn;
        mdev->md_sync_timer.data = (unsigned long) mdev;
+       mdev->delay_probe_timer.function = delay_probe_timer_fn;
+       mdev->delay_probe_timer.data = (unsigned long) mdev;
+
 
        init_waitqueue_head(&mdev->misc_wait);
        init_waitqueue_head(&mdev->state_wait);