diff options
-rw-r--r-- | drivers/block/drbd/drbd_req.c | 30 |
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 | ||