aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/mem.c')
-rw-r--r--drivers/char/mem.c56
1 files changed, 13 insertions, 43 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 917403fe10da..524b707894ef 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -622,53 +622,23 @@ static ssize_t splice_write_null(struct pipe_inode_info *pipe, struct file *out,
622 return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null); 622 return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null);
623} 623}
624 624
625static ssize_t read_zero(struct file *file, char __user *buf, 625static ssize_t read_iter_zero(struct kiocb *iocb, struct iov_iter *iter)
626 size_t count, loff_t *ppos)
627{ 626{
628 size_t written; 627 size_t written = 0;
629
630 if (!count)
631 return 0;
632
633 if (!access_ok(VERIFY_WRITE, buf, count))
634 return -EFAULT;
635
636 written = 0;
637 while (count) {
638 unsigned long unwritten;
639 size_t chunk = count;
640 628
629 while (iov_iter_count(iter)) {
630 size_t chunk = iov_iter_count(iter), n;
641 if (chunk > PAGE_SIZE) 631 if (chunk > PAGE_SIZE)
642 chunk = PAGE_SIZE; /* Just for latency reasons */ 632 chunk = PAGE_SIZE; /* Just for latency reasons */
643 unwritten = __clear_user(buf, chunk); 633 n = iov_iter_zero(chunk, iter);
644 written += chunk - unwritten; 634 if (!n && iov_iter_count(iter))
645 if (unwritten) 635 return written ? written : -EFAULT;
646 break; 636 written += n;
647 if (signal_pending(current)) 637 if (signal_pending(current))
648 return written ? written : -ERESTARTSYS; 638 return written ? written : -ERESTARTSYS;
649 buf += chunk;
650 count -= chunk;
651 cond_resched(); 639 cond_resched();
652 } 640 }
653 return written ? written : -EFAULT; 641 return written;
654}
655
656static ssize_t aio_read_zero(struct kiocb *iocb, const struct iovec *iov,
657 unsigned long nr_segs, loff_t pos)
658{
659 size_t written = 0;
660 unsigned long i;
661 ssize_t ret;
662
663 for (i = 0; i < nr_segs; i++) {
664 ret = read_zero(iocb->ki_filp, iov[i].iov_base, iov[i].iov_len,
665 &pos);
666 if (ret < 0)
667 break;
668 written += ret;
669 }
670
671 return written ? written : -EFAULT;
672} 642}
673 643
674static int mmap_zero(struct file *file, struct vm_area_struct *vma) 644static int mmap_zero(struct file *file, struct vm_area_struct *vma)
@@ -738,7 +708,6 @@ static int open_port(struct inode *inode, struct file *filp)
738#define zero_lseek null_lseek 708#define zero_lseek null_lseek
739#define full_lseek null_lseek 709#define full_lseek null_lseek
740#define write_zero write_null 710#define write_zero write_null
741#define read_full read_zero
742#define aio_write_zero aio_write_null 711#define aio_write_zero aio_write_null
743#define open_mem open_port 712#define open_mem open_port
744#define open_kmem open_mem 713#define open_kmem open_mem
@@ -783,9 +752,9 @@ static const struct file_operations port_fops = {
783 752
784static const struct file_operations zero_fops = { 753static const struct file_operations zero_fops = {
785 .llseek = zero_lseek, 754 .llseek = zero_lseek,
786 .read = read_zero, 755 .read = new_sync_read,
787 .write = write_zero, 756 .write = write_zero,
788 .aio_read = aio_read_zero, 757 .read_iter = read_iter_zero,
789 .aio_write = aio_write_zero, 758 .aio_write = aio_write_zero,
790 .mmap = mmap_zero, 759 .mmap = mmap_zero,
791}; 760};
@@ -802,7 +771,8 @@ static struct backing_dev_info zero_bdi = {
802 771
803static const struct file_operations full_fops = { 772static const struct file_operations full_fops = {
804 .llseek = full_lseek, 773 .llseek = full_lseek,
805 .read = read_full, 774 .read = new_sync_read,
775 .read_iter = read_iter_zero,
806 .write = write_full, 776 .write = write_full,
807}; 777};
808 778