summaryrefslogtreecommitdiff
path: root/drivers/char/mem.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-13 11:28:42 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-13 11:28:42 +0200
commit77c688ac87183537ed0fb84ec2cb8fa8ec97c458 (patch)
treed18e117e05c0d71463823536165ddd9ad75b6bc5 /drivers/char/mem.c
parent5e40d331bd72447197f26525f21711c4a265b6a6 (diff)
parenta457606a6f81cfddfc9da1ef2a8bf2c65a8eb35e (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs updates from Al Viro: "The big thing in this pile is Eric's unmount-on-rmdir series; we finally have everything we need for that. The final piece of prereqs is delayed mntput() - now filesystem shutdown always happens on shallow stack. Other than that, we have several new primitives for iov_iter (Matt Wilcox, culled from his XIP-related series) pushing the conversion to ->read_iter()/ ->write_iter() a bit more, a bunch of fs/dcache.c cleanups and fixes (including the external name refcounting, which gives consistent behaviour of d_move() wrt procfs symlinks for long and short names alike) and assorted cleanups and fixes all over the place. This is just the first pile; there's a lot of stuff from various people that ought to go in this window. Starting with unionmount/overlayfs mess... ;-/" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (60 commits) fs/file_table.c: Update alloc_file() comment vfs: Deduplicate code shared by xattr system calls operating on paths reiserfs: remove pointless forward declaration of struct nameidata don't need that forward declaration of struct nameidata in dcache.h anymore take dname_external() into fs/dcache.c let path_init() failures treated the same way as subsequent link_path_walk() fix misuses of f_count() in ppp and netlink ncpfs: use list_for_each_entry() for d_subdirs walk vfs: move getname() from callers to do_mount() gfs2_atomic_open(): skip lookups on hashed dentry [infiniband] remove pointless assignments gadgetfs: saner API for gadgetfs_create_file() f_fs: saner API for ffs_sb_create_file() jfs: don't hash direct inode [s390] remove pointless assignment of ->f_op in vmlogrdr ->open() ecryptfs: ->f_op is never NULL android: ->f_op is never NULL nouveau: __iomem misannotations missing annotation in fs/file.c fs: namespace: suppress 'may be used uninitialized' warnings ...
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,
return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null);
}
-static ssize_t read_zero(struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
+static ssize_t read_iter_zero(struct kiocb *iocb, struct iov_iter *iter)
{
- size_t written;
-
- if (!count)
- return 0;
-
- if (!access_ok(VERIFY_WRITE, buf, count))
- return -EFAULT;
-
- written = 0;
- while (count) {
- unsigned long unwritten;
- size_t chunk = count;
+ size_t written = 0;
+ while (iov_iter_count(iter)) {
+ size_t chunk = iov_iter_count(iter), n;
if (chunk > PAGE_SIZE)
chunk = PAGE_SIZE; /* Just for latency reasons */
- unwritten = __clear_user(buf, chunk);
- written += chunk - unwritten;
- if (unwritten)
- break;
+ n = iov_iter_zero(chunk, iter);
+ if (!n && iov_iter_count(iter))
+ return written ? written : -EFAULT;
+ written += n;
if (signal_pending(current))
return written ? written : -ERESTARTSYS;
- buf += chunk;
- count -= chunk;
cond_resched();
}
- return written ? written : -EFAULT;
-}
-
-static ssize_t aio_read_zero(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos)
-{
- size_t written = 0;
- unsigned long i;
- ssize_t ret;
-
- for (i = 0; i < nr_segs; i++) {
- ret = read_zero(iocb->ki_filp, iov[i].iov_base, iov[i].iov_len,
- &pos);
- if (ret < 0)
- break;
- written += ret;
- }
-
- return written ? written : -EFAULT;
+ return written;
}
static 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)
#define zero_lseek null_lseek
#define full_lseek null_lseek
#define write_zero write_null
-#define read_full read_zero
#define aio_write_zero aio_write_null
#define open_mem open_port
#define open_kmem open_mem
@@ -783,9 +752,9 @@ static const struct file_operations port_fops = {
static const struct file_operations zero_fops = {
.llseek = zero_lseek,
- .read = read_zero,
+ .read = new_sync_read,
.write = write_zero,
- .aio_read = aio_read_zero,
+ .read_iter = read_iter_zero,
.aio_write = aio_write_zero,
.mmap = mmap_zero,
};
@@ -802,7 +771,8 @@ static struct backing_dev_info zero_bdi = {
static const struct file_operations full_fops = {
.llseek = full_lseek,
- .read = read_full,
+ .read = new_sync_read,
+ .read_iter = read_iter_zero,
.write = write_full,
};