/*
  * Get information for all chunks from the device.
  *
- * The caller is responsible for freeing the returned structure
+ * The caller is responsible for freeing (vmalloc) the returned structure
  */
 struct nvm_chk_meta *pblk_get_chunk_meta(struct pblk *pblk)
 {
        ppa.ppa = 0;
 
        len = geo->all_chunks * sizeof(*meta);
-       meta = kzalloc(len, GFP_KERNEL);
+       meta = vzalloc(len);
        if (!meta)
                return ERR_PTR(-ENOMEM);
 
 
        struct nvm_geo *geo = &ndev->geo;
        struct nvme_ns *ns = ndev->q->queuedata;
        struct nvme_ctrl *ctrl = ns->ctrl;
-       struct nvme_nvm_chk_meta *dev_meta = (struct nvme_nvm_chk_meta *)meta;
+       struct nvme_nvm_chk_meta *dev_meta, *dev_meta_off;
        struct ppa_addr ppa;
        size_t left = nchks * sizeof(struct nvme_nvm_chk_meta);
        size_t log_pos, offset, len;
         */
        max_len = min_t(unsigned int, ctrl->max_hw_sectors << 9, 256 * 1024);
 
+       dev_meta = kmalloc(max_len, GFP_KERNEL);
+       if (!dev_meta)
+               return -ENOMEM;
+
        /* Normalize lba address space to obtain log offset */
        ppa.ppa = slba;
        ppa = dev_to_generic_addr(ndev, ppa);
        while (left) {
                len = min_t(unsigned int, left, max_len);
 
+               memset(dev_meta, 0, max_len);
+               dev_meta_off = dev_meta;
+
                ret = nvme_get_log(ctrl, ns->head->ns_id,
                                NVME_NVM_LOG_REPORT_CHUNK, 0, dev_meta, len,
                                offset);
                }
 
                for (i = 0; i < len; i += sizeof(struct nvme_nvm_chk_meta)) {
-                       meta->state = dev_meta->state;
-                       meta->type = dev_meta->type;
-                       meta->wi = dev_meta->wi;
-                       meta->slba = le64_to_cpu(dev_meta->slba);
-                       meta->cnlb = le64_to_cpu(dev_meta->cnlb);
-                       meta->wp = le64_to_cpu(dev_meta->wp);
+                       meta->state = dev_meta_off->state;
+                       meta->type = dev_meta_off->type;
+                       meta->wi = dev_meta_off->wi;
+                       meta->slba = le64_to_cpu(dev_meta_off->slba);
+                       meta->cnlb = le64_to_cpu(dev_meta_off->cnlb);
+                       meta->wp = le64_to_cpu(dev_meta_off->wp);
 
                        meta++;
-                       dev_meta++;
+                       dev_meta_off++;
                }
 
                offset += len;
                left -= len;
        }
 
+       kfree(dev_meta);
+
        return ret;
 }