Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 572d34b9 authored by Oleg Nesterov's avatar Oleg Nesterov Committed by Linus Torvalds
Browse files

proc: unify mem_read() and mem_write()



No functional changes, cleanup and preparation.

mem_read() and mem_write() are very similar. Move this code into the
new common helper, mem_rw(), which takes the additional "int write"
argument.

Cc: stable@kernel.org
Signed-off-by: default avatarOleg Nesterov <oleg@redhat.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 71879d3c
Loading
Loading
Loading
Loading
+32 −58
Original line number Diff line number Diff line
@@ -718,13 +718,13 @@ static int mem_open(struct inode* inode, struct file* file)
	return 0;
}

static ssize_t mem_read(struct file * file, char __user * buf,
			size_t count, loff_t *ppos)
static ssize_t mem_rw(struct file *file, char __user *buf,
			size_t count, loff_t *ppos, int write)
{
	int ret;
	char *page;
	unsigned long src = *ppos;
	struct mm_struct *mm = file->private_data;
	unsigned long addr = *ppos;
	ssize_t copied;
	char *page;

	if (!mm)
		return 0;
@@ -733,74 +733,48 @@ static ssize_t mem_read(struct file * file, char __user * buf,
	if (!page)
		return -ENOMEM;

	ret = 0;
 
	copied = 0;
	while (count > 0) {
		int this_len, retval;
		int this_len = min_t(int, count, PAGE_SIZE);

		this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
		retval = access_remote_vm(mm, src, page, this_len, 0);
		if (!retval) {
			if (!ret)
				ret = -EIO;
		if (write && copy_from_user(page, buf, this_len)) {
			copied = -EFAULT;
			break;
		}

		if (copy_to_user(buf, page, retval)) {
			ret = -EFAULT;
		this_len = access_remote_vm(mm, addr, page, this_len, write);
		if (!this_len) {
			if (!copied)
				copied = -EIO;
			break;
		}

		ret += retval;
		src += retval;
		buf += retval;
		count -= retval;
		if (!write && copy_to_user(buf, page, this_len)) {
			copied = -EFAULT;
			break;
		}
	*ppos = src;

		buf += this_len;
		addr += this_len;
		copied += this_len;
		count -= this_len;
	}
	*ppos = addr;

	free_page((unsigned long) page);
	return ret;
	return copied;
}

static ssize_t mem_write(struct file * file, const char __user *buf,
static ssize_t mem_read(struct file *file, char __user *buf,
			size_t count, loff_t *ppos)
{
	int copied;
	char *page;
	unsigned long dst = *ppos;
	struct mm_struct *mm = file->private_data;

	if (!mm)
		return 0;

	page = (char *)__get_free_page(GFP_TEMPORARY);
	if (!page)
		return -ENOMEM;

	copied = 0;
	while (count > 0) {
		int this_len, retval;

		this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
		if (copy_from_user(page, buf, this_len)) {
			copied = -EFAULT;
			break;
	return mem_rw(file, buf, count, ppos, 0);
}
		retval = access_remote_vm(mm, dst, page, this_len, 1);
		if (!retval) {
			if (!copied)
				copied = -EIO;
			break;
		}
		copied += retval;
		buf += retval;
		dst += retval;
		count -= retval;			
	}
	*ppos = dst;

	free_page((unsigned long) page);
	return copied;
static ssize_t mem_write(struct file *file, const char __user *buf,
			 size_t count, loff_t *ppos)
{
	return mem_rw(file, (char __user*)buf, count, ppos, 1);
}

loff_t mem_lseek(struct file *file, loff_t offset, int orig)