nandwrite - handle situation when read returns less bytes the expected

Submitted by Artem Bityutskiy on Dec. 16, 2008, 6:28 a.m.

Details

Message ID 1229408910.4911.72.camel@sauron
State Accepted
Commit f1076eedef167ae28740a6844985a064a474fdfa
Headers show

Commit Message

Artem Bityutskiy Dec. 16, 2008, 6:28 a.m.
On Sun, 2008-12-14 at 15:59 +0200, Hai Zaar wrote:
> Good day!
> I've found a bug: nandwrite does not handle the situation when read
> syscall returns less bytes when expected. Instead of requesting more
> input, nandwrite just aborts with error.
> The bug is especially triggered when input comes from stdin[1] which
> is filled from remote host.
> 
> [1] http://lists.infradead.org/pipermail/linux-mtd/2008-September/022913.html.
> BTW - is it going to be applied?
> 
> P.S. I'm not on the list, so please CC me.

Your patch does not apply. It looks like it is not against the latest
mtd-utils. How about this patch?

From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Date: Tue, 16 Dec 2008 10:02:16 +0200
Subject: [PATCH] nandwrite: correct data reading

The "read" syscall does not necessarily return all the requested
data, in which case the caller has to try again and read more.
Take this into account when reading input data.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
---
 nandwrite.c |   31 +++++++++++++++++++++++--------
 1 files changed, 23 insertions(+), 8 deletions(-)

Comments

Hai Zaar Dec. 16, 2008, 8:40 a.m.
On Tue, Dec 16, 2008 at 8:28 AM, Artem Bityutskiy
<dedekind@infradead.org> wrote:
>
> Your patch does not apply. It looks like it is not against the latest
> mtd-utils. How about this patch?
Yes, my patch is against mtd-utils-1.2.0. Yours is surely better since
it covers oob reading as well.

>
> From: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
> Date: Tue, 16 Dec 2008 10:02:16 +0200
> Subject: [PATCH] nandwrite: correct data reading
>
> The "read" syscall does not necessarily return all the requested
> data, in which case the caller has to try again and read more.
> Take this into account when reading input data.
>
> Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
> ---
>  nandwrite.c |   31 +++++++++++++++++++++++--------
>  1 files changed, 23 insertions(+), 8 deletions(-)
>
> diff --git a/nandwrite.c b/nandwrite.c
> index fc23e85..0b2a9ee 100644
> --- a/nandwrite.c
> +++ b/nandwrite.c
> @@ -260,6 +260,7 @@ int main(int argc, char * const argv[])
>        int ret, readlen;
>        int oobinfochanged = 0;
>        struct nand_oobinfo old_oobinfo;
> +       int readcnt = 0;
>
>        process_options(argc, argv);
>
> @@ -477,6 +478,8 @@ int main(int argc, char * const argv[])
>                readlen = meminfo.writesize;
>
>                if (ifd != STDIN_FILENO) {
> +                       int tinycnt = 0;
> +
>                        if (pad && (imglen < readlen))
>                        {
>                                readlen = imglen;
> @@ -484,11 +487,15 @@ int main(int argc, char * const argv[])
>                        }
>
>                        /* Read Page Data from input file */
> -                       if ((cnt = read(ifd, writebuf, readlen)) != readlen) {
> -                               if (cnt == 0)   // EOF
> +                       while(tinycnt < readlen) {
> +                               cnt = read(ifd, writebuf + tinycnt, readlen - tinycnt);
> +                               if (cnt == 0) { // EOF
>                                        break;
> -                               perror ("File I/O error on input file");
> -                               goto closeall;
> +                               } else if (cnt < 0) {
> +                                       perror ("File I/O error on input file");
> +                                       goto closeall;
> +                               }
> +                               tinycnt += cnt;
>                        }
>                } else {
>                        int tinycnt = 0;
> @@ -522,11 +529,19 @@ int main(int argc, char * const argv[])
>                }
>
>                if (writeoob) {
> -                       /* Read OOB data from input file, exit on failure */
> -                       if ((cnt = read(ifd, oobreadbuf, meminfo.oobsize)) != meminfo.oobsize) {
> -                               perror ("File I/O error on input file");
> -                               goto closeall;
> +                       int tinycnt = 0;
> +
> +                       while(tinycnt < readlen) {
> +                               cnt = read(ifd, oobreadbuf + tinycnt, meminfo.oobsize - tinycnt);
> +                               if (cnt == 0) { // EOF
> +                                       break;
> +                               } else if (cnt < 0) {
> +                                       perror ("File I/O error on input file");
> +                                       goto closeall;
> +                               }
> +                               tinycnt += cnt;
>                        }
> +
>                        if (!noecc) {
>                                int i, start, len;
>                                /*
> --
> 1.5.4.3
>
> --
> Best regards,
> Artem Bityutskiy (Битюцкий Артём)
>
>

Patch hide | download patch | download mbox

diff --git a/nandwrite.c b/nandwrite.c
index fc23e85..0b2a9ee 100644
--- a/nandwrite.c
+++ b/nandwrite.c
@@ -260,6 +260,7 @@  int main(int argc, char * const argv[])
 	int ret, readlen;
 	int oobinfochanged = 0;
 	struct nand_oobinfo old_oobinfo;
+	int readcnt = 0;
 
 	process_options(argc, argv);
 
@@ -477,6 +478,8 @@  int main(int argc, char * const argv[])
 		readlen = meminfo.writesize;
 
 		if (ifd != STDIN_FILENO) {
+			int tinycnt = 0;
+
 			if (pad && (imglen < readlen))
 			{
 				readlen = imglen;
@@ -484,11 +487,15 @@  int main(int argc, char * const argv[])
 			}
 
 			/* Read Page Data from input file */
-			if ((cnt = read(ifd, writebuf, readlen)) != readlen) {
-				if (cnt == 0)	// EOF
+			while(tinycnt < readlen) {
+				cnt = read(ifd, writebuf + tinycnt, readlen - tinycnt);
+				if (cnt == 0) { // EOF
 					break;
-				perror ("File I/O error on input file");
-				goto closeall;
+				} else if (cnt < 0) {
+					perror ("File I/O error on input file");
+					goto closeall;
+				}
+				tinycnt += cnt;
 			}
 		} else {
 			int tinycnt = 0;
@@ -522,11 +529,19 @@  int main(int argc, char * const argv[])
 		}
 
 		if (writeoob) {
-			/* Read OOB data from input file, exit on failure */
-			if ((cnt = read(ifd, oobreadbuf, meminfo.oobsize)) != meminfo.oobsize) {
-				perror ("File I/O error on input file");
-				goto closeall;
+			int tinycnt = 0;
+
+			while(tinycnt < readlen) {
+				cnt = read(ifd, oobreadbuf + tinycnt, meminfo.oobsize - tinycnt);
+				if (cnt == 0) { // EOF
+					break;
+				} else if (cnt < 0) {
+					perror ("File I/O error on input file");
+					goto closeall;
+				}
+				tinycnt += cnt;
 			}
+
 			if (!noecc) {
 				int i, start, len;
 				/*