aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
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 /include/linux
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 'include/linux')
-rw-r--r--include/linux/mm.h13
-rw-r--r--include/linux/mm_types.h6
-rw-r--r--include/linux/proc_fs.h20
3 files changed, 38 insertions, 1 deletions
diff --git a/include/linux/mm.h b/include/linux/mm.h
index fef602d82722..c31a9cd2a30e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1066,6 +1066,19 @@ extern void unlink_file_vma(struct vm_area_struct *);
1066extern struct vm_area_struct *copy_vma(struct vm_area_struct **, 1066extern struct vm_area_struct *copy_vma(struct vm_area_struct **,
1067 unsigned long addr, unsigned long len, pgoff_t pgoff); 1067 unsigned long addr, unsigned long len, pgoff_t pgoff);
1068extern void exit_mmap(struct mm_struct *); 1068extern void exit_mmap(struct mm_struct *);
1069
1070#ifdef CONFIG_PROC_FS
1071/* From fs/proc/base.c. callers must _not_ hold the mm's exe_file_lock */
1072extern void added_exe_file_vma(struct mm_struct *mm);
1073extern void removed_exe_file_vma(struct mm_struct *mm);
1074#else
1075static inline void added_exe_file_vma(struct mm_struct *mm)
1076{}
1077
1078static inline void removed_exe_file_vma(struct mm_struct *mm)
1079{}
1080#endif /* CONFIG_PROC_FS */
1081
1069extern int may_expand_vm(struct mm_struct *mm, unsigned long npages); 1082extern int may_expand_vm(struct mm_struct *mm, unsigned long npages);
1070extern int install_special_mapping(struct mm_struct *mm, 1083extern int install_special_mapping(struct mm_struct *mm,
1071 unsigned long addr, unsigned long len, 1084 unsigned long addr, unsigned long len,
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index bc97bd54f606..eb7c16cc9559 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -229,6 +229,12 @@ struct mm_struct {
229 struct task_struct *owner; /* The thread group leader that */ 229 struct task_struct *owner; /* The thread group leader that */
230 /* owns the mm_struct. */ 230 /* owns the mm_struct. */
231#endif 231#endif
232
233#ifdef CONFIG_PROC_FS
234 /* store ref to file /proc/<pid>/exe symlink points to */
235 struct file *exe_file;
236 unsigned long num_exe_file_vmas;
237#endif
232}; 238};
233 239
234#endif /* _LINUX_MM_TYPES_H */ 240#endif /* _LINUX_MM_TYPES_H */
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 9b6c935f69cf..65f2299b772b 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -9,7 +9,6 @@
9 9
10struct net; 10struct net;
11struct completion; 11struct completion;
12
13/* 12/*
14 * The proc filesystem constants/structures 13 * The proc filesystem constants/structures
15 */ 14 */
@@ -206,6 +205,12 @@ extern void proc_net_remove(struct net *net, const char *name);
206extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, 205extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
207 struct proc_dir_entry *parent); 206 struct proc_dir_entry *parent);
208 207
208/* While the {get|set|dup}_mm_exe_file functions are for mm_structs, they are
209 * only needed to implement /proc/<pid>|self/exe so we define them here. */
210extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file);
211extern struct file *get_mm_exe_file(struct mm_struct *mm);
212extern void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm);
213
209#else 214#else
210 215
211#define proc_root_driver NULL 216#define proc_root_driver NULL
@@ -255,6 +260,19 @@ static inline void pid_ns_release_proc(struct pid_namespace *ns)
255{ 260{
256} 261}
257 262
263static inline void set_mm_exe_file(struct mm_struct *mm,
264 struct file *new_exe_file)
265{}
266
267static inline struct file *get_mm_exe_file(struct mm_struct *mm)
268{
269 return NULL;
270}
271
272static inline void dup_mm_exe_file(struct mm_struct *oldmm,
273 struct mm_struct *newmm)
274{}
275
258#endif /* CONFIG_PROC_FS */ 276#endif /* CONFIG_PROC_FS */
259 277
260#if !defined(CONFIG_PROC_KCORE) 278#if !defined(CONFIG_PROC_KCORE)