提交 8b19e341 编写于 作者: L Linus Torvalds

vfs: make getcwd() get the root and pwd path under rcu

This allows us to skip all the crazy spinlocks and reference count
updates, and instead use the fs sequence read-lock to get an atomic
snapshot of the root and cwd information.

We might want to make the rule that "prepend_path()" is always called
with the RCU lock held, but the RCU lock nests fine and this is the
minimal fix.
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 5762482f
......@@ -3015,15 +3015,16 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen)
return ERR_PTR(-ENAMETOOLONG);
}
static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root,
struct path *pwd)
static void get_fs_root_and_pwd_rcu(struct fs_struct *fs, struct path *root,
struct path *pwd)
{
spin_lock(&fs->lock);
*root = fs->root;
path_get(root);
*pwd = fs->pwd;
path_get(pwd);
spin_unlock(&fs->lock);
unsigned seq;
do {
seq = read_seqcount_begin(&fs->seq);
*root = fs->root;
*pwd = fs->pwd;
} while (read_seqcount_retry(&fs->seq, seq));
}
/*
......@@ -3053,7 +3054,8 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
if (!page)
return -ENOMEM;
get_fs_root_and_pwd(current->fs, &root, &pwd);
rcu_read_lock();
get_fs_root_and_pwd_rcu(current->fs, &root, &pwd);
error = -ENOENT;
br_read_lock(&vfsmount_lock);
......@@ -3088,8 +3090,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
}
out:
path_put(&pwd);
path_put(&root);
rcu_read_unlock();
free_page((unsigned long) page);
return error;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册