mtd: check for max_bitflips in mtd_read_oob()

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Sat Sep 29 10:59:03 EDT 2012


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=e47f68587b8255410e79166cbdecae290ca8a84e
Commit:     e47f68587b8255410e79166cbdecae290ca8a84e
Parent:     8bb8b85f6732ed579222a465d0749f66a3cace4d
Author:     Brian Norris <computersforpeace at gmail.com>
AuthorDate: Fri Jun 22 16:35:39 2012 -0700
Committer:  David Woodhouse <David.Woodhouse at intel.com>
CommitDate: Sat Sep 29 14:50:50 2012 +0100

    mtd: check for max_bitflips in mtd_read_oob()
    
    mtd_read_oob() has some unexpected similarities to mtd_read(). For
    instance, when ops->datbuf != NULL, nand_base.c might return max_bitflips;
    however, when ops->datbuf == NULL, nand_base's code potentially could
    return -EUCLEAN (no in-tree drivers do this yet). In any case where the
    driver might return max_bitflips, we should translate this into an
    appropriate return code using the bitflip_threshold.
    
    Essentially, mtd_read_oob() duplicates the logic from mtd_read().
    
    This prevents users of mtd_read_oob() from receiving a positive return
    value (i.e., from max_bitflips) and interpreting it as an unknown error.
    
    Artem: amend comments.
    
    Signed-off-by: Brian Norris <computersforpeace at gmail.com>
    Reviewed-by: Mike Dunn <mikedunn at newsguy.com>
    Reviewed-by: Shmulik Ladkani <shmulik.ladkani at gmail.com>
    Signed-off-by: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
    Signed-off-by: David Woodhouse <David.Woodhouse at intel.com>
---
 drivers/mtd/mtdcore.c |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index fcfce24..ec794a7 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -860,10 +860,22 @@ EXPORT_SYMBOL_GPL(mtd_panic_write);
 
 int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
 {
+	int ret_code;
 	ops->retlen = ops->oobretlen = 0;
 	if (!mtd->_read_oob)
 		return -EOPNOTSUPP;
-	return mtd->_read_oob(mtd, from, ops);
+	/*
+	 * In cases where ops->datbuf != NULL, mtd->_read_oob() has semantics
+	 * similar to mtd->_read(), returning a non-negative integer
+	 * representing max bitflips. In other cases, mtd->_read_oob() may
+	 * return -EUCLEAN. In all cases, perform similar logic to mtd_read().
+	 */
+	ret_code = mtd->_read_oob(mtd, from, ops);
+	if (unlikely(ret_code < 0))
+		return ret_code;
+	if (mtd->ecc_strength == 0)
+		return 0;	/* device lacks ecc */
+	return ret_code >= mtd->bitflip_threshold ? -EUCLEAN : 0;
 }
 EXPORT_SYMBOL_GPL(mtd_read_oob);
 



More information about the linux-mtd-cvs mailing list