diff options
Diffstat (limited to 'fs/proc/generic.c')
-rw-r--r-- | fs/proc/generic.c | 49 |
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 | |||
24 | static ssize_t proc_file_read(struct file *file, char __user *buf, | 26 | static 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); |
26 | static ssize_t proc_file_write(struct file *file, const char __user *buffer, | 28 | static 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, | |||
202 | static loff_t | 216 | static loff_t |
203 | proc_file_lseek(struct file *file, loff_t offset, int orig) | 217 | proc_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 | |||
226 | out: | ||
227 | unlock_kernel(); | ||
228 | return -EINVAL; | ||
229 | } | 230 | } |
230 | 231 | ||
231 | static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) | 232 | static int proc_notify_change(struct dentry *dentry, struct iattr *iattr) |