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.c65
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
39static ssize_t 39static ssize_t
40proc_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
185static ssize_t 185static ssize_t
186proc_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
206static ssize_t
186proc_file_write(struct file *file, const char __user *buffer, 207proc_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 */
311static unsigned int get_inode_number(void) 354static 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
366static struct dentry_operations proc_dentry_operations = 409static const struct dentry_operations proc_dentry_operations =
367{ 410{
368 .d_delete = proc_delete_dentry, 411 .d_delete = proc_delete_dentry,
369}; 412};