diff options
Diffstat (limited to 'fs/proc/generic.c')
-rw-r--r-- | fs/proc/generic.c | 65 |
1 files changed, 54 insertions, 11 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index db7fa5cab988..fa678abc9db1 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -37,7 +37,7 @@ static int proc_match(int len, const char *name, struct proc_dir_entry *de) | |||
37 | #define PROC_BLOCK_SIZE (PAGE_SIZE - 1024) | 37 | #define PROC_BLOCK_SIZE (PAGE_SIZE - 1024) |
38 | 38 | ||
39 | static ssize_t | 39 | static ssize_t |
40 | proc_file_read(struct file *file, char __user *buf, size_t nbytes, | 40 | __proc_file_read(struct file *file, char __user *buf, size_t nbytes, |
41 | loff_t *ppos) | 41 | loff_t *ppos) |
42 | { | 42 | { |
43 | struct inode * inode = file->f_path.dentry->d_inode; | 43 | struct inode * inode = file->f_path.dentry->d_inode; |
@@ -183,19 +183,47 @@ proc_file_read(struct file *file, char __user *buf, size_t nbytes, | |||
183 | } | 183 | } |
184 | 184 | ||
185 | static ssize_t | 185 | static ssize_t |
186 | proc_file_read(struct file *file, char __user *buf, size_t nbytes, | ||
187 | loff_t *ppos) | ||
188 | { | ||
189 | struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode); | ||
190 | ssize_t rv = -EIO; | ||
191 | |||
192 | spin_lock(&pde->pde_unload_lock); | ||
193 | if (!pde->proc_fops) { | ||
194 | spin_unlock(&pde->pde_unload_lock); | ||
195 | return rv; | ||
196 | } | ||
197 | pde->pde_users++; | ||
198 | spin_unlock(&pde->pde_unload_lock); | ||
199 | |||
200 | rv = __proc_file_read(file, buf, nbytes, ppos); | ||
201 | |||
202 | pde_users_dec(pde); | ||
203 | return rv; | ||
204 | } | ||
205 | |||
206 | static ssize_t | ||
186 | proc_file_write(struct file *file, const char __user *buffer, | 207 | proc_file_write(struct file *file, const char __user *buffer, |
187 | size_t count, loff_t *ppos) | 208 | size_t count, loff_t *ppos) |
188 | { | 209 | { |
189 | struct inode *inode = file->f_path.dentry->d_inode; | 210 | struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode); |
190 | struct proc_dir_entry * dp; | 211 | ssize_t rv = -EIO; |
191 | 212 | ||
192 | dp = PDE(inode); | 213 | if (pde->write_proc) { |
193 | 214 | spin_lock(&pde->pde_unload_lock); | |
194 | if (!dp->write_proc) | 215 | if (!pde->proc_fops) { |
195 | return -EIO; | 216 | spin_unlock(&pde->pde_unload_lock); |
217 | return rv; | ||
218 | } | ||
219 | pde->pde_users++; | ||
220 | spin_unlock(&pde->pde_unload_lock); | ||
196 | 221 | ||
197 | /* FIXME: does this routine need ppos? probably... */ | 222 | /* FIXME: does this routine need ppos? probably... */ |
198 | return dp->write_proc(file, buffer, count, dp->data); | 223 | rv = pde->write_proc(file, buffer, count, pde->data); |
224 | pde_users_dec(pde); | ||
225 | } | ||
226 | return rv; | ||
199 | } | 227 | } |
200 | 228 | ||
201 | 229 | ||
@@ -307,6 +335,21 @@ static DEFINE_SPINLOCK(proc_inum_lock); /* protects the above */ | |||
307 | /* | 335 | /* |
308 | * Return an inode number between PROC_DYNAMIC_FIRST and | 336 | * Return an inode number between PROC_DYNAMIC_FIRST and |
309 | * 0xffffffff, or zero on failure. | 337 | * 0xffffffff, or zero on failure. |
338 | * | ||
339 | * Current inode allocations in the proc-fs (hex-numbers): | ||
340 | * | ||
341 | * 00000000 reserved | ||
342 | * 00000001-00000fff static entries (goners) | ||
343 | * 001 root-ino | ||
344 | * | ||
345 | * 00001000-00001fff unused | ||
346 | * 0001xxxx-7fffxxxx pid-dir entries for pid 1-7fff | ||
347 | * 80000000-efffffff unused | ||
348 | * f0000000-ffffffff dynamic entries | ||
349 | * | ||
350 | * Goal: | ||
351 | * Once we split the thing into several virtual filesystems, | ||
352 | * we will get rid of magical ranges (and this comment, BTW). | ||
310 | */ | 353 | */ |
311 | static unsigned int get_inode_number(void) | 354 | static unsigned int get_inode_number(void) |
312 | { | 355 | { |
@@ -363,7 +406,7 @@ static int proc_delete_dentry(struct dentry * dentry) | |||
363 | return 1; | 406 | return 1; |
364 | } | 407 | } |
365 | 408 | ||
366 | static struct dentry_operations proc_dentry_operations = | 409 | static const struct dentry_operations proc_dentry_operations = |
367 | { | 410 | { |
368 | .d_delete = proc_delete_dentry, | 411 | .d_delete = proc_delete_dentry, |
369 | }; | 412 | }; |