From patchwork Mon Apr 23 05:45:59 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [(mtd-utils)] mtd_write: fall back to old method on ENOMEM Date: Sun, 22 Apr 2012 19:45:59 -0000 From: "Voss, Nikolaus" X-Patchwork-Id: 154321 Message-Id: To: "'linux-mtd@lists.infradead.org'" 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 --- 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 */