From 5f08d032972256928a7a9ede3b526963c884778e Mon Sep 17 00:00:00 2001 From: Nathaniel Clark Date: Wed, 25 May 2016 14:58:32 -0400 Subject: [PATCH] LU-8199 ptlrpc: better lut_reply_bitmap handling MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Use OBD_ALLOC_LARGE instead of OBD_ALLOC to allocate chunks because of size. Also ensure they are free'd correctly. Better return checking of tgt_bitmap_chunk_alloc by callers. Check lut_reply_bitmap[chunk] is non-null in tgt_clear_reply_slot (in case tgt_bitmap_chunk_alloc did fail). Don't leak lut_replay_bitmap chunks if tgt_init fails. Signed-off-by: Nathaniel Clark Change-Id: Ib222300a8c6d0032834d774cde9a9cb3830fb289 Reviewed-on: http://review.whamcloud.com/20450 Reviewed-by: Andreas Dilger Reviewed-by: Grégoire Pichon Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/target/tgt_lastrcvd.c | 17 ++++++++++++++--- lustre/target/tgt_main.c | 14 +++++++++++--- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/lustre/target/tgt_lastrcvd.c b/lustre/target/tgt_lastrcvd.c index f0d9222..1c907a6 100644 --- a/lustre/target/tgt_lastrcvd.c +++ b/lustre/target/tgt_lastrcvd.c @@ -50,7 +50,8 @@ static int tgt_bitmap_chunk_alloc(struct lu_target *lut, int chunk) { unsigned long *bm; - OBD_ALLOC(bm, BITS_TO_LONGS(LUT_REPLY_SLOTS_PER_CHUNK) * sizeof(long)); + OBD_ALLOC_LARGE(bm, BITS_TO_LONGS(LUT_REPLY_SLOTS_PER_CHUNK) * + sizeof(long)); if (bm == NULL) return -ENOMEM; @@ -59,7 +60,7 @@ static int tgt_bitmap_chunk_alloc(struct lu_target *lut, int chunk) if (lut->lut_reply_bitmap[chunk] != NULL) { /* someone else already allocated the bitmap for this chunk */ spin_unlock(&lut->lut_client_bitmap_lock); - OBD_FREE(bm, BITS_TO_LONGS(LUT_REPLY_SLOTS_PER_CHUNK) * + OBD_FREE_LARGE(bm, BITS_TO_LONGS(LUT_REPLY_SLOTS_PER_CHUNK) * sizeof(long)); return 0; } @@ -155,6 +156,12 @@ static int tgt_clear_reply_slot(struct lu_target *lut, int idx) LASSERT(chunk < LUT_REPLY_SLOTS_MAX_CHUNKS); LASSERT(b < LUT_REPLY_SLOTS_PER_CHUNK); + if (lut->lut_reply_bitmap[chunk] == NULL) { + CERROR("%s: slot %d not allocated\n", + tgt_name(lut), idx); + return -ENOENT; + } + if (test_and_clear_bit(b, lut->lut_reply_bitmap[chunk]) == 0) { CERROR("%s: slot %d already clear in bitmap\n", tgt_name(lut), idx); @@ -1885,7 +1892,11 @@ int tgt_reply_data_init(const struct lu_env *env, struct lu_target *tgt) /* create in-memory reply_data and link it to * target export's reply list */ - tgt_set_reply_slot(tgt, idx); + rc = tgt_set_reply_slot(tgt, idx); + if (rc != 0) { + mutex_unlock(&ted->ted_lcd_lock); + GOTO(out, rc); + } trd->trd_reply = *lrd; trd->trd_pre_versions[0] = 0; trd->trd_pre_versions[1] = 0; diff --git a/lustre/target/tgt_main.c b/lustre/target/tgt_main.c index 6dfb7c4..3e45abf 100644 --- a/lustre/target/tgt_main.c +++ b/lustre/target/tgt_main.c @@ -153,7 +153,7 @@ int tgt_init(const struct lu_env *env, struct lu_target *lut, struct lu_attr attr; struct lu_fid fid; struct dt_object *o; - int rc = 0; + int i, rc = 0; ENTRY; @@ -272,9 +272,17 @@ out_put: if (lut->lut_reply_data != NULL) lu_object_put(env, &lut->lut_reply_data->do_lu); lut->lut_reply_data = NULL; - if (lut->lut_reply_bitmap != NULL) + if (lut->lut_reply_bitmap != NULL) { + for (i = 0; i < LUT_REPLY_SLOTS_MAX_CHUNKS; i++) { + if (lut->lut_reply_bitmap[i] != NULL) + OBD_FREE_LARGE(lut->lut_reply_bitmap[i], + BITS_TO_LONGS(LUT_REPLY_SLOTS_PER_CHUNK) * + sizeof(long)); + lut->lut_reply_bitmap[i] = NULL; + } OBD_FREE(lut->lut_reply_bitmap, LUT_REPLY_SLOTS_MAX_CHUNKS * sizeof(unsigned long *)); + } lut->lut_reply_bitmap = NULL; return rc; } @@ -306,7 +314,7 @@ void tgt_fini(const struct lu_env *env, struct lu_target *lut) if (lut->lut_reply_bitmap != NULL) { for (i = 0; i < LUT_REPLY_SLOTS_MAX_CHUNKS; i++) { if (lut->lut_reply_bitmap[i] != NULL) - OBD_FREE(lut->lut_reply_bitmap[i], + OBD_FREE_LARGE(lut->lut_reply_bitmap[i], BITS_TO_LONGS(LUT_REPLY_SLOTS_PER_CHUNK) * sizeof(long)); lut->lut_reply_bitmap[i] = NULL; -- 1.8.3.1