系统调用chdir最终要通过路径名查找目标dentry
比如说,在控制台执行"cd /usr/bin", 就需要找到"/usr/bin"对应的dentry和vfsmount
chdir->
user_path_at->
do_path_lookup
int user_path_at(int dfd, const char __user *name, unsigned flags,
struct path *path)
{
struct nameidata nd;
char *tmp = getname(name);
int err = PTR_ERR(tmp);
if (!IS_ERR(tmp)) {
BUG_ON(flags & LOOKUP_PARENT);
err = do_path_lookup(dfd, tmp, flags, &nd);
putname(tmp);
if (!err)
*path = nd.path;
}
return err;
}
-
#define user_path_dir(name, path) \
user_path_at(AT_FDCWD, name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, path)
-
SYSCALL_DEFINE1(chdir, const char __user *, filename)
-
{
-
struct path path;
-
int error;
-
-
error = user_path_dir(filename, &path);
-
if (error)
-
goto out;
-
-
...
-
-
dput_and_out:
-
path_put(&path);
-
out:
-
return error;
-
}
do_path_lookup的功能是:根据参数"name",找到其对应的dentry和vfsmount结构。
函数主要有两部分:
1. 确定查找起始点的path(dentry和vfsmount结构), 这个功能由path_init函数实现
对于"/usr/bin"来说,起始路径是"/", path_init需要确定"/"的dentry和vfsmount。起始路径信息记录在nd->path里面。
2. 从起始点查找"name"对应的path(dentry和vfsmount结构), 这个功能由path_walk实现
对于"/usr/bin"来说,起始路径是"/", name是"usr/bin"。在执行path_init时,已经确定了"/"的dentry和vfsmount,所以path_walk从"/"开始,先在"/"下查找"usr"这个路径分量的dentry,找到之后,再根据"usr"的dentry,到"/usr"下查找"bin"这个路径分量的dentry。
-
-
/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
static int do_path_lookup(int dfd, const char *name,
unsigned int flags, struct nameidata *nd)
{
-
/* 1. 确定查找起始点的path(dentry和vfsmount结构) */
int retval = path_init(dfd, name, flags, nd);
-
-
2. 从起始点查找”name"对应的path(dentry和vfsmount结构)
if (!retval)
retval = path_walk(name, nd);
if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
nd->path.dentry->d_inode))
audit_inode(name, nd->path.dentry);
if (nd->root.mnt) {
path_put(&nd->root);
nd->root.mnt = NULL;
}
return retval;
}
阅读(927) | 评论(0) | 转发(0) |