Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] adjust /dev/{kmem,mem,port} write handlers

The /dev/mem and /dev/kmem write handlers weren't fully POSIX compliant in
that they wouldn't always force the file pointer to be updated when
returning success status.

The /dev/port write handler was inconsistent with the /dev/mem and
/dev/kmem handlers in that when encountering a -EFAULT condition after
already having written a number of items it would return -EFAULT rather
than the number of bytes written.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Jan Beulich and committed by
Linus Torvalds
c654d60e 58bf6a2d

+13 -15
+13 -15
drivers/char/mem.c
··· 216 216 217 217 copied = copy_from_user(ptr, buf, sz); 218 218 if (copied) { 219 - ssize_t ret; 220 - 221 - ret = written + (sz - copied); 222 - if (ret) 223 - return ret; 219 + written += sz - copied; 220 + if (written) 221 + break; 224 222 return -EFAULT; 225 223 } 226 224 buf += sz; ··· 454 456 455 457 copied = copy_from_user(ptr, buf, sz); 456 458 if (copied) { 457 - ssize_t ret; 458 - 459 - ret = written + (sz - copied); 460 - if (ret) 461 - return ret; 459 + written += sz - copied; 460 + if (written) 461 + break; 462 462 return -EFAULT; 463 463 } 464 464 buf += sz; ··· 510 514 if (len) { 511 515 written = copy_from_user(kbuf, buf, len); 512 516 if (written) { 513 - ssize_t ret; 514 - 517 + if (wrote + virtr) 518 + break; 515 519 free_page((unsigned long)kbuf); 516 - ret = wrote + virtr + (len - written); 517 - return ret ? ret : -EFAULT; 520 + return -EFAULT; 518 521 } 519 522 } 520 523 len = vwrite(kbuf, (char *)p, len); ··· 558 563 return -EFAULT; 559 564 while (count-- > 0 && i < 65536) { 560 565 char c; 561 - if (__get_user(c, tmp)) 566 + if (__get_user(c, tmp)) { 567 + if (tmp > buf) 568 + break; 562 569 return -EFAULT; 570 + } 563 571 outb(c,i); 564 572 i++; 565 573 tmp++;