aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/generic.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/generic.c')
-rw-r--r--fs/proc/generic.c49
1 files changed, 25 insertions, 24 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index b638fb500743..20e5c4509a43 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -21,6 +21,8 @@
21#include <linux/bitops.h> 21#include <linux/bitops.h>
22#include <asm/uaccess.h> 22#include <asm/uaccess.h>
23 23
24#include "internal.h"
25
24static ssize_t proc_file_read(struct file *file, char __user *buf, 26static ssize_t proc_file_read(struct file *file, char __user *buf,
25 size_t nbytes, loff_t *ppos); 27 size_t nbytes, loff_t *ppos);
26static ssize_t proc_file_write(struct file *file, const char __user *buffer, 28static ssize_t proc_file_write(struct file *file, const char __user *buffer,
@@ -54,6 +56,18 @@ proc_file_read(struct file *file, char __user *buf, size_t nbytes,
54 ssize_t n, count; 56 ssize_t n, count;
55 char *start; 57 char *start;
56 struct proc_dir_entry * dp; 58 struct proc_dir_entry * dp;
59 unsigned long long pos;
60
61 /*
62 * Gaah, please just use "seq_file" instead. The legacy /proc
63 * interfaces cut loff_t down to off_t for reads, and ignore
64 * the offset entirely for writes..
65 */
66 pos = *ppos;
67 if (pos > MAX_NON_LFS)
68 return 0;
69 if (nbytes > MAX_NON_LFS - pos)
70 nbytes = MAX_NON_LFS - pos;
57 71
58 dp = PDE(inode); 72 dp = PDE(inode);
59 if (!(page = (char*) __get_free_page(GFP_KERNEL))) 73 if (!(page = (char*) __get_free_page(GFP_KERNEL)))
@@ -202,30 +216,17 @@ proc_file_write(struct file *file, const char __user *buffer,
202static loff_t 216static loff_t
203proc_file_lseek(struct file *file, loff_t offset, int orig) 217proc_file_lseek(struct file *file, loff_t offset, int orig)
204{ 218{
205 lock_kernel(); 219 loff_t retval = -EINVAL;
206 220 switch (orig) {
207 switch (orig) { 221 case 1:
208 case 0: 222 offset += file->f_pos;
209 if (offset < 0) 223 /* fallthrough */
210 goto out; 224 case 0:
211 file->f_pos = offset; 225 if (offset < 0 || offset > MAX_NON_LFS)
212 unlock_kernel(); 226 break;
213 return(file->f_pos); 227 file->f_pos = retval = offset;
214 case 1: 228 }
215 if (offset + file->f_pos < 0) 229 return retval;
216 goto out;
217 file->f_pos += offset;
218 unlock_kernel();
219 return(file->f_pos);
220 case 2:
221 goto out;
222 default:
223 goto out;
224 }
225
226out:
227 unlock_kernel();
228 return -EINVAL;
229} 230}
230 231
231static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) 232static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)