struct page **bm_pages;
        spinlock_t bm_lock;
 
+       /* exclusively to be used by __al_write_transaction(),
+        * drbd_bm_mark_for_writeout() and
+        * and drbd_bm_write_hinted() -> bm_rw() called from there.
+        */
+       unsigned int n_bitmap_hints;
+       unsigned int al_bitmap_hints[AL_UPDATES_PER_TRANSACTION];
+
        /* see LIMITATIONS: above */
 
        unsigned long bm_set;       /* nr of set bits; THINK maybe atomic_t? */
        set_bit(BM_PAGE_NEED_WRITEOUT, &page_private(page));
 }
 
+void drbd_bm_reset_al_hints(struct drbd_device *device)
+{
+       device->bitmap->n_bitmap_hints = 0;
+}
+
 /**
  * drbd_bm_mark_for_writeout() - mark a page with a "hint" to be considered for writeout
  * @device:    DRBD device.
  */
 void drbd_bm_mark_for_writeout(struct drbd_device *device, int page_nr)
 {
+       struct drbd_bitmap *b = device->bitmap;
        struct page *page;
        if (page_nr >= device->bitmap->bm_number_of_pages) {
                drbd_warn(device, "BAD: page_nr: %u, number_of_pages: %u\n",
                return;
        }
        page = device->bitmap->bm_pages[page_nr];
-       set_bit(BM_PAGE_HINT_WRITEOUT, &page_private(page));
+       BUG_ON(b->n_bitmap_hints >= ARRAY_SIZE(b->al_bitmap_hints));
+       if (!test_and_set_bit(BM_PAGE_HINT_WRITEOUT, &page_private(page)))
+               b->al_bitmap_hints[b->n_bitmap_hints++] = page_nr;
 }
 
 static int bm_test_page_unchanged(struct page *page)
 {
        struct drbd_bm_aio_ctx *ctx;
        struct drbd_bitmap *b = device->bitmap;
-       int num_pages, i, count = 0;
+       unsigned int num_pages, i, count = 0;
        unsigned long now;
        char ppb[10];
        int err = 0;
        now = jiffies;
 
        /* let the layers below us try to merge these bios... */
-       for (i = 0; i < num_pages; i++) {
-               /* ignore completely unchanged pages */
-               if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx)
-                       break;
-               if (!(flags & BM_AIO_READ)) {
-                       if ((flags & BM_AIO_WRITE_HINTED) &&
-                           !test_and_clear_bit(BM_PAGE_HINT_WRITEOUT,
-                                   &page_private(b->bm_pages[i])))
-                               continue;
 
+       if (flags & BM_AIO_READ) {
+               for (i = 0; i < num_pages; i++) {
+                       atomic_inc(&ctx->in_flight);
+                       bm_page_io_async(ctx, i);
+                       ++count;
+                       cond_resched();
+               }
+       } else if (flags & BM_AIO_WRITE_HINTED) {
+               /* ASSERT: BM_AIO_WRITE_ALL_PAGES is not set. */
+               unsigned int hint;
+               for (hint = 0; hint < b->n_bitmap_hints; hint++) {
+                       i = b->al_bitmap_hints[hint];
+                       if (i >= num_pages) /* == -1U: no hint here. */
+                               continue;
+                       /* Several AL-extents may point to the same page. */
+                       if (!test_and_clear_bit(BM_PAGE_HINT_WRITEOUT,
+                           &page_private(b->bm_pages[i])))
+                               continue;
+                       /* Has it even changed? */
+                       if (bm_test_page_unchanged(b->bm_pages[i]))
+                               continue;
+                       atomic_inc(&ctx->in_flight);
+                       bm_page_io_async(ctx, i);
+                       ++count;
+               }
+       } else {
+               for (i = 0; i < num_pages; i++) {
+                       /* ignore completely unchanged pages */
+                       if (lazy_writeout_upper_idx && i == lazy_writeout_upper_idx)
+                               break;
                        if (!(flags & BM_AIO_WRITE_ALL_PAGES) &&
                            bm_test_page_unchanged(b->bm_pages[i])) {
                                dynamic_drbd_dbg(device, "skipped bm write for idx %u\n", i);
                                dynamic_drbd_dbg(device, "skipped bm lazy write for idx %u\n", i);
                                continue;
                        }
+                       atomic_inc(&ctx->in_flight);
+                       bm_page_io_async(ctx, i);
+                       ++count;
+                       cond_resched();
                }
-               atomic_inc(&ctx->in_flight);
-               bm_page_io_async(ctx, i);
-               ++count;
-               cond_resched();
        }
 
        /*