aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/drbd/drbd_actlog.c
diff options
context:
space:
mode:
authorLars Ellenberg <lars.ellenberg@linbit.com>2013-03-19 13:16:53 -0400
committerJens Axboe <axboe@kernel.dk>2013-03-22 20:15:17 -0400
commit6c3c4355d6bfa418db828684e67910c559402264 (patch)
treee7cbaa778b1614342d562f56e98612b850c25046 /drivers/block/drbd/drbd_actlog.c
parentb5bc8e08641805391f2c7834c40d0f647e8563c6 (diff)
drbd: split out some helper functions to drbd_al_begin_io
To make the code easier to follow, use an explicit find_active_resync_extent(), and add a "nonblock" parameter to _al_get(). 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/drbd_actlog.c')
-rw-r--r--drivers/block/drbd/drbd_actlog.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index e4f1231c2ef2..ff03f9053316 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -222,25 +222,37 @@ int drbd_md_sync_page_io(struct drbd_conf *mdev, struct drbd_backing_dev *bdev,
222 return err; 222 return err;
223} 223}
224 224
225static struct lc_element *_al_get(struct drbd_conf *mdev, unsigned int enr) 225static struct bm_extent *find_active_resync_extent(struct drbd_conf *mdev, unsigned int enr)
226{ 226{
227 struct lc_element *al_ext;
228 struct lc_element *tmp; 227 struct lc_element *tmp;
229 int wake;
230
231 spin_lock_irq(&mdev->al_lock);
232 tmp = lc_find(mdev->resync, enr/AL_EXT_PER_BM_SECT); 228 tmp = lc_find(mdev->resync, enr/AL_EXT_PER_BM_SECT);
233 if (unlikely(tmp != NULL)) { 229 if (unlikely(tmp != NULL)) {
234 struct bm_extent *bm_ext = lc_entry(tmp, struct bm_extent, lce); 230 struct bm_extent *bm_ext = lc_entry(tmp, struct bm_extent, lce);
235 if (test_bit(BME_NO_WRITES, &bm_ext->flags)) { 231 if (test_bit(BME_NO_WRITES, &bm_ext->flags))
236 wake = !test_and_set_bit(BME_PRIORITY, &bm_ext->flags); 232 return bm_ext;
237 spin_unlock_irq(&mdev->al_lock);
238 if (wake)
239 wake_up(&mdev->al_wait);
240 return NULL;
241 }
242 } 233 }
243 al_ext = lc_get(mdev->act_log, enr); 234 return NULL;
235}
236
237static struct lc_element *_al_get(struct drbd_conf *mdev, unsigned int enr, bool nonblock)
238{
239 struct lc_element *al_ext;
240 struct bm_extent *bm_ext;
241 int wake;
242
243 spin_lock_irq(&mdev->al_lock);
244 bm_ext = find_active_resync_extent(mdev, enr);
245 if (bm_ext) {
246 wake = !test_and_set_bit(BME_PRIORITY, &bm_ext->flags);
247 spin_unlock_irq(&mdev->al_lock);
248 if (wake)
249 wake_up(&mdev->al_wait);
250 return NULL;
251 }
252 if (nonblock)
253 al_ext = lc_try_get(mdev->act_log, enr);
254 else
255 al_ext = lc_get(mdev->act_log, enr);
244 spin_unlock_irq(&mdev->al_lock); 256 spin_unlock_irq(&mdev->al_lock);
245 return al_ext; 257 return al_ext;
246} 258}
@@ -251,7 +263,6 @@ bool drbd_al_begin_io_fastpath(struct drbd_conf *mdev, struct drbd_interval *i)
251 * we may need to activate two extents in one go */ 263 * we may need to activate two extents in one go */
252 unsigned first = i->sector >> (AL_EXTENT_SHIFT-9); 264 unsigned first = i->sector >> (AL_EXTENT_SHIFT-9);
253 unsigned last = i->size == 0 ? first : (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9); 265 unsigned last = i->size == 0 ? first : (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9);
254 bool fastpath_ok = true;
255 266
256 D_ASSERT((unsigned)(last - first) <= 1); 267 D_ASSERT((unsigned)(last - first) <= 1);
257 D_ASSERT(atomic_read(&mdev->local_cnt) > 0); 268 D_ASSERT(atomic_read(&mdev->local_cnt) > 0);
@@ -260,12 +271,7 @@ bool drbd_al_begin_io_fastpath(struct drbd_conf *mdev, struct drbd_interval *i)
260 if (first != last) 271 if (first != last)
261 return false; 272 return false;
262 273
263 spin_lock_irq(&mdev->al_lock); 274 return _al_get(mdev, first, true);
264 fastpath_ok =
265 lc_find(mdev->resync, first/AL_EXT_PER_BM_SECT) == NULL &&
266 lc_try_get(mdev->act_log, first) != NULL;
267 spin_unlock_irq(&mdev->al_lock);
268 return fastpath_ok;
269} 275}
270 276
271bool drbd_al_begin_io_prepare(struct drbd_conf *mdev, struct drbd_interval *i) 277bool drbd_al_begin_io_prepare(struct drbd_conf *mdev, struct drbd_interval *i)
@@ -282,7 +288,8 @@ bool drbd_al_begin_io_prepare(struct drbd_conf *mdev, struct drbd_interval *i)
282 288
283 for (enr = first; enr <= last; enr++) { 289 for (enr = first; enr <= last; enr++) {
284 struct lc_element *al_ext; 290 struct lc_element *al_ext;
285 wait_event(mdev->al_wait, (al_ext = _al_get(mdev, enr)) != NULL); 291 wait_event(mdev->al_wait,
292 (al_ext = _al_get(mdev, enr, false)) != NULL);
286 if (al_ext->lc_number != enr) 293 if (al_ext->lc_number != enr)
287 need_transaction = true; 294 need_transaction = true;
288 } 295 }