diff options
author | Matt Helsley <matthltc@us.ibm.com> | 2008-04-29 04:01:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-29 11:06:17 -0400 |
commit | 925d1c401fa6cfd0df5d2e37da8981494ccdec07 (patch) | |
tree | 4f3b7a09311cd99783b822350628125e44f9902d /kernel/fork.c | |
parent | e93b4ea20adb20f1f1f07f10ba5d7dd739d2843e (diff) |
procfs task exe symlink
The kernel implements readlink of /proc/pid/exe by getting the file from
the first executable VMA. Then the path to the file is reconstructed and
reported as the result.
Because of the VMA walk the code is slightly different on nommu systems.
This patch avoids separate /proc/pid/exe code on nommu systems. Instead of
walking the VMAs to find the first executable file-backed VMA we store a
reference to the exec'd file in the mm_struct.
That reference would prevent the filesystem holding the executable file
from being unmounted even after unmapping the VMAs. So we track the number
of VM_EXECUTABLE VMAs and drop the new reference when the last one is
unmapped. This avoids pinning the mounted filesystem.
[akpm@linux-foundation.org: improve comments]
[yamamoto@valinux.co.jp: fix dup_mmap]
Signed-off-by: Matt Helsley <matthltc@us.ibm.com>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Cc: David Howells <dhowells@redhat.com>
Cc:"Eric W. Biederman" <ebiederm@xmission.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Hugh Dickins <hugh@veritas.com>
Signed-off-by: YAMAMOTO Takashi <yamamoto@valinux.co.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index de5c16c6b6ec..068ffe007529 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -431,6 +431,7 @@ void mmput(struct mm_struct *mm) | |||
431 | if (atomic_dec_and_test(&mm->mm_users)) { | 431 | if (atomic_dec_and_test(&mm->mm_users)) { |
432 | exit_aio(mm); | 432 | exit_aio(mm); |
433 | exit_mmap(mm); | 433 | exit_mmap(mm); |
434 | set_mm_exe_file(mm, NULL); | ||
434 | if (!list_empty(&mm->mmlist)) { | 435 | if (!list_empty(&mm->mmlist)) { |
435 | spin_lock(&mmlist_lock); | 436 | spin_lock(&mmlist_lock); |
436 | list_del(&mm->mmlist); | 437 | list_del(&mm->mmlist); |
@@ -543,6 +544,8 @@ struct mm_struct *dup_mm(struct task_struct *tsk) | |||
543 | if (init_new_context(tsk, mm)) | 544 | if (init_new_context(tsk, mm)) |
544 | goto fail_nocontext; | 545 | goto fail_nocontext; |
545 | 546 | ||
547 | dup_mm_exe_file(oldmm, mm); | ||
548 | |||
546 | err = dup_mmap(mm, oldmm); | 549 | err = dup_mmap(mm, oldmm); |
547 | if (err) | 550 | if (err) |
548 | goto free_pt; | 551 | goto free_pt; |