[PATCH] devmem: handle partial kmem write/read

From: Wu Fengguang
Date: Sun Sep 13 2009 - 23:29:20 EST


Current vwrite silently ignores vwrite() to vmap holes.
Better behavior should be stop the write and return
on such holes.

Also return on partial read, which may happen in future
(eg. hit hwpoison pages).

CC: Andi Kleen <andi@xxxxxxxxxxxxxx>
Signed-off-by: Wu Fengguang <fengguang.wu@xxxxxxxxx>
---
drivers/char/mem.c | 30 ++++++++++++++++++------------
1 file changed, 18 insertions(+), 12 deletions(-)

--- linux-mm.orig/drivers/char/mem.c 2009-09-14 10:59:50.000000000 +0800
+++ linux-mm/drivers/char/mem.c 2009-09-14 11:06:25.000000000 +0800
@@ -444,18 +444,22 @@ static ssize_t read_kmem(struct file *fi
if (!kbuf)
return -ENOMEM;
while (count > 0) {
+ unsigned long n;
+
sz = size_inside_page(p, count);
- sz = vread(kbuf, (char *)p, sz);
- if (!sz)
+ n = vread(kbuf, (char *)p, sz);
+ if (!n)
break;
- if (copy_to_user(buf, kbuf, sz)) {
+ if (copy_to_user(buf, kbuf, n)) {
free_page((unsigned long)kbuf);
return -EFAULT;
}
- count -= sz;
- buf += sz;
- read += sz;
- p += sz;
+ count -= n;
+ buf += n;
+ read += n;
+ p += n;
+ if (n < sz)
+ break;
}
free_page((unsigned long)kbuf);
}
@@ -551,11 +555,13 @@ static ssize_t write_kmem(struct file *
free_page((unsigned long)kbuf);
return -EFAULT;
}
- sz = vwrite(kbuf, (char *)p, sz);
- count -= sz;
- buf += sz;
- virtr += sz;
- p += sz;
+ n = vwrite(kbuf, (char *)p, sz);
+ count -= n;
+ buf += n;
+ virtr += n;
+ p += n;
+ if (n < sz)
+ break;
}
free_page((unsigned long)kbuf);
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/