diff options
-rw-r--r-- | fs/proc/base.c | 36 | ||||
-rw-r--r-- | fs/proc/internal.h | 2 |
2 files changed, 23 insertions, 15 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index baf852b648ad..4c542b907754 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -632,29 +632,35 @@ static const struct file_operations proc_single_file_operations = { | |||
632 | .release = single_release, | 632 | .release = single_release, |
633 | }; | 633 | }; |
634 | 634 | ||
635 | static int __mem_open(struct inode *inode, struct file *file, unsigned int mode) | 635 | |
636 | struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode) | ||
636 | { | 637 | { |
637 | struct task_struct *task = get_proc_task(file_inode(file)); | 638 | struct task_struct *task = get_proc_task(inode); |
638 | struct mm_struct *mm; | 639 | struct mm_struct *mm = ERR_PTR(-ESRCH); |
639 | 640 | ||
640 | if (!task) | 641 | if (task) { |
641 | return -ESRCH; | 642 | mm = mm_access(task, mode); |
643 | put_task_struct(task); | ||
642 | 644 | ||
643 | mm = mm_access(task, mode); | 645 | if (!IS_ERR_OR_NULL(mm)) { |
644 | put_task_struct(task); | 646 | /* ensure this mm_struct can't be freed */ |
647 | atomic_inc(&mm->mm_count); | ||
648 | /* but do not pin its memory */ | ||
649 | mmput(mm); | ||
650 | } | ||
651 | } | ||
652 | |||
653 | return mm; | ||
654 | } | ||
655 | |||
656 | static int __mem_open(struct inode *inode, struct file *file, unsigned int mode) | ||
657 | { | ||
658 | struct mm_struct *mm = proc_mem_open(inode, mode); | ||
645 | 659 | ||
646 | if (IS_ERR(mm)) | 660 | if (IS_ERR(mm)) |
647 | return PTR_ERR(mm); | 661 | return PTR_ERR(mm); |
648 | 662 | ||
649 | if (mm) { | ||
650 | /* ensure this mm_struct can't be freed */ | ||
651 | atomic_inc(&mm->mm_count); | ||
652 | /* but do not pin its memory */ | ||
653 | mmput(mm); | ||
654 | } | ||
655 | |||
656 | file->private_data = mm; | 663 | file->private_data = mm; |
657 | |||
658 | return 0; | 664 | return 0; |
659 | } | 665 | } |
660 | 666 | ||
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 7da13e49128a..3c685563406f 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -278,6 +278,8 @@ struct proc_maps_private { | |||
278 | #endif | 278 | #endif |
279 | }; | 279 | }; |
280 | 280 | ||
281 | struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode); | ||
282 | |||
281 | extern const struct file_operations proc_pid_maps_operations; | 283 | extern const struct file_operations proc_pid_maps_operations; |
282 | extern const struct file_operations proc_tid_maps_operations; | 284 | extern const struct file_operations proc_tid_maps_operations; |
283 | extern const struct file_operations proc_pid_numa_maps_operations; | 285 | extern const struct file_operations proc_pid_numa_maps_operations; |