aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/drbd')
-rw-r--r--drivers/block/drbd/drbd_actlog.c46
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
265void drbd_al_complete_io(struct drbd_conf *mdev, struct drbd_interval *i) 261void 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)