aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2012-07-31 03:31:11 -0400
committerPhilipp Reisner <philipp.reisner@linbit.com>2012-08-16 11:12:56 -0400
commit227f052f4711caf432b9a7dbcfe1a2857d3c0def (patch)
treea8e7a59fbe8a8c9d5e0ecbe76db9a9c769fd7e30 /drivers
parenta73ff3231df59a4b92ccd0dd4e73897c5822489b (diff)
drbd: fix drbd wire compatibility for empty flushes
DRBD has a concept of request epochs or reorder-domains, which are separated on the wire by P_BARRIER packets. Older DRBD is not able to handle zero-sized requests at all, so we need to map empty flushes to these drbd barriers. These are the equivalent of empty flushes, and by default trigger flushes on the receiving side anyways (unless not supported or explicitly disabled), so there is no need to handle this differently in newer drbd either. Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com> Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/drbd/drbd_req.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 910335c30927..0bb1e41f136f 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -834,7 +834,15 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns
834 req->private_bio = NULL; 834 req->private_bio = NULL;
835 } 835 }
836 if (rw == WRITE) { 836 if (rw == WRITE) {
837 remote = 1; 837 /* Need to replicate writes. Unless it is an empty flush,
838 * which is better mapped to a DRBD P_BARRIER packet,
839 * also for drbd wire protocol compatibility reasons. */
840 if (unlikely(size == 0)) {
841 /* The only size==0 bios we expect are empty flushes. */
842 D_ASSERT(bio->bi_rw & REQ_FLUSH);
843 remote = 0;
844 } else
845 remote = 1;
838 } else { 846 } else {
839 /* READ || READA */ 847 /* READ || READA */
840 if (local) { 848 if (local) {
@@ -870,8 +878,11 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns
870 * extent. This waits for any resync activity in the corresponding 878 * extent. This waits for any resync activity in the corresponding
871 * resync extent to finish, and, if necessary, pulls in the target 879 * resync extent to finish, and, if necessary, pulls in the target
872 * extent into the activity log, which involves further disk io because 880 * extent into the activity log, which involves further disk io because
873 * of transactional on-disk meta data updates. */ 881 * of transactional on-disk meta data updates.
874 if (rw == WRITE && local && !test_bit(AL_SUSPENDED, &mdev->flags)) { 882 * Empty flushes don't need to go into the activity log, they can only
883 * flush data for pending writes which are already in there. */
884 if (rw == WRITE && local && size
885 && !test_bit(AL_SUSPENDED, &mdev->flags)) {
875 req->rq_state |= RQ_IN_ACT_LOG; 886 req->rq_state |= RQ_IN_ACT_LOG;
876 drbd_al_begin_io(mdev, sector); 887 drbd_al_begin_io(mdev, sector);
877 } 888 }
@@ -994,7 +1005,10 @@ allocate_barrier:
994 if (rw == WRITE && _req_conflicts(req)) 1005 if (rw == WRITE && _req_conflicts(req))
995 goto fail_conflicting; 1006 goto fail_conflicting;
996 1007
997 list_add_tail(&req->tl_requests, &mdev->newest_tle->requests); 1008 /* no point in adding empty flushes to the transfer log,
1009 * they are mapped to drbd barriers already. */
1010 if (likely(size!=0))
1011 list_add_tail(&req->tl_requests, &mdev->newest_tle->requests);
998 1012
999 /* NOTE remote first: to get the concurrent write detection right, 1013 /* NOTE remote first: to get the concurrent write detection right,
1000 * we must register the request before start of local IO. */ 1014 * we must register the request before start of local IO. */
@@ -1014,6 +1028,14 @@ allocate_barrier:
1014 mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) 1028 mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96)
1015 maybe_pull_ahead(mdev); 1029 maybe_pull_ahead(mdev);
1016 1030
1031 /* If this was a flush, queue a drbd barrier/start a new epoch.
1032 * Unless the current epoch was empty anyways, or we are not currently
1033 * replicating, in which case there is no point. */
1034 if (unlikely(bio->bi_rw & REQ_FLUSH)
1035 && mdev->newest_tle->n_writes
1036 && drbd_should_do_remote(mdev->state))
1037 queue_barrier(mdev);
1038
1017 spin_unlock_irq(&mdev->req_lock); 1039 spin_unlock_irq(&mdev->req_lock);
1018 kfree(b); /* if someone else has beaten us to it... */ 1040 kfree(b); /* if someone else has beaten us to it... */
1019 1041