dm dedup: fix all 64bit divides when ARCH=i386 dm-dedup dm-dedup-sonam dm-dedup-vasily
authorMike Snitzer <snitzer@redhat.com>
Mon, 22 Sep 2014 22:31:30 +0000 (18:31 -0400)
committerMike Snitzer <snitzer@redhat.com>
Mon, 22 Sep 2014 22:31:30 +0000 (18:31 -0400)
Hopefully nothing got broken along the way...
(also tweaked some whitespace)

XXX: sizeof(lbn) in prepare_bio_on_write() looks suspect

drivers/md/dm-dedup-ram.c
drivers/md/dm-dedup-rw.c
drivers/md/dm-dedup-target.c

index b9c9503c1db1a3862f1191a77f7a6d8bd571b384..8718270d50e3c562c535346778dec6a73e4e7691 100644 (file)
@@ -44,7 +44,7 @@ struct kvstore_inram {
 
 static struct metadata *init_meta_inram(void *init_param, bool *unformatted)
 {
-       uint64_t smap_size;
+       uint64_t smap_size, tmp;
        struct metadata *md;
        struct init_param_inram *p = (struct init_param_inram *)init_param;
 
@@ -64,10 +64,10 @@ static struct metadata *init_meta_inram(void *init_param, bool *unformatted)
                return ERR_PTR(-ENOMEM);
        }
 
+       tmp = smap_size;
+       (void) do_div(tmp, (1024 * 1024));
        DMINFO("Space allocated for pbn reference count map: %llu.%06llu MB\n",
-                       smap_size / (1024 * 1024),
-                       smap_size - ((smap_size /
-                       (1024 * 1024)) * (1024 * 1024)));
+              tmp, smap_size - (tmp * (1024 * 1024)));
 
        memset(md->smap, 0, smap_size);
 
@@ -109,6 +109,12 @@ static int flush_meta_inram(struct metadata *md)
  *             Space Management Functions              *
  ********************************************************/
 
+static uint64_t next_head(uint64_t current_head, uint64_t smax)
+{
+       current_head += 1;
+       return dm_sector_div64(current_head, smax);
+}
+
 static int alloc_data_block_inram(struct metadata *md, uint64_t *blockn)
 {
        uint64_t head, tail;
@@ -119,11 +125,11 @@ static int alloc_data_block_inram(struct metadata *md, uint64_t *blockn)
                if (!md->smap[head]) {
                        md->smap[head] = 1;
                        *blockn = head;
-                       md->allocptr = (head + 1) % md->smax;
+                       md->allocptr = next_head(head, md->smax);
                        return 0;
                }
 
-               head = (head + 1) % md->smax;
+               head = next_head(head, md->smax);
 
        } while (head != tail);
 
@@ -318,7 +324,7 @@ static struct kvstore *kvs_create_linear_inram(struct metadata *md,
                        bool unformatted)
 {
        struct kvstore_inram *kvs;
-       uint64_t kvstore_size;
+       uint64_t kvstore_size, tmp;
 
        if (!vsize || !ksize || !kmax)
                return ERR_PTR(-ENOTSUPP);
@@ -342,10 +348,10 @@ static struct kvstore *kvs_create_linear_inram(struct metadata *md,
                return ERR_PTR(-ENOMEM);
        }
 
+       tmp = kvstore_size;
+       (void) do_div(tmp, (1024 * 1024));
        DMINFO("Space allocated for linear key value store: %llu.%06llu MB\n",
-                       kvstore_size / (1024 * 1024),
-                       kvstore_size - ((kvstore_size / (1024 * 1024))
-                       * (1024 * 1024)));
+              tmp, kvstore_size - (tmp * (1024 * 1024)));
 
        memset(kvs->store, EMPTY_ENTRY, kvstore_size);
 
