aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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