Message ID | 20230323140350.69908-1-libang.linuxer@gmail.com |
---|---|
State | Changes Requested |
Headers | show |
Series | mtdblock: tolerate corrected bit-flips | expand |
Hello, libang.linuxer@gmail.com wrote on Thu, 23 Mar 2023 22:03:50 +0800: > mtd_read() may return -EUCLEAN in case of corrected bit-flips.This > particular condition should not be treated like an error. I'm fine with the patch, Richard, are you okay as well? > Signed-off-by: Bang Li <libang.linuxer@gmail.com> > --- > drivers/mtd/mtdblock.c | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > > diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c > index 1e94e7d10b8b..a0a1194dc1d9 100644 > --- a/drivers/mtd/mtdblock.c > +++ b/drivers/mtd/mtdblock.c > @@ -153,7 +153,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, > mtdblk->cache_state = STATE_EMPTY; > ret = mtd_read(mtd, sect_start, sect_size, > &retlen, mtdblk->cache_data); > - if (ret) > + if (ret && !mtd_is_bitflip(ret)) > return ret; > if (retlen != sect_size) > return -EIO; > @@ -188,8 +188,12 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, > pr_debug("mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n", > mtd->name, pos, len); > > - if (!sect_size) > - return mtd_read(mtd, pos, len, &retlen, buf); > + if (!sect_size) { > + ret = mtd_read(mtd, pos, len, &retlen, buf); > + if (ret && !mtd_is_bitflip(ret)) > + return ret; > + return 0; > + } > > while (len > 0) { > unsigned long sect_start = (pos/sect_size)*sect_size; > @@ -209,7 +213,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, > memcpy (buf, mtdblk->cache_data + offset, size); > } else { > ret = mtd_read(mtd, pos, size, &retlen, buf); > - if (ret) > + if (ret && !mtd_is_bitflip(ret)) > return ret; > if (retlen != size) > return -EIO; Thanks, Miquèl
Hi! ----- Ursprüngliche Mail ----- > libang.linuxer@gmail.com wrote on Thu, 23 Mar 2023 22:03:50 +0800: > >> mtd_read() may return -EUCLEAN in case of corrected bit-flips.This >> particular condition should not be treated like an error. > > I'm fine with the patch, Richard, are you okay as well? Hm yes. I see the bug. I think it broke about 10 years ago by e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()"). In the early day I'd expect someone to hit this bug but I guess on the last 10 years mtdblock had no real users. Thanks, //richard
Hi Richard, richard@nod.at wrote on Tue, 28 Mar 2023 15:21:50 +0200 (CEST): > Hi! > > ----- Ursprüngliche Mail ----- > > libang.linuxer@gmail.com wrote on Thu, 23 Mar 2023 22:03:50 +0800: > > > >> mtd_read() may return -EUCLEAN in case of corrected bit-flips.This > >> particular condition should not be treated like an error. > > > > I'm fine with the patch, Richard, are you okay as well? > > Hm yes. I see the bug. I think it broke about 10 years ago > by e47f68587b82 ("mtd: check for max_bitflips in mtd_read_oob()"). > > In the early day I'd expect someone to hit this bug but I guess > on the last 10 years mtdblock had no real users. Right. Well, anyhow I guess this patch deserves a Fixes/Cc: stable # v3.7+ Li, can you please re-send with the proper tags? Thanks. Thanks, Miquèl
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c index 1e94e7d10b8b..a0a1194dc1d9 100644 --- a/drivers/mtd/mtdblock.c +++ b/drivers/mtd/mtdblock.c @@ -153,7 +153,7 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, mtdblk->cache_state = STATE_EMPTY; ret = mtd_read(mtd, sect_start, sect_size, &retlen, mtdblk->cache_data); - if (ret) + if (ret && !mtd_is_bitflip(ret)) return ret; if (retlen != sect_size) return -EIO; @@ -188,8 +188,12 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, pr_debug("mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n", mtd->name, pos, len); - if (!sect_size) - return mtd_read(mtd, pos, len, &retlen, buf); + if (!sect_size) { + ret = mtd_read(mtd, pos, len, &retlen, buf); + if (ret && !mtd_is_bitflip(ret)) + return ret; + return 0; + } while (len > 0) { unsigned long sect_start = (pos/sect_size)*sect_size; @@ -209,7 +213,7 @@ static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, memcpy (buf, mtdblk->cache_data + offset, size); } else { ret = mtd_read(mtd, pos, size, &retlen, buf); - if (ret) + if (ret && !mtd_is_bitflip(ret)) return ret; if (retlen != size) return -EIO;
mtd_read() may return -EUCLEAN in case of corrected bit-flips.This particular condition should not be treated like an error. Signed-off-by: Bang Li <libang.linuxer@gmail.com> --- drivers/mtd/mtdblock.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)