@@ -367,7 +373,7 @@ static struct kvstore *kvs_create_linear_inram(struct metadata *md,
  ********************************************************/
 
 static int kvs_delete_sparse_inram(struct kvstore *kvs,
-                               void *key, int32_t ksize)
+                                  void *key, int32_t ksize)
 {
        uint64_t idxhead = *((uint64_t *)key);
        uint32_t entry_size, head, tail;
@@ -380,7 +386,7 @@ static int kvs_delete_sparse_inram(struct kvstore *kvs,
        kvinram = container_of(kvs, struct kvstore_inram, ckvs);
 
        entry_size = kvs->vsize + kvs->ksize;
-       head = idxhead % kvinram->kmax;
+       head = do_div(idxhead, kvinram->kmax);
        tail = head;
 
        do {
@@ -390,7 +396,7 @@ static int kvs_delete_sparse_inram(struct kvstore *kvs,
                        goto doesnotexist;
 
                if (memcmp(ptr, key, kvs->ksize))
-                       head = (head + 1) % kvinram->kmax;
+                       head = next_head(head, kvinram->kmax);
                else {
                        memset(ptr, DELETED_ENTRY, entry_size);
                        return 0;
@@ -407,7 +413,7 @@ doesnotexist:
  * < 0 - error on lookup
  */
 static int kvs_lookup_sparse_inram(struct kvstore *kvs, void *key,
-                       int32_t ksize, void *value, int32_t *vsize)
+                                  int32_t ksize, void *value, int32_t *vsize)
 {
        uint64_t idxhead = *((uint64_t *)key);
        uint32_t entry_size, head, tail;
@@ -420,7 +426,7 @@ static int kvs_lookup_sparse_inram(struct kvstore *kvs, void *key,
        kvinram = container_of(kvs, struct kvstore_inram, ckvs);
 
        entry_size = kvs->vsize + kvs->ksize;
-       head = idxhead % kvinram->kmax;
+       head = do_div(idxhead, kvinram->kmax);
        tail = head;
 
        do {
@@ -430,11 +436,11 @@ static int kvs_lookup_sparse_inram(struct kvstore *kvs, void *key,
                        return 0;
 
                if (memcmp(ptr, key, kvs->ksize))
-                       head = (head + 1) % kvinram->kmax;
+                       head = next_head(head, kvinram->kmax);
                else {
                        memcpy(value, ptr + kvs->ksize, kvs->vsize);
                        return 1;
-       }
+               }
 
        } while (head != tail);
 
@@ -442,7 +448,7 @@ static int kvs_lookup_sparse_inram(struct kvstore *kvs, void *key,
 }
 
 static int kvs_insert_sparse_inram(struct kvstore *kvs, void *key,
-                       int32_t ksize, void *value, int32_t vsize)
+                                  int32_t ksize, void *value, int32_t vsize)
 {
        uint64_t idxhead = *((uint64_t *)key);
        uint32_t entry_size, head, tail;
@@ -455,7 +461,7 @@ static int kvs_insert_sparse_inram(struct kvstore *kvs, void *key,
        kvinram = container_of(kvs, struct kvstore_inram, ckvs);
 
        entry_size = kvs->vsize + kvs->ksize;
-       head = idxhead % kvinram->kmax;
+       head = do_div(idxhead, kvinram->kmax);
        tail = head;
 
        do {
@@ -467,7 +473,7 @@ static int kvs_insert_sparse_inram(struct kvstore *kvs, void *key,
                        return 0;
                }
 
-               head = (head + 1) % kvinram->kmax;
+               head = next_head(head, kvinram->kmax);
 
        } while (head != tail);
 
@@ -508,7 +514,7 @@ static int kvs_iterate_sparse_inram(struct kvstore *kvs,
                                goto out;
                }
 
-               head = (head + 1) % kvinram->kmax;
+               head = next_head(head, kvinram->kmax);
        } while (head);
 
 out:
@@ -520,7 +526,7 @@ static struct kvstore *kvs_create_sparse_inram(struct metadata *md,
                        bool unformatted)
 {
        struct kvstore_inram *kvs;
-       uint64_t kvstore_size;
+       uint64_t kvstore_size, tmp;
 
        if (!vsize || !ksize || !knummax)
                return ERR_PTR(-ENOTSUPP);
@@ -533,7 +539,7 @@ static struct kvstore *kvs_create_sparse_inram(struct metadata *md,
        if (!kvs)
                return ERR_PTR(-ENOMEM);
 
-       knummax += knummax * HASHTABLE_OVERPROV / 100;
+       knummax += (knummax * HASHTABLE_OVERPROV) / 100;
 
        kvstore_size = (knummax * (vsize + ksize));
 
@@ -543,10 +549,10 @@ static struct kvstore *kvs_create_sparse_inram(struct metadata *md,
                return ERR_PTR(-ENOMEM);
        }
 
+       tmp = kvstore_size;
+       (void) do_div(tmp, (1024 * 1024));
        DMINFO("Space allocated for sparse key value store: %llu.%06llu MB\n",
-                       kvstore_size / (1024 * 1024),
-                       kvstore_size - ((kvstore_size / (1024 * 1024))
-                       * (1024 * 1024)));
+              tmp, kvstore_size - (tmp * (1024 * 1024)));
 
        memset(kvs->store, EMPTY_ENTRY, kvstore_size);
 
index 383ec394b0a2a54098efd454f5476269fab1dc68..9b88bfdc46adfff815b46e061c7df19bbef7a59f 100644 (file)
 
 #define DMD_IO_SIZE    4096
 
-static uint64_t compute_sector(struct bio *bio,
+static sector_t compute_sector(struct bio *bio,
                               struct dedup_config *dc)
 {
-       uint64_t to_be_lbn;
+       sector_t to_be_lbn;
 
        to_be_lbn = bio->bi_iter.bi_sector;
-       to_be_lbn /= dc->sectors_per_block;
+       (void) sector_div(to_be_lbn, dc->sectors_per_block);
        to_be_lbn *= dc->sectors_per_block;
 
        return to_be_lbn;
 }
 
 static int fetch_whole_block(struct dedup_config *dc,
-                       uint64_t pbn, struct page_list *pl)
+                            uint64_t pbn, struct page_list *pl)
 {
        struct dm_io_request iorq;
        struct dm_io_region where;
@@ -50,13 +50,14 @@ static int fetch_whole_block(struct dedup_config *dc,
 }
 
 static int merge_data(struct dedup_config *dc, struct page *page,
-                               struct bio *bio)
+                     struct bio *bio)
 {
+       sector_t bi_sector = bio->bi_iter.bi_sector;
        void *src_page_vaddr, *dest_page_vaddr;
        int position, err = 0;
 
        /* Relative offset in terms of sector size */
-       position = (bio->bi_iter.bi_sector % dc->sectors_per_block);
+       position = sector_div(bi_sector, dc->sectors_per_block);
 
        if (!page || !bio->bi_io_vec->bv_page) {
                err = -EINVAL;
@@ -224,23 +225,22 @@ out:
 struct bio *prepare_bio_on_write(struct dedup_config *dc, struct bio *bio)
 {
        int r;
-       uint64_t lbn_sector;
-       uint64_t lbn;
+       sector_t lbn;
        uint32_t vsize;
        struct lbn_pbn_value lbnpbn_value;
        struct bio *clone;
 
-       lbn_sector = compute_sector(bio, dc);
-       lbn = lbn_sector / dc->sectors_per_block;
+       lbn = compute_sector(bio, dc);
+       (void) sector_div(lbn, dc->sectors_per_block);
 
        /* check for old or new lbn and fetch the appropriate pbn */
        r = dc->kvs_lbn_pbn->kvs_lookup(dc->kvs_lbn_pbn, (void *)&lbn,
-                       sizeof(lbn), (void *)&lbnpbn_value, &vsize);
+                                       sizeof(lbn), (void *)&lbnpbn_value, &vsize);
        if (r == 0)
                clone = prepare_bio_without_pbn(dc, bio);
        else if (r == 1)
-               clone = prepare_bio_with_pbn(dc, bio, lbnpbn_value.pbn
-                                               * dc->sectors_per_block);
+               clone = prepare_bio_with_pbn(dc, bio,
+                                            lbnpbn_value.pbn * dc->sectors_per_block);
        else
                BUG();
 
index dc0ffd2edc67b23d43e11cf011237e785d9a439a..3993f5669f95fa5dfb11babde18d8736acfcdb22 100644 (file)
@@ -61,15 +61,18 @@ static void bio_zero_endio(struct bio *bio)
 
 static uint64_t bio_lbn(struct dedup_config *dc, struct bio *bio)
 {
-       return bio->bi_iter.bi_sector / dc->sectors_per_block;
+       sector_t lbn = bio->bi_iter.bi_sector;
+
+       sector_div(lbn, dc->sectors_per_block);
+
+       return lbn;
 }
 
-static void do_io(struct dedup_config *dc, struct bio *bio,
-                       uint64_t pbn)
+static void do_io(struct dedup_config *dc, struct bio *bio, uint64_t pbn)
 {
        int offset;
 
-       offset = (sector_t) bio->bi_iter.bi_sector % dc->sectors_per_block;
+       offset = sector_div(bio->bi_iter.bi_sector, dc->sectors_per_block);
        bio->bi_iter.bi_sector = (sector_t)pbn * dc->sectors_per_block + offset;
 
        bio->bi_bdev = dc->data_dev->bdev;
@@ -539,7 +542,7 @@ static int dm_dedup_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        void *iparam;
        struct metadata *md = NULL;
 
-       uint64_t data_size;
+       sector_t data_size;
        int r;
        int crypto_key_size;
 
@@ -590,10 +593,13 @@ static int dm_dedup_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 
        dc->block_size = da.block_size;
        dc->sectors_per_block = to_sector(da.block_size);
-       dc->lblocks = ti->len / dc->sectors_per_block;
+       data_size = ti->len;
+       (void) sector_div(data_size, dc->sectors_per_block);
+       dc->lblocks = data_size;
 
-       data_size = i_size_read(da.data_dev->bdev->bd_inode);
-       dc->pblocks = data_size / da.block_size;
+       data_size = i_size_read(da.data_dev->bdev->bd_inode) >> SECTOR_SHIFT;
+       (void) sector_div(data_size, dc->sectors_per_block);
+       dc->pblocks = data_size;
 
        /* Meta-data backend specific part */
        if (da.backend == BKND_INRAM) {
@@ -830,14 +836,15 @@ static int cleanup_hash_pbn(void *key, int32_t ksize, void *value,
 static int mark_and_sweep(struct dedup_config *dc)
 {
        int err = 0;
-       uint64_t data_size = 0;
+       sector_t data_size = 0;
        uint64_t bitmap_size = 0;
        struct mark_and_sweep_data ms_data;
 
        BUG_ON(!dc);
 
-       data_size = i_size_read(dc->data_dev->bdev->bd_inode);
-       bitmap_size = data_size / dc->block_size;
+       data_size = i_size_read(dc->data_dev->bdev->bd_inode) >> SECTOR_SHIFT;
+       (void) sector_div(data_size, dc->sectors_per_block);
+       bitmap_size = data_size;
 
        memset(&ms_data, 0, sizeof(struct mark_and_sweep_data));