aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2011-05-26 19:25:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-26 20:12:36 -0400
commit3864601387cf4196371e3c1897fdffa5228296f9 (patch)
tree1c517a970194f9e49ef98ef434c650771ffa31e1
parent63ab25ebbc50f74550bd8d164a34724b498f6fb9 (diff)
mm: extract exe_file handling from procfs
Setup and cleanup of mm_struct->exe_file is currently done in fs/proc/. This was because exe_file was needed only for /proc/<pid>/exe. Since we will need the exe_file functionality also for core dumps (so core name can contain full binary path), built this functionality always into the kernel. To achieve that move that out of proc FS to the kernel/ where in fact it should belong. By doing that we can make dup_mm_exe_file static. Also we can drop linux/proc_fs.h inclusion in fs/exec.c and kernel/fork.c. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/exec.c1
-rw-r--r--fs/proc/base.c51
-rw-r--r--include/linux/mm.h10
-rw-r--r--include/linux/mm_types.h2
-rw-r--r--include/linux/proc_fs.h19
-rw-r--r--kernel/fork.c52
6 files changed, 53 insertions, 82 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 936f5776655..88a16c57228 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -42,7 +42,6 @@
42#include <linux/pid_namespace.h> 42#include <linux/pid_namespace.h>
43#include <linux/module.h> 43#include <linux/module.h>
44#include <linux/namei.h> 44#include <linux/namei.h>
45#include <linux/proc_fs.h>
46#include <linux/mount.h> 45#include <linux/mount.h>
47#include <linux/security.h> 46#include <linux/security.h>
48#include <linux/syscalls.h> 47#include <linux/syscalls.h>
diff --git a/fs/proc/base.c b/fs/proc/base.c
index dc8bca72b00..c2ac2fb123c 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1576,57 +1576,6 @@ static const struct file_operations proc_pid_set_comm_operations = {
1576 .release = single_release, 1576 .release = single_release,
1577}; 1577};
1578 1578
1579/*
1580 * We added or removed a vma mapping the executable. The vmas are only mapped
1581 * during exec and are not mapped with the mmap system call.
1582 * Callers must hold down_write() on the mm's mmap_sem for these
1583 */
1584void added_exe_file_vma(struct mm_struct *mm)
1585{
1586 mm->num_exe_file_vmas++;
1587}
1588
1589void removed_exe_file_vma(struct mm_struct *mm)
1590{
1591 mm->num_exe_file_vmas--;
1592 if ((mm->num_exe_file_vmas == 0) && mm->exe_file){
1593 fput(mm->exe_file);
1594 mm->exe_file = NULL;
1595 }
1596
1597}
1598
1599void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
1600{
1601 if (new_exe_file)
1602 get_file(new_exe_file);
1603 if (mm->exe_file)
1604 fput(mm->exe_file);
1605 mm->exe_file = new_exe_file;
1606 mm->num_exe_file_vmas = 0;
1607}
1608
1609struct file *get_mm_exe_file(struct mm_struct *mm)
1610{
1611 struct file *exe_file;
1612
1613 /* We need mmap_sem to protect against races with removal of
1614 * VM_EXECUTABLE vmas */
1615 down_read(&mm->mmap_sem);
1616 exe_file = mm->exe_file;
1617 if (exe_file)
1618 get_file(exe_file);
1619 up_read(&mm->mmap_sem);
1620 return exe_file;
1621}
1622
1623void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm)
1624{
1625 /* It's safe to write the exe_file pointer without exe_file_lock because
1626 * this is called during fork when the task is not yet in /proc */
1627 newmm->exe_file = get_mm_exe_file(oldmm);
1628}
1629
1630static int proc_exe_link(struct inode *inode, struct path *exe_path) 1579static int proc_exe_link(struct inode *inode, struct path *exe_path)
1631{ 1580{
1632 struct task_struct *task; 1581 struct task_struct *task;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index fb8e814f78d..9670f71d7be 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1408,17 +1408,11 @@ extern void exit_mmap(struct mm_struct *);
1408extern int mm_take_all_locks(struct mm_struct *mm); 1408extern int mm_take_all_locks(struct mm_struct *mm);
1409extern void mm_drop_all_locks(struct mm_struct *mm); 1409extern void mm_drop_all_locks(struct mm_struct *mm);
1410 1410
1411#ifdef CONFIG_PROC_FS
1412/* From fs/proc/base.c. callers must _not_ hold the mm's exe_file_lock */ 1411/* From fs/proc/base.c. callers must _not_ hold the mm's exe_file_lock */
1413extern void added_exe_file_vma(struct mm_struct *mm); 1412extern void added_exe_file_vma(struct mm_struct *mm);
1414extern void removed_exe_file_vma(struct mm_struct *mm); 1413extern void removed_exe_file_vma(struct mm_struct *mm);
1415#else 1414extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file);
1416static inline void added_exe_file_vma(struct mm_struct *mm) 1415extern struct file *get_mm_exe_file(struct mm_struct *mm);
1417{}
1418
1419static inline void removed_exe_file_vma(struct mm_struct *mm)
1420{}
1421#endif /* CONFIG_PROC_FS */
1422 1416
1423extern int may_expand_vm(struct mm_struct *mm, unsigned long npages); 1417extern int may_expand_vm(struct mm_struct *mm, unsigned long npages);
1424extern int install_special_mapping(struct mm_struct *mm, 1418extern int install_special_mapping(struct mm_struct *mm,
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 6fe96c19f85..2a78aae78c6 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -302,11 +302,9 @@ struct mm_struct {
302 struct task_struct __rcu *owner; 302 struct task_struct __rcu *owner;
303#endif 303#endif
304 304
305#ifdef CONFIG_PROC_FS
306 /* store ref to file /proc/<pid>/exe symlink points to */ 305 /* store ref to file /proc/<pid>/exe symlink points to */
307 struct file *exe_file; 306 struct file *exe_file;
308 unsigned long num_exe_file_vmas; 307 unsigned long num_exe_file_vmas;
309#endif
310#ifdef CONFIG_MMU_NOTIFIER 308#ifdef CONFIG_MMU_NOTIFIER
311 struct mmu_notifier_mm *mmu_notifier_mm; 309 struct mmu_notifier_mm *mmu_notifier_mm;
312#endif 310#endif
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 648c9c58add..e7576cf9e32 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -173,12 +173,6 @@ extern void proc_net_remove(struct net *net, const char *name);
173extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, 173extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
174 struct proc_dir_entry *parent); 174 struct proc_dir_entry *parent);
175 175
176/* While the {get|set|dup}_mm_exe_file functions are for mm_structs, they are
177 * only needed to implement /proc/<pid>|self/exe so we define them here. */
178extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file);
179extern struct file *get_mm_exe_file(struct mm_struct *mm);
180extern void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm);
181
182extern struct file *proc_ns_fget(int fd); 176extern struct file *proc_ns_fget(int fd);
183 177
184#else 178#else
@@ -230,19 +224,6 @@ static inline void pid_ns_release_proc(struct pid_namespace *ns)
230{ 224{
231} 225}
232 226
233static inline void set_mm_exe_file(struct mm_struct *mm,
234 struct file *new_exe_file)
235{}
236
237static inline struct file *get_mm_exe_file(struct mm_struct *mm)
238{
239 return NULL;
240}
241
242static inline void dup_mm_exe_file(struct mm_struct *oldmm,
243 struct mm_struct *newmm)
244{}
245
246static inline struct file *proc_ns_fget(int fd) 227static inline struct file *proc_ns_fget(int fd)
247{ 228{
248 return ERR_PTR(-EINVAL); 229 return ERR_PTR(-EINVAL);
diff --git a/kernel/fork.c b/kernel/fork.c
index 1f84099ecce..ca406d91671 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -59,7 +59,6 @@
59#include <linux/taskstats_kern.h> 59#include <linux/taskstats_kern.h>
60#include <linux/random.h> 60#include <linux/random.h>
61#include <linux/tty.h> 61#include <linux/tty.h>
62#include <linux/proc_fs.h>
63#include <linux/blkdev.h> 62#include <linux/blkdev.h>
64#include <linux/fs_struct.h> 63#include <linux/fs_struct.h>
65#include <linux/magic.h> 64#include <linux/magic.h>
@@ -597,6 +596,57 @@ void mmput(struct mm_struct *mm)
597} 596}
598EXPORT_SYMBOL_GPL(mmput); 597EXPORT_SYMBOL_GPL(mmput);
599 598
599/*
600 * We added or removed a vma mapping the executable. The vmas are only mapped
601 * during exec and are not mapped with the mmap system call.
602 * Callers must hold down_write() on the mm's mmap_sem for these
603 */
604void added_exe_file_vma(struct mm_struct *mm)
605{
606 mm->num_exe_file_vmas++;
607}
608
609void removed_exe_file_vma(struct mm_struct *mm)
610{
611 mm->num_exe_file_vmas--;
612 if ((mm->num_exe_file_vmas == 0) && mm->exe_file){
613 fput(mm->exe_file);
614 mm->exe_file = NULL;
615 }
616
617}
618
619void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
620{
621 if (new_exe_file)
622 get_file(new_exe_file);
623 if (mm->exe_file)
624 fput(mm->exe_file);
625 mm->exe_file = new_exe_file;
626 mm->num_exe_file_vmas = 0;
627}
628
629struct file *get_mm_exe_file(struct mm_struct *mm)
630{
631 struct file *exe_file;
632
633 /* We need mmap_sem to protect against races with removal of
634 * VM_EXECUTABLE vmas */
635 down_read(&mm->mmap_sem);
636 exe_file = mm->exe_file;
637 if (exe_file)
638 get_file(exe_file);
639 up_read(&mm->mmap_sem);
640 return exe_file;
641}
642
643static void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm)
644{
645 /* It's safe to write the exe_file pointer without exe_file_lock because
646 * this is called during fork when the task is not yet in /proc */
647 newmm->exe_file = get_mm_exe_file(oldmm);
648}
649
600/** 650/**
601 * get_task_mm - acquire a reference to the task's mm 651 * get_task_mm - acquire a reference to the task's mm
602 * 652 *