Merge "[Bugfix][API-1423]Fix the problem that oemapp is not mounted-- mtk patch" into GSW3.0-No-Connman
diff --git a/src/kernel/linux/v4.19/drivers/mtd/mtdblock.c b/src/kernel/linux/v4.19/drivers/mtd/mtdblock.c
old mode 100644
new mode 100755
index a5b1933..5eb0e7c
--- a/src/kernel/linux/v4.19/drivers/mtd/mtdblock.c
+++ b/src/kernel/linux/v4.19/drivers/mtd/mtdblock.c
@@ -43,6 +43,7 @@
 	unsigned long cache_offset;
 	unsigned int cache_size;
 	enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state;
+	unsigned short *block_mapping;
 };
 
 /*
@@ -238,7 +239,22 @@
 			      unsigned long block, char *buf)
 {
 	struct mtdblk_dev *mtdblk = container_of(dev, struct mtdblk_dev, mbd);
-	return do_cached_read(mtdblk, block<<9, 512, buf);
+	struct mtd_info *mtd = dev->mtd;
+	unsigned short target_block, total_blocks;
+	unsigned long pos;
+
+	if (!mtdblk->block_mapping)
+		return do_cached_read(mtdblk, block << 9, 512, buf);
+
+	total_blocks = (unsigned short) ((uint32_t)mtd->size / mtd->erasesize);
+	target_block = mtdblk->block_mapping[(block << 9) / mtd->erasesize];
+	if (target_block >= total_blocks)
+		return -EIO;
+
+	pos = target_block * mtdblk->mbd.mtd->erasesize +
+		((block << 9) & (mtdblk->mbd.mtd->erasesize - 1));
+	return do_cached_read(mtdblk, pos, 512, buf);
+
 }
 
 static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
@@ -260,6 +276,8 @@
 static int mtdblock_open(struct mtd_blktrans_dev *mbd)
 {
 	struct mtdblk_dev *mtdblk = container_of(mbd, struct mtdblk_dev, mbd);
+	struct mtd_info *mtd = mbd->mtd;
+	unsigned short total_blocks;
 
 	pr_debug("mtdblock_open\n");
 
@@ -277,6 +295,26 @@
 		mtdblk->cache_data = NULL;
 	}
 
+	total_blocks = (unsigned short) ((uint32_t)mtd->size / mtd->erasesize);
+	mtdblk->block_mapping =
+		vmalloc(total_blocks * sizeof(mtdblk->block_mapping[0]));
+	if (mtdblk->block_mapping) {
+		unsigned short i, idx = 0;
+
+		memset(mtdblk->block_mapping, 0xFF,
+		       total_blocks * sizeof(mtdblk->block_mapping[0]));
+		for (i = 0; i < total_blocks; i++) {
+			if (mtd->_block_isbad(mtd, i * mtd->erasesize)) {
+				pr_info("MTDBLOCK%d: block %d is bad\n",
+				       mtd->index, i);
+				continue;
+			}
+
+			mtdblk->block_mapping[idx] = i;
+			idx++;
+		}
+	}
+
 	pr_debug("ok\n");
 
 	return 0;
@@ -300,6 +338,11 @@
 		if (mbd->file_mode & FMODE_WRITE)
 			mtd_sync(mbd->mtd);
 		vfree(mtdblk->cache_data);
+
+		if (mtdblk->block_mapping) {
+			vfree(mtdblk->block_mapping);
+			mtdblk->block_mapping = NULL;
+		}
 	}
 
 	pr_debug("ok\n");