Commit f8ef3ed2 authored by Al Viro's avatar Al Viro

Get rid of bumping fs_struct refcount in pivot_root(2)

Not because execve races with _that_ are serious - we really
need a situation when final drop of fs_struct refcount is
done by something that used to have it as current->fs.
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 11d06b2a
...@@ -2131,25 +2131,33 @@ static void chroot_fs_refs(struct path *old_root, struct path *new_root) ...@@ -2131,25 +2131,33 @@ static void chroot_fs_refs(struct path *old_root, struct path *new_root)
{ {
struct task_struct *g, *p; struct task_struct *g, *p;
struct fs_struct *fs; struct fs_struct *fs;
int count = 0;
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
do_each_thread(g, p) { do_each_thread(g, p) {
task_lock(p); task_lock(p);
fs = p->fs; fs = p->fs;
if (fs) { if (fs) {
atomic_inc(&fs->count); write_lock(&fs->lock);
task_unlock(p);
if (fs->root.dentry == old_root->dentry if (fs->root.dentry == old_root->dentry
&& fs->root.mnt == old_root->mnt) && fs->root.mnt == old_root->mnt) {
set_fs_root(fs, new_root); path_get(new_root);
fs->root = *new_root;
count++;
}
if (fs->pwd.dentry == old_root->dentry if (fs->pwd.dentry == old_root->dentry
&& fs->pwd.mnt == old_root->mnt) && fs->pwd.mnt == old_root->mnt) {
set_fs_pwd(fs, new_root); path_get(new_root);
put_fs_struct(fs); fs->pwd = *new_root;
} else count++;
task_unlock(p); }
write_unlock(&fs->lock);
}
task_unlock(p);
} while_each_thread(g, p); } while_each_thread(g, p);
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
while (count--)
path_put(old_root);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment