diff options
Diffstat (limited to 'drivers/block/drbd')
-rw-r--r-- | drivers/block/drbd/drbd_actlog.c | 46 |
1 files changed, 23 insertions, 23 deletions
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 07f222cae986..50b851e389e6 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c | |||
@@ -209,20 +209,16 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i) | |||
209 | { | 209 | { |
210 | /* for bios crossing activity log extent boundaries, | 210 | /* for bios crossing activity log extent boundaries, |
211 | * we may need to activate two extents in one go */ | 211 | * we may need to activate two extents in one go */ |
212 | unsigned int enr[2]; | 212 | unsigned first = i->sector >> (AL_EXTENT_SHIFT-9); |
213 | struct lc_element *al_ext[2] = { NULL, NULL }; | 213 | unsigned last = (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9); |
214 | struct update_al_work al_work; | 214 | unsigned enr; |
215 | 215 | ||
216 | D_ASSERT(atomic_read(&mdev->local_cnt) > 0); | 216 | D_ASSERT(atomic_read(&mdev->local_cnt) > 0); |
217 | 217 | ||
218 | enr[0] = i->sector >> (AL_EXTENT_SHIFT-9); | 218 | for (enr = first; enr <= last; enr++) |
219 | enr[1] = (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9); | 219 | wait_event(mdev->al_wait, _al_get(mdev, enr) != NULL); |
220 | wait_event(mdev->al_wait, (al_ext[0] = _al_get(mdev, enr[0]))); | ||
221 | if (enr[0] != enr[1]) | ||
222 | wait_event(mdev->al_wait, (al_ext[1] = _al_get(mdev, enr[1]))); | ||
223 | 220 | ||
224 | if (al_ext[0]->lc_number != enr[0] || | 221 | if (mdev->act_log->pending_changes) { |
225 | (al_ext[1] && al_ext[1]->lc_number != enr[1])) { | ||
226 | /* drbd_al_write_transaction(mdev,al_ext,enr); | 222 | /* drbd_al_write_transaction(mdev,al_ext,enr); |
227 | * recurses into generic_make_request(), which | 223 | * recurses into generic_make_request(), which |
228 | * disallows recursion, bios being serialized on the | 224 | * disallows recursion, bios being serialized on the |
@@ -239,8 +235,8 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i) | |||
239 | 235 | ||
240 | /* Double check: it may have been committed by someone else, | 236 | /* Double check: it may have been committed by someone else, |
241 | * while we have been waiting for the lock. */ | 237 | * while we have been waiting for the lock. */ |
242 | if (al_ext[0]->lc_number != enr[0] || | 238 | if (mdev->act_log->pending_changes) { |
243 | (al_ext[1] && al_ext[1]->lc_number != enr[1])) { | 239 | struct update_al_work al_work; |
244 | init_completion(&al_work.event); | 240 | init_completion(&al_work.event); |
245 | al_work.w.cb = w_al_write_transaction; | 241 | al_work.w.cb = w_al_write_transaction; |
246 | al_work.w.mdev = mdev; | 242 | al_work.w.mdev = mdev; |
@@ -264,24 +260,28 @@ void drbd_al_begin_io(struct drbd_conf *mdev, struct drbd_interval *i) | |||
264 | 260 | ||
265 | void drbd_al_complete_io(struct drbd_conf *mdev, struct drbd_interval *i) | 261 | void drbd_al_complete_io(struct drbd_conf *mdev, struct drbd_interval *i) |
266 | { | 262 | { |
267 | unsigned int enr = (i->sector >> (AL_EXTENT_SHIFT-9)); | 263 | /* for bios crossing activity log extent boundaries, |
264 | * we may need to activate two extents in one go */ | ||
265 | unsigned first = i->sector >> (AL_EXTENT_SHIFT-9); | ||
266 | unsigned last = (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9); | ||
267 | unsigned enr; | ||
268 | struct lc_element *extent; | 268 | struct lc_element *extent; |
269 | unsigned long flags; | 269 | unsigned long flags; |
270 | bool wake = false; | ||
270 | 271 | ||
271 | spin_lock_irqsave(&mdev->al_lock, flags); | 272 | spin_lock_irqsave(&mdev->al_lock, flags); |
272 | 273 | ||
273 | extent = lc_find(mdev->act_log, enr); | 274 | for (enr = first; enr <= last; enr++) { |
274 | 275 | extent = lc_find(mdev->act_log, enr); | |
275 | if (!extent) { | 276 | if (!extent) { |
276 | spin_unlock_irqrestore(&mdev->al_lock, flags); | 277 | dev_err(DEV, "al_complete_io() called on inactive extent %u\n", enr); |
277 | dev_err(DEV, "al_complete_io() called on inactive extent %u\n", enr); | 278 | continue; |
278 | return; | 279 | } |
280 | if (lc_put(mdev->act_log, extent) == 0) | ||
281 | wake = true; | ||
279 | } | 282 | } |
280 | |||
281 | if (lc_put(mdev->act_log, extent) == 0) | ||
282 | wake_up(&mdev->al_wait); | ||
283 | |||
284 | spin_unlock_irqrestore(&mdev->al_lock, flags); | 283 | spin_unlock_irqrestore(&mdev->al_lock, flags); |
284 | wake_up(&mdev->al_wait); | ||
285 | } | 285 | } |
286 | 286 | ||
287 | #if (PAGE_SHIFT + 3) < (AL_EXTENT_SHIFT - BM_BLOCK_SHIFT) | 287 | #if (PAGE_SHIFT + 3) < (AL_EXTENT_SHIFT - BM_BLOCK_SHIFT) |