[PATCH (mtd-utils)] mtd_write: fall back to old method on ENOMEM

Voss, Nikolaus N.Voss at weinmann.de
Mon Apr 23 01:45:59 EDT 2012


MEMWRITE ioctl tries to kmalloc the whole data. With usual
eraseblock sizes of 128 KiB, on memory constrained systems
this can easily lead to ENOMEM due to memory fragmentation
even if there are plenty of free pages left e.g.:

--------------------------------------------------------------

libmtd: error!: MEMWRITE ioctl failed for eraseblock 55 (mtd6)
        error 12 (Cannot allocate memory)
ubiformat: error!: cannot write eraseblock 55
           error 12 (Cannot allocate memory)

Kernel log:
[   67.870000] Normal: 85*4kB 37*8kB 15*16kB 4*32kB 8*64kB 0*128kB 0*256kB
0*512kB 0*1024kB 0*2048kB 0*4096kB = 1516kB
[   67.870000] 11214 total pagecache pages
[   67.873000] 16384 pages of RAM
[   67.873000] 493 free pages
[   67.873000] 1067 reserved pages
[   67.873000] 887 slab pages
[   67.873000] 6266 pages shared 
[   67.873000] 0 pages swap cached

--------------------------------------------------------------

In such a case, it is better to write slower than not at all.

Signed-off-by: Nikolaus Voss <n.voss at weinmann.de>
---
 lib/libmtd.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/libmtd.c b/lib/libmtd.c
index 9b247ae..9d24ef0 100644
--- a/lib/libmtd.c
+++ b/lib/libmtd.c
@@ -1151,7 +1151,7 @@ int mtd_write(libmtd_t desc, const struct mtd_dev_info *mtd, int fd, int eb,
 	ret = ioctl(fd, MEMWRITE, &ops);
 	if (ret == 0)
 		return 0;
-	else if (errno != ENOTTY && errno != EOPNOTSUPP)
+	else if (errno != ENOTTY && errno != EOPNOTSUPP && errno != ENOMEM)
 		return mtd_ioctl_error(mtd, eb, "MEMWRITE");
 
 	/* Fall back to old methods if necessary */
-- 
1.7.5.4




More information about the linux-mtd mailing list