concat_write_oob() adds the OOB length written to a sub-device to the
data length that it returns, instead of the data length, and never
counts the OOB length. A write of data which fits in the first
sub-device is then reported as not written at all, so the whole length
is written again to the next sub-device, from a position past the end
of the caller's buffer, and -EINVAL is returned.
Count both lengths, as concat_read_oob() does.
concat_read_oob() also moves the OOB buffer on by the total OOB length
read so far, rather than by what the last sub-device read, so it reads
into the wrong place when it needs a third sub-device. Fix that too.
Fixes: ff94bc40af34 ("mtd, ubi, ubifs: resync with Linux-3.14")
Signed-off-by: Padmarao Begari <[email protected]>
---
Changes in v2:
- New patch: fix concat_write_oob() and concat_read_oob(), which made a
write to a concatenated NAND device fail
drivers/mtd/mtdconcat.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 51232581d96..3c79a54a659 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -285,7 +285,7 @@ concat_read_oob(struct mtd_info *mtd, loff_t from, struct
mtd_oob_ops *ops)
devops.ooblen = ops->ooblen - ops->oobretlen;
if (!devops.ooblen)
return ret;
- devops.oobbuf += ops->oobretlen;
+ devops.oobbuf += devops.oobretlen;
}
from = 0;
@@ -318,7 +318,8 @@ concat_write_oob(struct mtd_info *mtd, loff_t to, struct
mtd_oob_ops *ops)
devops.len = subdev->size - to;
err = mtd_write_oob(subdev, to, &devops);
- ops->retlen += devops.oobretlen;
+ ops->retlen += devops.retlen;
+ ops->oobretlen += devops.oobretlen;
if (err)
return err;
--
2.34.1