diff options
| -rw-r--r-- | fs/namespace.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 0a42e0e9602..f7ec283ccfb 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
| @@ -2131,25 +2131,33 @@ static void chroot_fs_refs(struct path *old_root, struct path *new_root) | |||
| 2131 | { | 2131 | { |
| 2132 | struct task_struct *g, *p; | 2132 | struct task_struct *g, *p; |
| 2133 | struct fs_struct *fs; | 2133 | struct fs_struct *fs; |
| 2134 | int count = 0; | ||
| 2134 | 2135 | ||
| 2135 | read_lock(&tasklist_lock); | 2136 | read_lock(&tasklist_lock); |
| 2136 | do_each_thread(g, p) { | 2137 | do_each_thread(g, p) { |
| 2137 | task_lock(p); | 2138 | task_lock(p); |
| 2138 | fs = p->fs; | 2139 | fs = p->fs; |
| 2139 | if (fs) { | 2140 | if (fs) { |
| 2140 | atomic_inc(&fs->count); | 2141 | write_lock(&fs->lock); |
| 2141 | task_unlock(p); | ||
| 2142 | if (fs->root.dentry == old_root->dentry | 2142 | if (fs->root.dentry == old_root->dentry |
| 2143 | && fs->root.mnt == old_root->mnt) | 2143 | && fs->root.mnt == old_root->mnt) { |
| 2144 | set_fs_root(fs, new_root); | 2144 | path_get(new_root); |
| 2145 | fs->root = *new_root; | ||
| 2146 | count++; | ||
| 2147 | } | ||
| 2145 | if (fs->pwd.dentry == old_root->dentry | 2148 | if (fs->pwd.dentry == old_root->dentry |
| 2146 | && fs->pwd.mnt == old_root->mnt) | 2149 | && fs->pwd.mnt == old_root->mnt) { |
| 2147 | set_fs_pwd(fs, new_root); | 2150 | path_get(new_root); |
| 2148 | put_fs_struct(fs); | 2151 | fs->pwd = *new_root; |
| 2149 | } else | 2152 | count++; |
| 2150 | task_unlock(p); | 2153 | } |
| 2154 | write_unlock(&fs->lock); | ||
| 2155 | } | ||
| 2156 | task_unlock(p); | ||
| 2151 | } while_each_thread(g, p); | 2157 | } while_each_thread(g, p); |
| 2152 | read_unlock(&tasklist_lock); | 2158 | read_unlock(&tasklist_lock); |
| 2159 | while (count--) | ||
| 2160 | path_put(old_root); | ||
| 2153 | } | 2161 | } |
| 2154 | 2162 | ||
| 2155 | /* | 2163 | /* |
