patch-2.3.99-pre9 linux/drivers/char/mem.c
Next file: linux/drivers/char/msp3400.c
Previous file: linux/drivers/char/lp.c
Back to the patch index
Back to the overall index
- Lines: 46
- Date:
Mon May 15 11:19:26 2000
- Orig file:
v2.3.99-pre8/linux/drivers/char/mem.c
- Orig date:
Tue Apr 11 15:09:16 2000
diff -u --recursive --new-file v2.3.99-pre8/linux/drivers/char/mem.c linux/drivers/char/mem.c
@@ -231,9 +231,10 @@
{
unsigned long p = *ppos;
ssize_t read = 0;
- ssize_t virtr;
+ ssize_t virtr = 0;
+ char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
- if (p < (unsigned long) high_memory) {
+ if (p < (unsigned long) high_memory) {
read = count;
if (count > (unsigned long) high_memory - p)
read = (unsigned long) high_memory - p;
@@ -258,11 +259,27 @@
count -= read;
}
- virtr = vread(buf, (char *)p, count);
- if (virtr < 0)
- return virtr;
- *ppos += p + virtr;
- return virtr + read;
+ kbuf = (char *)__get_free_page(GFP_KERNEL);
+ if (!kbuf)
+ return -ENOMEM;
+ while (count > 0) {
+ int len = count;
+
+ if (len > PAGE_SIZE)
+ len = PAGE_SIZE;
+ len = vread(kbuf, (char *)p, len);
+ if (len && copy_to_user(buf, kbuf, len)) {
+ free_page((unsigned long)kbuf);
+ return -EFAULT;
+ }
+ count -= len;
+ buf += len;
+ virtr += len;
+ p += len;
+ }
+ free_page((unsigned long)kbuf);
+ *ppos = p;
+ return virtr + read;
}
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)