diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2011-01-28 04:31:04 -0500 |
---|---|---|
committer | Philipp Reisner <philipp.reisner@linbit.com> | 2011-09-28 04:26:31 -0400 |
commit | 53840641bb1feff8c08acdba9de4c0f8b8674df5 (patch) | |
tree | 4a0eb7966272182b417a9a94f1c5423bcb1fd663 /drivers/block/drbd/drbd_req.c | |
parent | 3e05146f0a9f28ef5959403eabf3239869476315 (diff) |
drbd: Allow to wait for the completion of an epoch entry as well
Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Diffstat (limited to 'drivers/block/drbd/drbd_req.c')
-rw-r--r-- | drivers/block/drbd/drbd_req.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 8b4ba94538bd..078f77ba68fb 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c | |||
@@ -70,9 +70,12 @@ static struct drbd_request *drbd_req_new(struct drbd_conf *mdev, | |||
70 | req->mdev = mdev; | 70 | req->mdev = mdev; |
71 | req->master_bio = bio_src; | 71 | req->master_bio = bio_src; |
72 | req->epoch = 0; | 72 | req->epoch = 0; |
73 | |||
73 | drbd_clear_interval(&req->i); | 74 | drbd_clear_interval(&req->i); |
74 | req->i.sector = bio_src->bi_sector; | 75 | req->i.sector = bio_src->bi_sector; |
75 | req->i.size = bio_src->bi_size; | 76 | req->i.size = bio_src->bi_size; |
77 | req->i.waiting = false; | ||
78 | |||
76 | INIT_LIST_HEAD(&req->tl_requests); | 79 | INIT_LIST_HEAD(&req->tl_requests); |
77 | INIT_LIST_HEAD(&req->w.list); | 80 | INIT_LIST_HEAD(&req->w.list); |
78 | 81 | ||
@@ -175,10 +178,6 @@ static void _about_to_complete_local_write(struct drbd_conf *mdev, | |||
175 | (s & RQ_NET_SENT) != 0 && | 178 | (s & RQ_NET_SENT) != 0 && |
176 | req->epoch == mdev->tconn->newest_tle->br_number) | 179 | req->epoch == mdev->tconn->newest_tle->br_number) |
177 | queue_barrier(mdev); | 180 | queue_barrier(mdev); |
178 | |||
179 | /* Wake up any processes waiting for this request to complete. */ | ||
180 | if ((s & RQ_NET_DONE) && (s & RQ_COLLISION)) | ||
181 | wake_up(&mdev->misc_wait); | ||
182 | } | 181 | } |
183 | 182 | ||
184 | void complete_master_bio(struct drbd_conf *mdev, | 183 | void complete_master_bio(struct drbd_conf *mdev, |
@@ -188,6 +187,20 @@ void complete_master_bio(struct drbd_conf *mdev, | |||
188 | dec_ap_bio(mdev); | 187 | dec_ap_bio(mdev); |
189 | } | 188 | } |
190 | 189 | ||
190 | |||
191 | static void drbd_remove_request_interval(struct rb_root *root, | ||
192 | struct drbd_request *req) | ||
193 | { | ||
194 | struct drbd_conf *mdev = req->mdev; | ||
195 | struct drbd_interval *i = &req->i; | ||
196 | |||
197 | drbd_remove_interval(root, i); | ||
198 | |||
199 | /* Wake up any processes waiting for this request to complete. */ | ||
200 | if (i->waiting) | ||
201 | wake_up(&mdev->misc_wait); | ||
202 | } | ||
203 | |||
191 | /* Helper for __req_mod(). | 204 | /* Helper for __req_mod(). |
192 | * Set m->bio to the master bio, if it is fit to be completed, | 205 | * Set m->bio to the master bio, if it is fit to be completed, |
193 | * or leave it alone (it is initialized to NULL in __req_mod), | 206 | * or leave it alone (it is initialized to NULL in __req_mod), |
@@ -251,7 +264,7 @@ void _req_may_be_done(struct drbd_request *req, struct bio_and_error *m) | |||
251 | root = &mdev->write_requests; | 264 | root = &mdev->write_requests; |
252 | else | 265 | else |
253 | root = &mdev->read_requests; | 266 | root = &mdev->read_requests; |
254 | drbd_remove_interval(root, &req->i); | 267 | drbd_remove_request_interval(root, req); |
255 | } else | 268 | } else |
256 | D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0); | 269 | D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0); |
257 | 270 | ||