]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
dm zoned: target: use refcount_t for dm zoned reference counters
authorJohn Pittman <jpittman@redhat.com>
Thu, 23 Aug 2018 17:35:57 +0000 (13:35 -0400)
committerMike Snitzer <snitzer@redhat.com>
Tue, 16 Oct 2018 18:27:38 +0000 (14:27 -0400)
The API surrounding refcount_t should be used in place of atomic_t
when variables are being used as reference counters.  This API can
prevent issues such as counter overflows and use-after-free
conditions.  Within the dm zoned target stack, the atomic_t API is
used for bioctx->ref and cw->refcount.  Change these to use
refcount_t, avoiding the issues mentioned.

Signed-off-by: John Pittman <jpittman@redhat.com>
Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com>
Tested-by: Damien Le Moal <damien.lemoal@wdc.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
drivers/md/dm-zoned-target.c

index a44183ff4be0a3bd4219a7bf5854622aeca79db2..fa36825c1eff7a3a6c45c9a9887bed9fd91ada0e 100644 (file)
@@ -19,7 +19,7 @@ struct dmz_bioctx {
        struct dmz_target       *target;
        struct dm_zone          *zone;
        struct bio              *bio;
-       atomic_t                ref;
+       refcount_t              ref;
        blk_status_t            status;
 };
 
@@ -28,7 +28,7 @@ struct dmz_bioctx {
  */
 struct dm_chunk_work {
        struct work_struct      work;
-       atomic_t                refcount;
+       refcount_t              refcount;
        struct dmz_target       *target;
        unsigned int            chunk;
        struct bio_list         bio_list;
@@ -115,7 +115,7 @@ static int dmz_submit_read_bio(struct dmz_target *dmz, struct dm_zone *zone,
        if (nr_blocks == dmz_bio_blocks(bio)) {
                /* Setup and submit the BIO */
                bio->bi_iter.bi_sector = sector;
-               atomic_inc(&bioctx->ref);
+               refcount_inc(&bioctx->ref);
                generic_make_request(bio);
                return 0;
        }
@@ -134,7 +134,7 @@ static int dmz_submit_read_bio(struct dmz_target *dmz, struct dm_zone *zone,
        bio_advance(bio, clone->bi_iter.bi_size);
 
        /* Submit the clone */
-       atomic_inc(&bioctx->ref);
+       refcount_inc(&bioctx->ref);
        generic_make_request(clone);
 
        return 0;
@@ -240,7 +240,7 @@ static void dmz_submit_write_bio(struct dmz_target *dmz, struct dm_zone *zone,
        /* Setup and submit the BIO */
        bio_set_dev(bio, dmz->dev->bdev);
        bio->bi_iter.bi_sector = dmz_start_sect(dmz->metadata, zone) + dmz_blk2sect(chunk_block);
-       atomic_inc(&bioctx->ref);
+       refcount_inc(&bioctx->ref);
        generic_make_request(bio);
 
        if (dmz_is_seq(zone))
@@ -456,7 +456,7 @@ static void dmz_handle_bio(struct dmz_target *dmz, struct dm_chunk_work *cw,
  */
 static inline void dmz_get_chunk_work(struct dm_chunk_work *cw)
 {
-       atomic_inc(&cw->refcount);
+       refcount_inc(&cw->refcount);
 }
 
 /*
@@ -465,7 +465,7 @@ static inline void dmz_get_chunk_work(struct dm_chunk_work *cw)
  */
 static void dmz_put_chunk_work(struct dm_chunk_work *cw)
 {
-       if (atomic_dec_and_test(&cw->refcount)) {
+       if (refcount_dec_and_test(&cw->refcount)) {
                WARN_ON(!bio_list_empty(&cw->bio_list));
                radix_tree_delete(&cw->target->chunk_rxtree, cw->chunk);
                kfree(cw);
@@ -546,7 +546,7 @@ static void dmz_queue_chunk_work(struct dmz_target *dmz, struct bio *bio)
                        goto out;
 
                INIT_WORK(&cw->work, dmz_chunk_work);
-               atomic_set(&cw->refcount, 0);
+               refcount_set(&cw->refcount, 0);
                cw->target = dmz;
                cw->chunk = chunk;
                bio_list_init(&cw->bio_list);
@@ -599,7 +599,7 @@ static int dmz_map(struct dm_target *ti, struct bio *bio)
        bioctx->target = dmz;
        bioctx->zone = NULL;
        bioctx->bio = bio;
-       atomic_set(&bioctx->ref, 1);
+       refcount_set(&bioctx->ref, 1);
        bioctx->status = BLK_STS_OK;
 
        /* Set the BIO pending in the flush list */
@@ -633,7 +633,7 @@ static int dmz_end_io(struct dm_target *ti, struct bio *bio, blk_status_t *error
        if (bioctx->status == BLK_STS_OK && *error)
                bioctx->status = *error;
 
-       if (!atomic_dec_and_test(&bioctx->ref))
+       if (!refcount_dec_and_test(&bioctx->ref))
                return DM_ENDIO_INCOMPLETE;
 
        /* Done */