dect
/
linux-2.6
Archived
13
0
Fork 0

drbd: Added a kref to bm_aio_ctx

Signed-off-by: Philipp Reisner <philipp.reisner@linbit.com>
Signed-off-by: Lars Ellenberg <lars.ellenberg@linbit.com>
This commit is contained in:
Philipp Reisner 2011-06-27 14:56:52 +02:00
parent b2057629ea
commit d1f3779bbe
1 changed files with 59 additions and 25 deletions

View File

@ -890,8 +890,16 @@ struct bm_aio_ctx {
unsigned flags; unsigned flags;
#define BM_AIO_COPY_PAGES 1 #define BM_AIO_COPY_PAGES 1
int error; int error;
struct kref kref;
}; };
static void bm_aio_ctx_destroy(struct kref *kref)
{
struct bm_aio_ctx *ctx = container_of(kref, struct bm_aio_ctx, kref);
kfree(ctx);
}
/* bv_page may be a copy, or may be the original */ /* bv_page may be a copy, or may be the original */
static void bm_async_io_complete(struct bio *bio, int error) static void bm_async_io_complete(struct bio *bio, int error)
{ {
@ -936,8 +944,10 @@ static void bm_async_io_complete(struct bio *bio, int error)
bio_put(bio); bio_put(bio);
if (atomic_dec_and_test(&ctx->in_flight)) if (atomic_dec_and_test(&ctx->in_flight)) {
complete(&ctx->done); complete(&ctx->done);
kref_put(&ctx->kref, &bm_aio_ctx_destroy);
}
} }
static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must_hold(local) static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must_hold(local)
@ -1001,12 +1011,7 @@ static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must
*/ */
static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_idx) __must_hold(local) static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_idx) __must_hold(local)
{ {
struct bm_aio_ctx ctx = { struct bm_aio_ctx *ctx;
.mdev = mdev,
.in_flight = ATOMIC_INIT(1),
.done = COMPLETION_INITIALIZER_ONSTACK(ctx.done),
.flags = lazy_writeout_upper_idx ? BM_AIO_COPY_PAGES : 0,
};
struct drbd_bitmap *b = mdev->bitmap; struct drbd_bitmap *b = mdev->bitmap;
int num_pages, i, count = 0; int num_pages, i, count = 0;
unsigned long now; unsigned long now;
@ -1021,7 +1026,21 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_id
* For lazy writeout, we don't care for ongoing changes to the bitmap, * For lazy writeout, we don't care for ongoing changes to the bitmap,
* as we submit copies of pages anyways. * as we submit copies of pages anyways.
*/ */
if (!ctx.flags)
ctx = kmalloc(sizeof(struct bm_aio_ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
*ctx = (struct bm_aio_ctx) {
.mdev = mdev,
.in_flight = ATOMIC_INIT(1),
.done = COMPLETION_INITIALIZER(ctx->done),
.flags = lazy_writeout_upper_idx ? BM_AIO_COPY_PAGES : 0,
.error = 0,
.kref = { ATOMIC_INIT(2) },
};
if (!ctx->flags)
WARN_ON(!(BM_LOCKED_MASK & b->bm_flags)); WARN_ON(!(BM_LOCKED_MASK & b->bm_flags));
num_pages = b->bm_number_of_pages; num_pages = b->bm_number_of_pages;
@ -1046,27 +1065,28 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_id
continue; continue;
} }
} }
atomic_inc(&ctx.in_flight); atomic_inc(&ctx->in_flight);
bm_page_io_async(&ctx, i, rw); bm_page_io_async(ctx, i, rw);
++count; ++count;
cond_resched(); cond_resched();
} }
/* /*
* We initialize ctx.in_flight to one to make sure bm_async_io_complete * We initialize ctx->in_flight to one to make sure bm_async_io_complete
* will not complete() early, and decrement / test it here. If there * will not complete() early, and decrement / test it here. If there
* are still some bios in flight, we need to wait for them here. * are still some bios in flight, we need to wait for them here.
*/ */
if (!atomic_dec_and_test(&ctx.in_flight)) if (!atomic_dec_and_test(&ctx->in_flight))
wait_for_completion(&ctx.done); wait_for_completion(&ctx->done);
dev_info(DEV, "bitmap %s of %u pages took %lu jiffies\n", dev_info(DEV, "bitmap %s of %u pages took %lu jiffies\n",
rw == WRITE ? "WRITE" : "READ", rw == WRITE ? "WRITE" : "READ",
count, jiffies - now); count, jiffies - now);
if (ctx.error) { if (ctx->error) {
dev_alert(DEV, "we had at least one MD IO ERROR during bitmap IO\n"); dev_alert(DEV, "we had at least one MD IO ERROR during bitmap IO\n");
drbd_chk_io_error(mdev, 1, true); drbd_chk_io_error(mdev, 1, true);
err = -EIO; /* ctx.error ? */ err = -EIO; /* ctx->error ? */
} }
now = jiffies; now = jiffies;
@ -1082,6 +1102,8 @@ static int bm_rw(struct drbd_conf *mdev, int rw, unsigned lazy_writeout_upper_id
dev_info(DEV, "%s (%lu bits) marked out-of-sync by on disk bit-map.\n", dev_info(DEV, "%s (%lu bits) marked out-of-sync by on disk bit-map.\n",
ppsize(ppb, now << (BM_BLOCK_SHIFT-10)), now); ppsize(ppb, now << (BM_BLOCK_SHIFT-10)), now);
kref_put(&ctx->kref, &bm_aio_ctx_destroy);
return err; return err;
} }
@ -1130,28 +1152,40 @@ int drbd_bm_write_lazy(struct drbd_conf *mdev, unsigned upper_idx) __must_hold(l
*/ */
int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local) int drbd_bm_write_page(struct drbd_conf *mdev, unsigned int idx) __must_hold(local)
{ {
struct bm_aio_ctx ctx = { struct bm_aio_ctx *ctx;
.mdev = mdev, int err;
.in_flight = ATOMIC_INIT(1),
.done = COMPLETION_INITIALIZER_ONSTACK(ctx.done),
.flags = BM_AIO_COPY_PAGES,
};
if (bm_test_page_unchanged(mdev->bitmap->bm_pages[idx])) { if (bm_test_page_unchanged(mdev->bitmap->bm_pages[idx])) {
dynamic_dev_dbg(DEV, "skipped bm page write for idx %u\n", idx); dynamic_dev_dbg(DEV, "skipped bm page write for idx %u\n", idx);
return 0; return 0;
} }
bm_page_io_async(&ctx, idx, WRITE_SYNC); ctx = kmalloc(sizeof(struct bm_aio_ctx), GFP_KERNEL);
wait_for_completion(&ctx.done); if (!ctx)
return -ENOMEM;
if (ctx.error) *ctx = (struct bm_aio_ctx) {
.mdev = mdev,
.in_flight = ATOMIC_INIT(1),
.done = COMPLETION_INITIALIZER(ctx->done),
.flags = BM_AIO_COPY_PAGES,
.error = 0,
.kref = { ATOMIC_INIT(2) },
};
bm_page_io_async(ctx, idx, WRITE_SYNC);
wait_for_completion(&ctx->done);
if (ctx->error)
drbd_chk_io_error(mdev, 1, true); drbd_chk_io_error(mdev, 1, true);
/* that should force detach, so the in memory bitmap will be /* that should force detach, so the in memory bitmap will be
* gone in a moment as well. */ * gone in a moment as well. */
mdev->bm_writ_cnt++; mdev->bm_writ_cnt++;
return ctx.error; err = ctx->error;
kref_put(&ctx->kref, &bm_aio_ctx_destroy);
return err;
} }
/* NOTE /* NOTE