每个进程都有他自己当前的工作目录和它自己的根目录。这是内核用来标识进程与文件系统相互作用做必须维护的数据;每个进程的fs字段指向进程的fs_struct结构;
struct path {
struct vfsmount *mnt;
struct dentry *dentry;
};
/include/linux line6
struct fs_struct { int users; // 共享这个表的进程个数 rwlock_t lock; //用于表中字段的读写自旋锁 int umask; //打开文件设置文件权限是所使用的位掩码 int in_exec; struct path root, pwd; };
struct nameidata用于保存与路径名查找操作有关的数据对象;
struct qstr { unsigned int hash; unsigned int len; const unsigned char *name; }; struct nameidata { struct path path;//目录项对象的地址和已安装文件系统对象的地址 struct qstr last;//路径名的最后一个分量 unsigned int flags;//查找标志 int last_type;//路径名最后一个分量的类型 unsigned depth; //符号链接嵌套的当前级别 char *saved_names[MAX_NESTED_LINKS + 1];//符号链接嵌套的当前级别 /* Intent data */ union { struct open_intent open;//指点如何访问文件 } intent; };
查找过程
static int do_path_lookup(int dfd, const char *name, unsigned int flags, struct nameidata *nd) { int retval = 0; int fput_needed; struct file *file; struct fs_struct *fs = current->fs; /*初始化查找结果*/ nd->last_type = LAST_ROOT; /* if there are only slashes... */ nd->flags = flags; nd->depth = 0; if (*name=='/') { //从根目录开始查找 read_lock(&fs->lock); nd->path = fs->root; path_get(&fs->root);//增加目录对象和文件系统对象的引用计数 read_unlock(&fs->lock); } else if (dfd == AT_FDCWD) { //从当前目录开始查找 read_lock(&fs->lock); nd->path = fs->pwd; path_get(&fs->pwd); read_unlock(&fs->lock); } else { //从其他目录查找 struct dentry *dentry; file = fget_light(dfd, &fput_needed); retval = -EBADF; if (!file) goto out_fail; dentry = file->f_path.dentry; retval = -ENOTDIR; if (!S_ISDIR(dentry->d_inode->i_mode)) goto fput_fail; retval = file_permission(file, MAY_EXEC); if (retval) goto fput_fail; nd->path = file->f_path; path_get(&file->f_path); fput_light(file, fput_needed); } 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); out_fail: return retval; fput_fail: fput_light(file, fput_needed); goto out_fail; }