您的位置:首页 > 其它

文件路径查找do_path_lookup

2013-04-02 20:29 931 查看
每个进程都有他自己当前的工作目录和它自己的根目录。这是内核用来标识进程与文件系统相互作用做必须维护的数据;每个进程的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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: