lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 13 Apr 2016 16:27:52 +0800
From:	Wenwei Tao <ww.tao0320@...il.com>
To:	mb@...htnvm.io
Cc:	linux-kernel@...r.kernel.org, linux-block@...r.kernel.org
Subject: [PATCH 3/3] lightnvm: fix address issues related to multi target

In rrpc, some of the address operations are based on
one target assumption, the global values are always
used. Now multi target is available, we should use
relative/global values properly.

In rrpc_l2p_update, we use relative logical address
to deal with trans_map and rev_trans_map, and check
the bound of target's own intead of global device's.

In rrpc_block_map_update, we should use the global
physcical address to compare with the one in trans_map,
since we store the global value in it.

Signed-off-by: Wenwei Tao <ww.tao0320@...il.com>
---
 drivers/lightnvm/rrpc.c | 39 ++++++++++++++++++---------------------
 1 file changed, 18 insertions(+), 21 deletions(-)

diff --git a/drivers/lightnvm/rrpc.c b/drivers/lightnvm/rrpc.c
index 3143b98..159dc3b 100644
--- a/drivers/lightnvm/rrpc.c
+++ b/drivers/lightnvm/rrpc.c
@@ -116,15 +116,6 @@ static int block_is_full(struct rrpc *rrpc, struct rrpc_block *rblk)
 	return (rblk->next_page == rrpc->dev->sec_per_blk);
 }
 
-/* Calculate relative addr for the given block, considering instantiated LUNs */
-static u64 block_to_rel_addr(struct rrpc *rrpc, struct rrpc_block *rblk)
-{
-	struct nvm_block *blk = rblk->parent;
-	int lun_blk = blk->id % (rrpc->dev->blks_per_lun * rrpc->nr_luns);
-
-	return lun_blk * rrpc->dev->sec_per_blk;
-}
-
 /* Calculate global addr for the given block */
 static u64 block_to_addr(struct rrpc *rrpc, struct rrpc_block *rblk)
 {
@@ -997,24 +988,29 @@ static void rrpc_map_free(struct rrpc *rrpc)
 static int rrpc_l2p_update(u64 slba, u32 nlb, __le64 *entries, void *private)
 {
 	struct rrpc *rrpc = (struct rrpc *)private;
-	struct nvm_dev *dev = rrpc->dev;
-	struct rrpc_addr *addr = rrpc->trans_map + slba;
-	struct rrpc_rev_addr *raddr = rrpc->rev_trans_map;
-	u64 elba = slba + nlb;
-	u64 i;
+	struct rrpc_addr *addr;
+	struct rrpc_rev_addr *raddr;
+	u64 i, elba = slba + nlb - 1;
 
-	if (unlikely(elba > dev->total_secs)) {
+	if (unlikely(slba < rrpc->soffset ||
+			elba > rrpc->soffset + rrpc->nr_sects - 1)) {
 		pr_err("nvm: L2P data from device is out of bounds!\n");
 		return -EINVAL;
 	}
 
+	slba -= rrpc->soffset;
+	addr = rrpc->trans_map + slba;
+	raddr = rrpc->rev_trans_map;
+
 	for (i = 0; i < nlb; i++) {
 		u64 pba = le64_to_cpu(entries[i]);
 		unsigned int mod;
 		/* LNVM treats address-spaces as silos, LBA and PBA are
 		 * equally large and zero-indexed.
 		 */
-		if (unlikely(pba >= dev->total_secs && pba != U64_MAX)) {
+		if (unlikely((pba < rrpc->poffset ||
+			pba > rrpc->poffset + rrpc->nr_sects - 1) &&
+					(pba != U64_MAX && pba != 0))) {
 			pr_err("nvm: L2P data entry is out of bounds!\n");
 			return -EINVAL;
 		}
@@ -1289,19 +1285,20 @@ static void rrpc_block_map_update(struct rrpc *rrpc, struct rrpc_block *rblk)
 	struct nvm_dev *dev = rrpc->dev;
 	int offset;
 	struct rrpc_addr *laddr;
-	u64 bpaddr, paddr, pladdr;
+	u64 paddr, rpaddr, pladdr;
+
+	paddr = block_to_addr(rrpc, rblk);
+	rpaddr = paddr - rrpc->poffset;
 
-	bpaddr = block_to_rel_addr(rrpc, rblk);
 	for (offset = 0; offset < dev->sec_per_blk; offset++) {
-		paddr = bpaddr + offset;
 
-		pladdr = rrpc->rev_trans_map[paddr].addr;
+		pladdr = rrpc->rev_trans_map[rpaddr + offset].addr;
 		if (pladdr == ADDR_EMPTY)
 			continue;
 
 		laddr = &rrpc->trans_map[pladdr];
 
-		if (paddr == laddr->addr) {
+		if (paddr + offset == laddr->addr) {
 			laddr->rblk = rblk;
 		} else {
 			set_bit(offset, rblk->invalid_pages);
-- 
1.8.3.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