diff options
| -rw-r--r-- | fs/proc/generic.c | 48 | ||||
| -rw-r--r-- | fs/proc/inode.c | 2 | ||||
| -rw-r--r-- | fs/proc/internal.h | 1 |
3 files changed, 40 insertions, 11 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 8c68bbe2b61e..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 | ||
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index d8bb5c671f42..e11dc22c6511 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
| @@ -127,7 +127,7 @@ static void __pde_users_dec(struct proc_dir_entry *pde) | |||
| 127 | complete(pde->pde_unload_completion); | 127 | complete(pde->pde_unload_completion); |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | static void pde_users_dec(struct proc_dir_entry *pde) | 130 | void pde_users_dec(struct proc_dir_entry *pde) |
| 131 | { | 131 | { |
| 132 | spin_lock(&pde->pde_unload_lock); | 132 | spin_lock(&pde->pde_unload_lock); |
| 133 | __pde_users_dec(pde); | 133 | __pde_users_dec(pde); |
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index cd53ff838498..f6db9618a888 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
| @@ -91,3 +91,4 @@ struct pde_opener { | |||
| 91 | int (*release)(struct inode *, struct file *); | 91 | int (*release)(struct inode *, struct file *); |
| 92 | struct list_head lh; | 92 | struct list_head lh; |
| 93 | }; | 93 | }; |
| 94 | void pde_users_dec(struct proc_dir_entry *pde); | ||
