aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2010-08-10 05:41:36 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2010-08-11 00:28:20 -0400
commitf7ad3c6be90809b53b7f0ae9d4eaa45ce2564a79 (patch)
treedc9b09188bab35320200f318b5e7b52f24dc43ad
parent542ce7a9bc6b3838832ae0f4f8de30c667af8ff3 (diff)
vfs: add helpers to get root and pwd
Add three helpers that retrieve a refcounted copy of the root and cwd from the supplied fs_struct. get_fs_root() get_fs_pwd() get_fs_root_and_pwd() Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/cachefiles/daemon.c14
-rw-r--r--fs/dcache.c12
-rw-r--r--fs/fs_struct.c7
-rw-r--r--fs/namei.c15
-rw-r--r--fs/namespace.c5
-rw-r--r--fs/proc/base.c22
-rw-r--r--include/linux/fs_struct.h27
-rw-r--r--kernel/auditsc.c9
8 files changed, 49 insertions, 62 deletions
diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c
index 72d4d0042826..727caedcdd92 100644
--- a/fs/cachefiles/daemon.c
+++ b/fs/cachefiles/daemon.c
@@ -552,7 +552,6 @@ static int cachefiles_daemon_tag(struct cachefiles_cache *cache, char *args)
552 */ 552 */
553static int cachefiles_daemon_cull(struct cachefiles_cache *cache, char *args) 553static int cachefiles_daemon_cull(struct cachefiles_cache *cache, char *args)
554{ 554{
555 struct fs_struct *fs;
556 struct path path; 555 struct path path;
557 const struct cred *saved_cred; 556 const struct cred *saved_cred;
558 int ret; 557 int ret;
@@ -573,11 +572,7 @@ static int cachefiles_daemon_cull(struct cachefiles_cache *cache, char *args)
573 } 572 }
574 573
575 /* extract the directory dentry from the cwd */ 574 /* extract the directory dentry from the cwd */
576 fs = current->fs; 575 get_fs_pwd(current->fs, &path);
577 read_lock(&fs->lock);
578 path = fs->pwd;
579 path_get(&path);
580 read_unlock(&fs->lock);
581 576
582 if (!S_ISDIR(path.dentry->d_inode->i_mode)) 577 if (!S_ISDIR(path.dentry->d_inode->i_mode))
583 goto notdir; 578 goto notdir;
@@ -629,7 +624,6 @@ inval:
629 */ 624 */
630static int cachefiles_daemon_inuse(struct cachefiles_cache *cache, char *args) 625static int cachefiles_daemon_inuse(struct cachefiles_cache *cache, char *args)
631{ 626{
632 struct fs_struct *fs;
633 struct path path; 627 struct path path;
634 const struct cred *saved_cred; 628 const struct cred *saved_cred;
635 int ret; 629 int ret;
@@ -650,11 +644,7 @@ static int cachefiles_daemon_inuse(struct cachefiles_cache *cache, char *args)
650 } 644 }
651 645
652 /* extract the directory dentry from the cwd */ 646 /* extract the directory dentry from the cwd */
653 fs = current->fs; 647 get_fs_pwd(current->fs, &path);
654 read_lock(&fs->lock);
655 path = fs->pwd;
656 path_get(&path);
657 read_unlock(&fs->lock);
658 648
659 if (!S_ISDIR(path.dentry->d_inode->i_mode)) 649 if (!S_ISDIR(path.dentry->d_inode->i_mode))
660 goto notdir; 650 goto notdir;
diff --git a/fs/dcache.c b/fs/dcache.c
index 9f2c13417969..995d08069d26 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2014,10 +2014,7 @@ char *d_path(const struct path *path, char *buf, int buflen)
2014 if (path->dentry->d_op && path->dentry->d_op->d_dname) 2014 if (path->dentry->d_op && path->dentry->d_op->d_dname)
2015 return path->dentry->d_op->d_dname(path->dentry, buf, buflen); 2015 return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
2016 2016
2017 read_lock(&current->fs->lock); 2017 get_fs_root(current->fs, &root);
2018 root = current->fs->root;
2019 path_get(&root);
2020 read_unlock(&current->fs->lock);
2021 spin_lock(&dcache_lock); 2018 spin_lock(&dcache_lock);
2022 tmp = root; 2019 tmp = root;
2023 res = __d_path(path, &tmp, buf, buflen); 2020 res = __d_path(path, &tmp, buf, buflen);
@@ -2129,12 +2126,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
2129 if (!page) 2126 if (!page)
2130 return -ENOMEM; 2127 return -ENOMEM;
2131 2128
2132 read_lock(&current->fs->lock); 2129 get_fs_root_and_pwd(current->fs, &root, &pwd);
2133 pwd = current->fs->pwd;
2134 path_get(&pwd);
2135 root = current->fs->root;
2136 path_get(&root);
2137 read_unlock(&current->fs->lock);
2138 2130
2139 error = -ENOENT; 2131 error = -ENOENT;
2140 spin_lock(&dcache_lock); 2132 spin_lock(&dcache_lock);
diff --git a/fs/fs_struct.c b/fs/fs_struct.c
index eee059052db5..1ee40eb9a2c0 100644
--- a/fs/fs_struct.c
+++ b/fs/fs_struct.c
@@ -106,12 +106,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
106 fs->in_exec = 0; 106 fs->in_exec = 0;
107 rwlock_init(&fs->lock); 107 rwlock_init(&fs->lock);
108 fs->umask = old->umask; 108 fs->umask = old->umask;
109 read_lock(&old->lock); 109 get_fs_root_and_pwd(old, &fs->root, &fs->pwd);
110 fs->root = old->root;
111 path_get(&old->root);
112 fs->pwd = old->pwd;
113 path_get(&old->pwd);
114 read_unlock(&old->lock);
115 } 110 }
116 return fs; 111 return fs;
117} 112}
diff --git a/fs/namei.c b/fs/namei.c
index 13ff4abdbdca..17ea76bf2fbe 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -483,13 +483,8 @@ ok:
483 483
484static __always_inline void set_root(struct nameidata *nd) 484static __always_inline void set_root(struct nameidata *nd)
485{ 485{
486 if (!nd->root.mnt) { 486 if (!nd->root.mnt)
487 struct fs_struct *fs = current->fs; 487 get_fs_root(current->fs, &nd->root);
488 read_lock(&fs->lock);
489 nd->root = fs->root;
490 path_get(&nd->root);
491 read_unlock(&fs->lock);
492 }
493} 488}
494 489
495static int link_path_walk(const char *, struct nameidata *); 490static int link_path_walk(const char *, struct nameidata *);
@@ -1015,11 +1010,7 @@ static int path_init(int dfd, const char *name, unsigned int flags, struct namei
1015 nd->path = nd->root; 1010 nd->path = nd->root;
1016 path_get(&nd->root); 1011 path_get(&nd->root);
1017 } else if (dfd == AT_FDCWD) { 1012 } else if (dfd == AT_FDCWD) {
1018 struct fs_struct *fs = current->fs; 1013 get_fs_pwd(current->fs, &nd->path);
1019 read_lock(&fs->lock);
1020 nd->path = fs->pwd;
1021 path_get(&fs->pwd);
1022 read_unlock(&fs->lock);
1023 } else { 1014 } else {
1024 struct dentry *dentry; 1015 struct dentry *dentry;
1025 1016
diff --git a/fs/namespace.c b/fs/namespace.c
index 66c4f7e781cb..7972e51ccc06 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2213,10 +2213,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
2213 goto out1; 2213 goto out1;
2214 } 2214 }
2215 2215
2216 read_lock(&current->fs->lock); 2216 get_fs_root(current->fs, &root);
2217 root = current->fs->root;
2218 path_get(&current->fs->root);
2219 read_unlock(&current->fs->lock);
2220 down_write(&namespace_sem); 2217 down_write(&namespace_sem);
2221 mutex_lock(&old.dentry->d_inode->i_mutex); 2218 mutex_lock(&old.dentry->d_inode->i_mutex);
2222 error = -EINVAL; 2219 error = -EINVAL;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index c806dfb24e08..4cf5abf77ddf 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -149,18 +149,13 @@ static unsigned int pid_entry_count_dirs(const struct pid_entry *entries,
149 return count; 149 return count;
150} 150}
151 151
152static int get_fs_path(struct task_struct *task, struct path *path, bool root) 152static int get_task_root(struct task_struct *task, struct path *root)
153{ 153{
154 struct fs_struct *fs;
155 int result = -ENOENT; 154 int result = -ENOENT;
156 155
157 task_lock(task); 156 task_lock(task);
158 fs = task->fs; 157 if (task->fs) {
159 if (fs) { 158 get_fs_root(task->fs, root);
160 read_lock(&fs->lock);
161 *path = root ? fs->root : fs->pwd;
162 path_get(path);
163 read_unlock(&fs->lock);
164 result = 0; 159 result = 0;
165 } 160 }
166 task_unlock(task); 161 task_unlock(task);
@@ -173,7 +168,12 @@ static int proc_cwd_link(struct inode *inode, struct path *path)
173 int result = -ENOENT; 168 int result = -ENOENT;
174 169
175 if (task) { 170 if (task) {
176 result = get_fs_path(task, path, 0); 171 task_lock(task);
172 if (task->fs) {
173 get_fs_pwd(task->fs, path);
174 result = 0;
175 }
176 task_unlock(task);
177 put_task_struct(task); 177 put_task_struct(task);
178 } 178 }
179 return result; 179 return result;
@@ -185,7 +185,7 @@ static int proc_root_link(struct inode *inode, struct path *path)
185 int result = -ENOENT; 185 int result = -ENOENT;
186 186
187 if (task) { 187 if (task) {
188 result = get_fs_path(task, path, 1); 188 result = get_task_root(task, path);
189 put_task_struct(task); 189 put_task_struct(task);
190 } 190 }
191 return result; 191 return result;
@@ -597,7 +597,7 @@ static int mounts_open_common(struct inode *inode, struct file *file,
597 get_mnt_ns(ns); 597 get_mnt_ns(ns);
598 } 598 }
599 rcu_read_unlock(); 599 rcu_read_unlock();
600 if (ns && get_fs_path(task, &root, 1) == 0) 600 if (ns && get_task_root(task, &root) == 0)
601 ret = 0; 601 ret = 0;
602 put_task_struct(task); 602 put_task_struct(task);
603 } 603 }
diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h
index 78a05bfcd8eb..eca3d5202138 100644
--- a/include/linux/fs_struct.h
+++ b/include/linux/fs_struct.h
@@ -21,4 +21,31 @@ extern void free_fs_struct(struct fs_struct *);
21extern void daemonize_fs_struct(void); 21extern void daemonize_fs_struct(void);
22extern int unshare_fs_struct(void); 22extern int unshare_fs_struct(void);
23 23
24static inline void get_fs_root(struct fs_struct *fs, struct path *root)
25{
26 read_lock(&fs->lock);
27 *root = fs->root;
28 path_get(root);
29 read_unlock(&fs->lock);
30}
31
32static inline void get_fs_pwd(struct fs_struct *fs, struct path *pwd)
33{
34 read_lock(&fs->lock);
35 *pwd = fs->pwd;
36 path_get(pwd);
37 read_unlock(&fs->lock);
38}
39
40static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root,
41 struct path *pwd)
42{
43 read_lock(&fs->lock);
44 *root = fs->root;
45 path_get(root);
46 *pwd = fs->pwd;
47 path_get(pwd);
48 read_unlock(&fs->lock);
49}
50
24#endif /* _LINUX_FS_STRUCT_H */ 51#endif /* _LINUX_FS_STRUCT_H */
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index b87a63beb66c..1b31c130d034 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1835,13 +1835,8 @@ void __audit_getname(const char *name)
1835 context->names[context->name_count].ino = (unsigned long)-1; 1835 context->names[context->name_count].ino = (unsigned long)-1;
1836 context->names[context->name_count].osid = 0; 1836 context->names[context->name_count].osid = 0;
1837 ++context->name_count; 1837 ++context->name_count;
1838 if (!context->pwd.dentry) { 1838 if (!context->pwd.dentry)
1839 read_lock(&current->fs->lock); 1839 get_fs_pwd(current->fs, &context->pwd);
1840 context->pwd = current->fs->pwd;
1841 path_get(&current->fs->pwd);
1842 read_unlock(&current->fs->lock);
1843 }
1844
1845} 1840}
1846 1841
1847/* audit_putname - intercept a putname request 1842/* audit_putname - intercept a putname request