diff options
author | Lars Ellenberg <lars.ellenberg@linbit.com> | 2013-03-19 13:16:54 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2013-03-22 20:15:17 -0400 |
commit | 779b3fe4c0e9dea19ae3ddef0b5fd1a663b63ee6 (patch) | |
tree | c750af98a46675531e7a40c6d1e1061382dc2b1a /drivers/block/drbd | |
parent | 6c3c4355d6bfa418db828684e67910c559402264 (diff) |
drbd: queue writes on submitter thread, unless they pass the activity log fastpath
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block/drbd')
-rw-r--r-- | drivers/block/drbd/drbd_req.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 4af709e0aae5..43bc1d064bc7 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
@@ -1020,6 +1020,14 @@ drbd_submit_req_private_bio(struct drbd_request *req) | |||
1020 | bio_endio(bio, -EIO); | 1020 | bio_endio(bio, -EIO); |
1021 | } | 1021 | } |
1022 | 1022 | ||
1023 | static void drbd_queue_write(struct drbd_conf *mdev, struct drbd_request *req) | ||
1024 | { | ||
1025 | spin_lock(&mdev->submit.lock); | ||
1026 | list_add_tail(&req->tl_requests, &mdev->submit.writes); | ||
1027 | spin_unlock(&mdev->submit.lock); | ||
1028 | queue_work(mdev->submit.wq, &mdev->submit.worker); | ||
1029 | } | ||
1030 | |||
1023 | /* returns the new drbd_request pointer, if the caller is expected to | 1031 | /* returns the new drbd_request pointer, if the caller is expected to |
1024 | * drbd_send_and_submit() it (to save latency), or NULL if we queued the | 1032 | * drbd_send_and_submit() it (to save latency), or NULL if we queued the |
1025 | * request on the submitter thread. | 1033 | * request on the submitter thread. |
@@ -1048,17 +1056,13 @@ drbd_request_prepare(struct drbd_conf *mdev, struct bio *bio, unsigned long star | |||
1048 | req->private_bio = NULL; | 1056 | req->private_bio = NULL; |
1049 | } | 1057 | } |
1050 | 1058 | ||
1051 | /* For WRITES going to the local disk, grab a reference on the target | ||
1052 | * extent. This waits for any resync activity in the corresponding | ||
1053 | * resync extent to finish, and, if necessary, pulls in the target | ||
1054 | * extent into the activity log, which involves further disk io because | ||
1055 | * of transactional on-disk meta data updates. | ||
1056 | * Empty flushes don't need to go into the activity log, they can only | ||
1057 | * flush data for pending writes which are already in there. */ | ||
1058 | if (rw == WRITE && req->private_bio && req->i.size | 1059 | if (rw == WRITE && req->private_bio && req->i.size |
1059 | && !test_bit(AL_SUSPENDED, &mdev->flags)) { | 1060 | && !test_bit(AL_SUSPENDED, &mdev->flags)) { |
1061 | if (!drbd_al_begin_io_fastpath(mdev, &req->i)) { | ||
1062 | drbd_queue_write(mdev, req); | ||
1063 | return NULL; | ||
1064 | } | ||
1060 | req->rq_state |= RQ_IN_ACT_LOG; | 1065 | req->rq_state |= RQ_IN_ACT_LOG; |
1061 | drbd_al_begin_io(mdev, &req->i, true); | ||
1062 | } | 1066 | } |
1063 | 1067 | ||
1064 | return req; | 1068 | return req; |