summaryrefslogtreecommitdiffstats
path: root/fs/proc/generic.c
diff options
context:
space:
mode:
authorDavid Howells2018-05-18 12:46:15 +0200
committerDavid Howells2018-05-18 12:46:15 +0200
commit564def71765caf65040f926c0783b9c27cc6c087 (patch)
treebf7b7051f76e961a082819f5eb126384495d0a89 /fs/proc/generic.c
parentafs: Rearrange fs/afs/proc.c to remove remaining predeclarations. (diff)
downloadkernel-qcow2-linux-564def71765caf65040f926c0783b9c27cc6c087.tar.gz
kernel-qcow2-linux-564def71765caf65040f926c0783b9c27cc6c087.tar.xz
kernel-qcow2-linux-564def71765caf65040f926c0783b9c27cc6c087.zip
proc: Add a way to make network proc files writable
Provide two extra functions, proc_create_net_data_write() and proc_create_net_single_write() that act like their non-write versions but also set a write method in the proc_dir_entry struct. An internal simple write function is provided that will copy its buffer and hand it to the pde->write() method if available (or give an error if not). The buffer may be modified by the write method. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/proc/generic.c')
-rw-r--r--fs/proc/generic.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 02bb1914f5f7..d0e5a68ae14a 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -741,3 +741,27 @@ void *PDE_DATA(const struct inode *inode)
return __PDE_DATA(inode);
}
EXPORT_SYMBOL(PDE_DATA);
+
+/*
+ * Pull a user buffer into memory and pass it to the file's write handler if
+ * one is supplied. The ->write() method is permitted to modify the
+ * kernel-side buffer.
+ */
+ssize_t proc_simple_write(struct file *f, const char __user *ubuf, size_t size,
+ loff_t *_pos)
+{
+ struct proc_dir_entry *pde = PDE(file_inode(f));
+ char *buf;
+ int ret;
+
+ if (!pde->write)
+ return -EACCES;
+ if (size == 0 || size > PAGE_SIZE - 1)
+ return -EINVAL;
+ buf = memdup_user_nul(ubuf, size);
+ if (IS_ERR(buf))
+ return PTR_ERR(buf);
+ ret = pde->write(f, buf, size);
+ kfree(buf);
+ return ret == 0 ? size : ret;
+}