aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mmap.c
diff options
context:
space:
mode:
authorMatt Helsley <matthltc@us.ibm.com>2008-04-29 04:01:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:06:17 -0400
commit925d1c401fa6cfd0df5d2e37da8981494ccdec07 (patch)
tree4f3b7a09311cd99783b822350628125e44f9902d /mm/mmap.c
parente93b4ea20adb20f1f1f07f10ba5d7dd739d2843e (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 'mm/mmap.c')
-rw-r--r--mm/mmap.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/mm/mmap.c b/mm/mmap.c
index 677d184b0d42..fac66337da2a 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -230,8 +230,11 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
230 might_sleep(); 230 might_sleep();
231 if (vma->vm_ops && vma->vm_ops->close) 231 if (vma->vm_ops && vma->vm_ops->close)
232 vma->vm_ops->close(vma); 232 vma->vm_ops->close(vma);
233 if (vma->vm_file) 233 if (vma->vm_file) {
234 fput(vma->vm_file); 234 fput(vma->vm_file);
235 if (vma->vm_flags & VM_EXECUTABLE)
236 removed_exe_file_vma(vma->vm_mm);
237 }
235 mpol_put(vma_policy(vma)); 238 mpol_put(vma_policy(vma));
236 kmem_cache_free(vm_area_cachep, vma); 239 kmem_cache_free(vm_area_cachep, vma);
237 return next; 240 return next;
@@ -623,8 +626,11 @@ again: remove_next = 1 + (end > next->vm_end);
623 spin_unlock(&mapping->i_mmap_lock); 626 spin_unlock(&mapping->i_mmap_lock);
624 627
625 if (remove_next) { 628 if (remove_next) {
626 if (file) 629 if (file) {
627 fput(file); 630 fput(file);
631 if (next->vm_flags & VM_EXECUTABLE)
632 removed_exe_file_vma(mm);
633 }
628 mm->map_count--; 634 mm->map_count--;
629 mpol_put(vma_policy(next)); 635 mpol_put(vma_policy(next));
630 kmem_cache_free(vm_area_cachep, next); 636 kmem_cache_free(vm_area_cachep, next);
@@ -1154,6 +1160,8 @@ munmap_back:
1154 error = file->f_op->mmap(file, vma); 1160 error = file->f_op->mmap(file, vma);
1155 if (error) 1161 if (error)
1156 goto unmap_and_free_vma; 1162 goto unmap_and_free_vma;
1163 if (vm_flags & VM_EXECUTABLE)
1164 added_exe_file_vma(mm);
1157 } else if (vm_flags & VM_SHARED) { 1165 } else if (vm_flags & VM_SHARED) {
1158 error = shmem_zero_setup(vma); 1166 error = shmem_zero_setup(vma);
1159 if (error) 1167 if (error)
@@ -1185,6 +1193,8 @@ munmap_back:
1185 mpol_put(vma_policy(vma)); 1193 mpol_put(vma_policy(vma));
1186 kmem_cache_free(vm_area_cachep, vma); 1194 kmem_cache_free(vm_area_cachep, vma);
1187 fput(file); 1195 fput(file);
1196 if (vm_flags & VM_EXECUTABLE)
1197 removed_exe_file_vma(mm);
1188 } else { 1198 } else {
1189 vma_link(mm, vma, prev, rb_link, rb_parent); 1199 vma_link(mm, vma, prev, rb_link, rb_parent);
1190 file = vma->vm_file; 1200 file = vma->vm_file;
@@ -1817,8 +1827,11 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
1817 } 1827 }
1818 vma_set_policy(new, pol); 1828 vma_set_policy(new, pol);
1819 1829
1820 if (new->vm_file) 1830 if (new->vm_file) {
1821 get_file(new->vm_file); 1831 get_file(new->vm_file);
1832 if (vma->vm_flags & VM_EXECUTABLE)
1833 added_exe_file_vma(mm);
1834 }
1822 1835
1823 if (new->vm_ops && new->vm_ops->open) 1836 if (new->vm_ops && new->vm_ops->open)
1824 new->vm_ops->open(new); 1837 new->vm_ops->open(new);
@@ -2135,8 +2148,11 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
2135 new_vma->vm_start = addr; 2148 new_vma->vm_start = addr;
2136 new_vma->vm_end = addr + len; 2149 new_vma->vm_end = addr + len;
2137 new_vma->vm_pgoff = pgoff; 2150 new_vma->vm_pgoff = pgoff;
2138 if (new_vma->vm_file) 2151 if (new_vma->vm_file) {
2139 get_file(new_vma->vm_file); 2152 get_file(new_vma->vm_file);
2153 if (vma->vm_flags & VM_EXECUTABLE)
2154 added_exe_file_vma(mm);
2155 }
2140 if (new_vma->vm_ops && new_vma->vm_ops->open) 2156 if (new_vma->vm_ops && new_vma->vm_ops->open)
2141 new_vma->vm_ops->open(new_vma); 2157 new_vma->vm_ops->open(new_vma);
2142 vma_link(mm, new_vma, prev, rb_link, rb_parent); 2158 vma_link(mm, new_vma, prev, rb_link, rb_parent);