Whamcloud - gitweb
LU-8199 ptlrpc: better lut_reply_bitmap handling 50/20450/3
authorNathaniel Clark <nathaniel.l.clark@intel.com>
Wed, 25 May 2016 18:58:32 +0000 (14:58 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 11 Jul 2016 23:53:29 +0000 (23:53 +0000)
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 <nathaniel.l.clark@intel.com>
Change-Id: Ib222300a8c6d0032834d774cde9a9cb3830fb289
Reviewed-on: http://review.whamcloud.com/20450
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Grégoire Pichon <gregoire.pichon@bull.net>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/target/tgt_lastrcvd.c
lustre/target/tgt_main.c

index f0d9222..1c907a6 100644 (file)
@@ -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;
index 6dfb7c4..3e45abf 100644 (file)
@@ -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;