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.c100
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 */
236int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent, 236int 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
297out: 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
301int proc_readdir(struct file *filp, void *dirent, filldir_t filldir) 277int 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)
313static const struct file_operations proc_dir_operations = { 289static 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/*