diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/proc/generic.c | 33 | ||||
-rw-r--r-- | fs/proc/inode.c | 69 |
2 files changed, 46 insertions, 56 deletions
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 3c6f5669523a..8b406e21a258 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -388,20 +388,18 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir, | |||
388 | 388 | ||
389 | lock_kernel(); | 389 | lock_kernel(); |
390 | spin_lock(&proc_subdir_lock); | 390 | spin_lock(&proc_subdir_lock); |
391 | if (de) { | 391 | for (de = de->subdir; de ; de = de->next) { |
392 | for (de = de->subdir; de ; de = de->next) { | 392 | if (de->namelen != dentry->d_name.len) |
393 | if (de->namelen != dentry->d_name.len) | 393 | continue; |
394 | continue; | 394 | if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { |
395 | if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { | 395 | unsigned int ino; |
396 | unsigned int ino; | 396 | |
397 | 397 | ino = de->low_ino; | |
398 | ino = de->low_ino; | 398 | de_get(de); |
399 | de_get(de); | 399 | spin_unlock(&proc_subdir_lock); |
400 | spin_unlock(&proc_subdir_lock); | 400 | error = -EINVAL; |
401 | error = -EINVAL; | 401 | inode = proc_get_inode(dir->i_sb, ino, de); |
402 | inode = proc_get_inode(dir->i_sb, ino, de); | 402 | goto out_unlock; |
403 | goto out_unlock; | ||
404 | } | ||
405 | } | 403 | } |
406 | } | 404 | } |
407 | spin_unlock(&proc_subdir_lock); | 405 | spin_unlock(&proc_subdir_lock); |
@@ -413,7 +411,8 @@ out_unlock: | |||
413 | d_add(dentry, inode); | 411 | d_add(dentry, inode); |
414 | return NULL; | 412 | return NULL; |
415 | } | 413 | } |
416 | de_put(de); | 414 | if (de) |
415 | de_put(de); | ||
417 | return ERR_PTR(error); | 416 | return ERR_PTR(error); |
418 | } | 417 | } |
419 | 418 | ||
@@ -443,10 +442,6 @@ int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent, | |||
443 | lock_kernel(); | 442 | lock_kernel(); |
444 | 443 | ||
445 | ino = inode->i_ino; | 444 | ino = inode->i_ino; |
446 | if (!de) { | ||
447 | ret = -EINVAL; | ||
448 | goto out; | ||
449 | } | ||
450 | i = filp->f_pos; | 445 | i = filp->f_pos; |
451 | switch (i) { | 446 | switch (i) { |
452 | case 0: | 447 | case 0: |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 82b3a1b5a70b..6f4e8dc97da1 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -25,8 +25,7 @@ | |||
25 | 25 | ||
26 | struct proc_dir_entry *de_get(struct proc_dir_entry *de) | 26 | struct proc_dir_entry *de_get(struct proc_dir_entry *de) |
27 | { | 27 | { |
28 | if (de) | 28 | atomic_inc(&de->count); |
29 | atomic_inc(&de->count); | ||
30 | return de; | 29 | return de; |
31 | } | 30 | } |
32 | 31 | ||
@@ -35,18 +34,16 @@ struct proc_dir_entry *de_get(struct proc_dir_entry *de) | |||
35 | */ | 34 | */ |
36 | void de_put(struct proc_dir_entry *de) | 35 | void de_put(struct proc_dir_entry *de) |
37 | { | 36 | { |
38 | if (de) { | 37 | lock_kernel(); |
39 | lock_kernel(); | 38 | if (!atomic_read(&de->count)) { |
40 | if (!atomic_read(&de->count)) { | 39 | printk("de_put: entry %s already free!\n", de->name); |
41 | printk("de_put: entry %s already free!\n", de->name); | ||
42 | unlock_kernel(); | ||
43 | return; | ||
44 | } | ||
45 | |||
46 | if (atomic_dec_and_test(&de->count)) | ||
47 | free_proc_entry(de); | ||
48 | unlock_kernel(); | 40 | unlock_kernel(); |
41 | return; | ||
49 | } | 42 | } |
43 | |||
44 | if (atomic_dec_and_test(&de->count)) | ||
45 | free_proc_entry(de); | ||
46 | unlock_kernel(); | ||
50 | } | 47 | } |
51 | 48 | ||
52 | /* | 49 | /* |
@@ -392,7 +389,7 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, | |||
392 | { | 389 | { |
393 | struct inode * inode; | 390 | struct inode * inode; |
394 | 391 | ||
395 | if (de != NULL && !try_module_get(de->owner)) | 392 | if (!try_module_get(de->owner)) |
396 | goto out_mod; | 393 | goto out_mod; |
397 | 394 | ||
398 | inode = iget_locked(sb, ino); | 395 | inode = iget_locked(sb, ino); |
@@ -402,30 +399,29 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, | |||
402 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 399 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
403 | PROC_I(inode)->fd = 0; | 400 | PROC_I(inode)->fd = 0; |
404 | PROC_I(inode)->pde = de; | 401 | PROC_I(inode)->pde = de; |
405 | if (de) { | 402 | |
406 | if (de->mode) { | 403 | if (de->mode) { |
407 | inode->i_mode = de->mode; | 404 | inode->i_mode = de->mode; |
408 | inode->i_uid = de->uid; | 405 | inode->i_uid = de->uid; |
409 | inode->i_gid = de->gid; | 406 | inode->i_gid = de->gid; |
410 | } | 407 | } |
411 | if (de->size) | 408 | if (de->size) |
412 | inode->i_size = de->size; | 409 | inode->i_size = de->size; |
413 | if (de->nlink) | 410 | if (de->nlink) |
414 | inode->i_nlink = de->nlink; | 411 | inode->i_nlink = de->nlink; |
415 | if (de->proc_iops) | 412 | if (de->proc_iops) |
416 | inode->i_op = de->proc_iops; | 413 | inode->i_op = de->proc_iops; |
417 | if (de->proc_fops) { | 414 | if (de->proc_fops) { |
418 | if (S_ISREG(inode->i_mode)) { | 415 | if (S_ISREG(inode->i_mode)) { |
419 | #ifdef CONFIG_COMPAT | 416 | #ifdef CONFIG_COMPAT |
420 | if (!de->proc_fops->compat_ioctl) | 417 | if (!de->proc_fops->compat_ioctl) |
421 | inode->i_fop = | 418 | inode->i_fop = |
422 | &proc_reg_file_ops_no_compat; | 419 | &proc_reg_file_ops_no_compat; |
423 | else | 420 | else |
424 | #endif | 421 | #endif |
425 | inode->i_fop = &proc_reg_file_ops; | 422 | inode->i_fop = &proc_reg_file_ops; |
426 | } else { | 423 | } else { |
427 | inode->i_fop = de->proc_fops; | 424 | inode->i_fop = de->proc_fops; |
428 | } | ||
429 | } | 425 | } |
430 | } | 426 | } |
431 | unlock_new_inode(inode); | 427 | unlock_new_inode(inode); |
@@ -433,8 +429,7 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, | |||
433 | return inode; | 429 | return inode; |
434 | 430 | ||
435 | out_ino: | 431 | out_ino: |
436 | if (de != NULL) | 432 | module_put(de->owner); |
437 | module_put(de->owner); | ||
438 | out_mod: | 433 | out_mod: |
439 | return NULL; | 434 | return NULL; |
440 | } | 435 | } |