diff options
Diffstat (limited to 'drivers/block/drbd/drbd_req.c')
-rw-r--r-- | drivers/block/drbd/drbd_req.c | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 910335c30927..01b2ac641c7b 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
@@ -695,6 +695,12 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, | |||
695 | break; | 695 | break; |
696 | 696 | ||
697 | case resend: | 697 | case resend: |
698 | /* Simply complete (local only) READs. */ | ||
699 | if (!(req->rq_state & RQ_WRITE) && !req->w.cb) { | ||
700 | _req_may_be_done(req, m); | ||
701 | break; | ||
702 | } | ||
703 | |||
698 | /* If RQ_NET_OK is already set, we got a P_WRITE_ACK or P_RECV_ACK | 704 | /* If RQ_NET_OK is already set, we got a P_WRITE_ACK or P_RECV_ACK |
699 | before the connection loss (B&C only); only P_BARRIER_ACK was missing. | 705 | before the connection loss (B&C only); only P_BARRIER_ACK was missing. |
700 | Trowing them out of the TL here by pretending we got a BARRIER_ACK | 706 | Trowing them out of the TL here by pretending we got a BARRIER_ACK |
@@ -834,7 +840,15 @@ static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, uns | |||
834 | req->private_bio = NULL; | 840 | req->private_bio = NULL; |
835 | } | 841 | } |
836 | if (rw == WRITE) { | 842 | if (rw == WRITE) { |
837 | remote = 1; | 843 | /* Need to replicate writes. Unless it is an empty flush, |
844 | * which is better mapped to a DRBD P_BARRIER packet, | ||
845 | * also for drbd wire protocol compatibility reasons. */ | ||
846 | if (unlikely(size == 0)) { | ||
847 | /* The only size==0 bios we expect are empty flushes. */ | ||
848 | D_ASSERT(bio->bi_rw & REQ_FLUSH); | ||
849 | remote = 0; | ||
850 | } else | ||
851 | remote = 1; | ||
838 | } else { | 852 | } else { |
839 | /* READ || READA */ | 853 | /* READ || READA */ |
840 | if (local) { | 854 | if (local) { |
@@ -870,8 +884,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 | 884 | * extent. This waits for any resync activity in the corresponding |
871 | * resync extent to finish, and, if necessary, pulls in the target | 885 | * resync extent to finish, and, if necessary, pulls in the target |
872 | * extent into the activity log, which involves further disk io because | 886 | * extent into the activity log, which involves further disk io because |
873 | * of transactional on-disk meta data updates. */ | 887 | * of transactional on-disk meta data updates. |
874 | if (rw == WRITE && local && !test_bit(AL_SUSPENDED, &mdev->flags)) { | 888 | * Empty flushes don't need to go into the activity log, they can only |
889 | * flush data for pending writes which are already in there. */ | ||
890 | if (rw == WRITE && local && size | ||
891 | && !test_bit(AL_SUSPENDED, &mdev->flags)) { | ||
875 | req->rq_state |= RQ_IN_ACT_LOG; | 892 | req->rq_state |= RQ_IN_ACT_LOG; |
876 | drbd_al_begin_io(mdev, sector); | 893 | drbd_al_begin_io(mdev, sector); |
877 | } | 894 | } |
@@ -994,7 +1011,10 @@ allocate_barrier: | |||
994 | if (rw == WRITE && _req_conflicts(req)) | 1011 | if (rw == WRITE && _req_conflicts(req)) |
995 | goto fail_conflicting; | 1012 | goto fail_conflicting; |
996 | 1013 | ||
997 | list_add_tail(&req->tl_requests, &mdev->newest_tle->requests); | 1014 | /* no point in adding empty flushes to the transfer log, |
1015 | * they are mapped to drbd barriers already. */ | ||
1016 | if (likely(size!=0)) | ||
1017 | list_add_tail(&req->tl_requests, &mdev->newest_tle->requests); | ||
998 | 1018 | ||
999 | /* NOTE remote first: to get the concurrent write detection right, | 1019 | /* NOTE remote first: to get the concurrent write detection right, |
1000 | * we must register the request before start of local IO. */ | 1020 | * we must register the request before start of local IO. */ |
@@ -1014,6 +1034,14 @@ allocate_barrier: | |||
1014 | mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) | 1034 | mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) |
1015 | maybe_pull_ahead(mdev); | 1035 | maybe_pull_ahead(mdev); |
1016 | 1036 | ||
1037 | /* If this was a flush, queue a drbd barrier/start a new epoch. | ||
1038 | * Unless the current epoch was empty anyways, or we are not currently | ||
1039 | * replicating, in which case there is no point. */ | ||
1040 | if (unlikely(bio->bi_rw & REQ_FLUSH) | ||
1041 | && mdev->newest_tle->n_writes | ||
1042 | && drbd_should_do_remote(mdev->state)) | ||
1043 | queue_barrier(mdev); | ||
1044 | |||
1017 | spin_unlock_irq(&mdev->req_lock); | 1045 | spin_unlock_irq(&mdev->req_lock); |
1018 | kfree(b); /* if someone else has beaten us to it... */ | 1046 | kfree(b); /* if someone else has beaten us to it... */ |
1019 | 1047 | ||