Commit f7ad3c6be90809b53b7f0ae9d4eaa45ce2564a79
Committed by
Al Viro
1 parent
542ce7a9bc
Exists in
master
and in
4 other branches
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>
Showing 8 changed files with 49 additions and 62 deletions Side-by-side Diff
fs/cachefiles/daemon.c
... | ... | @@ -552,7 +552,6 @@ |
552 | 552 | */ |
553 | 553 | static int cachefiles_daemon_cull(struct cachefiles_cache *cache, char *args) |
554 | 554 | { |
555 | - struct fs_struct *fs; | |
556 | 555 | struct path path; |
557 | 556 | const struct cred *saved_cred; |
558 | 557 | int ret; |
... | ... | @@ -573,11 +572,7 @@ |
573 | 572 | } |
574 | 573 | |
575 | 574 | /* extract the directory dentry from the cwd */ |
576 | - fs = current->fs; | |
577 | - read_lock(&fs->lock); | |
578 | - path = fs->pwd; | |
579 | - path_get(&path); | |
580 | - read_unlock(&fs->lock); | |
575 | + get_fs_pwd(current->fs, &path); | |
581 | 576 | |
582 | 577 | if (!S_ISDIR(path.dentry->d_inode->i_mode)) |
583 | 578 | goto notdir; |
... | ... | @@ -629,7 +624,6 @@ |
629 | 624 | */ |
630 | 625 | static int cachefiles_daemon_inuse(struct cachefiles_cache *cache, char *args) |
631 | 626 | { |
632 | - struct fs_struct *fs; | |
633 | 627 | struct path path; |
634 | 628 | const struct cred *saved_cred; |
635 | 629 | int ret; |
... | ... | @@ -650,11 +644,7 @@ |
650 | 644 | } |
651 | 645 | |
652 | 646 | /* extract the directory dentry from the cwd */ |
653 | - fs = current->fs; | |
654 | - read_lock(&fs->lock); | |
655 | - path = fs->pwd; | |
656 | - path_get(&path); | |
657 | - read_unlock(&fs->lock); | |
647 | + get_fs_pwd(current->fs, &path); | |
658 | 648 | |
659 | 649 | if (!S_ISDIR(path.dentry->d_inode->i_mode)) |
660 | 650 | goto notdir; |
fs/dcache.c
... | ... | @@ -2014,10 +2014,7 @@ |
2014 | 2014 | if (path->dentry->d_op && path->dentry->d_op->d_dname) |
2015 | 2015 | return path->dentry->d_op->d_dname(path->dentry, buf, buflen); |
2016 | 2016 | |
2017 | - read_lock(¤t->fs->lock); | |
2018 | - root = current->fs->root; | |
2019 | - path_get(&root); | |
2020 | - read_unlock(¤t->fs->lock); | |
2017 | + get_fs_root(current->fs, &root); | |
2021 | 2018 | spin_lock(&dcache_lock); |
2022 | 2019 | tmp = root; |
2023 | 2020 | res = __d_path(path, &tmp, buf, buflen); |
... | ... | @@ -2129,12 +2126,7 @@ |
2129 | 2126 | if (!page) |
2130 | 2127 | return -ENOMEM; |
2131 | 2128 | |
2132 | - read_lock(¤t->fs->lock); | |
2133 | - pwd = current->fs->pwd; | |
2134 | - path_get(&pwd); | |
2135 | - root = current->fs->root; | |
2136 | - path_get(&root); | |
2137 | - read_unlock(¤t->fs->lock); | |
2129 | + get_fs_root_and_pwd(current->fs, &root, &pwd); | |
2138 | 2130 | |
2139 | 2131 | error = -ENOENT; |
2140 | 2132 | spin_lock(&dcache_lock); |
fs/fs_struct.c
... | ... | @@ -106,12 +106,7 @@ |
106 | 106 | fs->in_exec = 0; |
107 | 107 | rwlock_init(&fs->lock); |
108 | 108 | fs->umask = old->umask; |
109 | - read_lock(&old->lock); | |
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); | |
109 | + get_fs_root_and_pwd(old, &fs->root, &fs->pwd); | |
115 | 110 | } |
116 | 111 | return fs; |
117 | 112 | } |
fs/namei.c
... | ... | @@ -483,13 +483,8 @@ |
483 | 483 | |
484 | 484 | static __always_inline void set_root(struct nameidata *nd) |
485 | 485 | { |
486 | - if (!nd->root.mnt) { | |
487 | - struct fs_struct *fs = current->fs; | |
488 | - read_lock(&fs->lock); | |
489 | - nd->root = fs->root; | |
490 | - path_get(&nd->root); | |
491 | - read_unlock(&fs->lock); | |
492 | - } | |
486 | + if (!nd->root.mnt) | |
487 | + get_fs_root(current->fs, &nd->root); | |
493 | 488 | } |
494 | 489 | |
495 | 490 | static int link_path_walk(const char *, struct nameidata *); |
... | ... | @@ -1015,11 +1010,7 @@ |
1015 | 1010 | nd->path = nd->root; |
1016 | 1011 | path_get(&nd->root); |
1017 | 1012 | } else if (dfd == AT_FDCWD) { |
1018 | - struct fs_struct *fs = current->fs; | |
1019 | - read_lock(&fs->lock); | |
1020 | - nd->path = fs->pwd; | |
1021 | - path_get(&fs->pwd); | |
1022 | - read_unlock(&fs->lock); | |
1013 | + get_fs_pwd(current->fs, &nd->path); | |
1023 | 1014 | } else { |
1024 | 1015 | struct dentry *dentry; |
1025 | 1016 |
fs/namespace.c
... | ... | @@ -2213,10 +2213,7 @@ |
2213 | 2213 | goto out1; |
2214 | 2214 | } |
2215 | 2215 | |
2216 | - read_lock(¤t->fs->lock); | |
2217 | - root = current->fs->root; | |
2218 | - path_get(¤t->fs->root); | |
2219 | - read_unlock(¤t->fs->lock); | |
2216 | + get_fs_root(current->fs, &root); | |
2220 | 2217 | down_write(&namespace_sem); |
2221 | 2218 | mutex_lock(&old.dentry->d_inode->i_mutex); |
2222 | 2219 | error = -EINVAL; |
fs/proc/base.c
... | ... | @@ -149,18 +149,13 @@ |
149 | 149 | return count; |
150 | 150 | } |
151 | 151 | |
152 | -static int get_fs_path(struct task_struct *task, struct path *path, bool root) | |
152 | +static int get_task_root(struct task_struct *task, struct path *root) | |
153 | 153 | { |
154 | - struct fs_struct *fs; | |
155 | 154 | int result = -ENOENT; |
156 | 155 | |
157 | 156 | task_lock(task); |
158 | - fs = task->fs; | |
159 | - if (fs) { | |
160 | - read_lock(&fs->lock); | |
161 | - *path = root ? fs->root : fs->pwd; | |
162 | - path_get(path); | |
163 | - read_unlock(&fs->lock); | |
157 | + if (task->fs) { | |
158 | + get_fs_root(task->fs, root); | |
164 | 159 | result = 0; |
165 | 160 | } |
166 | 161 | task_unlock(task); |
... | ... | @@ -173,7 +168,12 @@ |
173 | 168 | int result = -ENOENT; |
174 | 169 | |
175 | 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 | 177 | put_task_struct(task); |
178 | 178 | } |
179 | 179 | return result; |
... | ... | @@ -185,7 +185,7 @@ |
185 | 185 | int result = -ENOENT; |
186 | 186 | |
187 | 187 | if (task) { |
188 | - result = get_fs_path(task, path, 1); | |
188 | + result = get_task_root(task, path); | |
189 | 189 | put_task_struct(task); |
190 | 190 | } |
191 | 191 | return result; |
... | ... | @@ -597,7 +597,7 @@ |
597 | 597 | get_mnt_ns(ns); |
598 | 598 | } |
599 | 599 | rcu_read_unlock(); |
600 | - if (ns && get_fs_path(task, &root, 1) == 0) | |
600 | + if (ns && get_task_root(task, &root) == 0) | |
601 | 601 | ret = 0; |
602 | 602 | put_task_struct(task); |
603 | 603 | } |
include/linux/fs_struct.h
... | ... | @@ -21,5 +21,32 @@ |
21 | 21 | extern void daemonize_fs_struct(void); |
22 | 22 | extern int unshare_fs_struct(void); |
23 | 23 | |
24 | +static 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 | + | |
32 | +static 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 | + | |
40 | +static 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 | 51 | #endif /* _LINUX_FS_STRUCT_H */ |
kernel/auditsc.c
... | ... | @@ -1835,13 +1835,8 @@ |
1835 | 1835 | context->names[context->name_count].ino = (unsigned long)-1; |
1836 | 1836 | context->names[context->name_count].osid = 0; |
1837 | 1837 | ++context->name_count; |
1838 | - if (!context->pwd.dentry) { | |
1839 | - read_lock(¤t->fs->lock); | |
1840 | - context->pwd = current->fs->pwd; | |
1841 | - path_get(¤t->fs->pwd); | |
1842 | - read_unlock(¤t->fs->lock); | |
1843 | - } | |
1844 | - | |
1838 | + if (!context->pwd.dentry) | |
1839 | + get_fs_pwd(current->fs, &context->pwd); | |
1845 | 1840 | } |
1846 | 1841 | |
1847 | 1842 | /* audit_putname - intercept a putname request |