diff options
Diffstat (limited to 'fs/proc/generic.c')
-rw-r--r-- | fs/proc/generic.c | 100 |
1 files changed, 38 insertions, 62 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index a2596afffae6..94441a407337 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -233,76 +233,52 @@ struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry, | |||
233 | * value of the readdir() call, as long as it's non-negative | 233 | * value of the readdir() call, as long as it's non-negative |
234 | * for success.. | 234 | * for success.. |
235 | */ | 235 | */ |
236 | int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent, | 236 | int proc_readdir_de(struct proc_dir_entry *de, struct file *file, |
237 | filldir_t filldir) | 237 | struct dir_context *ctx) |
238 | { | 238 | { |
239 | unsigned int ino; | ||
240 | int i; | 239 | int i; |
241 | struct inode *inode = file_inode(filp); | ||
242 | int ret = 0; | ||
243 | |||
244 | ino = inode->i_ino; | ||
245 | i = filp->f_pos; | ||
246 | switch (i) { | ||
247 | case 0: | ||
248 | if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0) | ||
249 | goto out; | ||
250 | i++; | ||
251 | filp->f_pos++; | ||
252 | /* fall through */ | ||
253 | case 1: | ||
254 | if (filldir(dirent, "..", 2, i, | ||
255 | parent_ino(filp->f_path.dentry), | ||
256 | DT_DIR) < 0) | ||
257 | goto out; | ||
258 | i++; | ||
259 | filp->f_pos++; | ||
260 | /* fall through */ | ||
261 | default: | ||
262 | spin_lock(&proc_subdir_lock); | ||
263 | de = de->subdir; | ||
264 | i -= 2; | ||
265 | for (;;) { | ||
266 | if (!de) { | ||
267 | ret = 1; | ||
268 | spin_unlock(&proc_subdir_lock); | ||
269 | goto out; | ||
270 | } | ||
271 | if (!i) | ||
272 | break; | ||
273 | de = de->next; | ||
274 | i--; | ||
275 | } | ||
276 | 240 | ||
277 | do { | 241 | if (!dir_emit_dots(file, ctx)) |
278 | struct proc_dir_entry *next; | 242 | return 0; |
279 | 243 | ||
280 | /* filldir passes info to user space */ | 244 | spin_lock(&proc_subdir_lock); |
281 | pde_get(de); | 245 | de = de->subdir; |
282 | spin_unlock(&proc_subdir_lock); | 246 | i = ctx->pos - 2; |
283 | if (filldir(dirent, de->name, de->namelen, filp->f_pos, | 247 | for (;;) { |
284 | de->low_ino, de->mode >> 12) < 0) { | 248 | if (!de) { |
285 | pde_put(de); | ||
286 | goto out; | ||
287 | } | ||
288 | spin_lock(&proc_subdir_lock); | ||
289 | filp->f_pos++; | ||
290 | next = de->next; | ||
291 | pde_put(de); | ||
292 | de = next; | ||
293 | } while (de); | ||
294 | spin_unlock(&proc_subdir_lock); | 249 | spin_unlock(&proc_subdir_lock); |
250 | return 0; | ||
251 | } | ||
252 | if (!i) | ||
253 | break; | ||
254 | de = de->next; | ||
255 | i--; | ||
295 | } | 256 | } |
296 | ret = 1; | 257 | |
297 | out: | 258 | do { |
298 | return ret; | 259 | struct proc_dir_entry *next; |
260 | pde_get(de); | ||
261 | spin_unlock(&proc_subdir_lock); | ||
262 | if (!dir_emit(ctx, de->name, de->namelen, | ||
263 | de->low_ino, de->mode >> 12)) { | ||
264 | pde_put(de); | ||
265 | return 0; | ||
266 | } | ||
267 | spin_lock(&proc_subdir_lock); | ||
268 | ctx->pos++; | ||
269 | next = de->next; | ||
270 | pde_put(de); | ||
271 | de = next; | ||
272 | } while (de); | ||
273 | spin_unlock(&proc_subdir_lock); | ||
274 | return 0; | ||
299 | } | 275 | } |
300 | 276 | ||
301 | int proc_readdir(struct file *filp, void *dirent, filldir_t filldir) | 277 | int proc_readdir(struct file *file, struct dir_context *ctx) |
302 | { | 278 | { |
303 | struct inode *inode = file_inode(filp); | 279 | struct inode *inode = file_inode(file); |
304 | 280 | ||
305 | return proc_readdir_de(PDE(inode), filp, dirent, filldir); | 281 | return proc_readdir_de(PDE(inode), file, ctx); |
306 | } | 282 | } |
307 | 283 | ||
308 | /* | 284 | /* |
@@ -313,7 +289,7 @@ int proc_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
313 | static const struct file_operations proc_dir_operations = { | 289 | static const struct file_operations proc_dir_operations = { |
314 | .llseek = generic_file_llseek, | 290 | .llseek = generic_file_llseek, |
315 | .read = generic_read_dir, | 291 | .read = generic_read_dir, |
316 | .readdir = proc_readdir, | 292 | .iterate = proc_readdir, |
317 | }; | 293 | }; |
318 | 294 | ||
319 | /* | 295 | /* |