linux文件打开和读写流程代码解析

本文深入解析Linux文件系统下打开文件及读写文件的具体流程,包括open()系统调用、do_filp_open()、vfs_open()、fops_get()等关键步骤,以及read()和write()系统调用的执行过程。通过分析,了解文件操作如何从用户空间传递到内核空间,并执行相应的文件操作。
摘要由CSDN通过智能技术生成

打开文件流程:系统调用

fd=open("/dev/pcie_ssd",O_RDWR);


代码定位fs: open.c文件里

SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
{
if (force_o_largefile())
flags |= O_LARGEFILE;


return do_sys_open(AT_FDCWD, filename, flags, mode);
}


long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
{
struct open_flags op;
int fd = build_open_flags(flags, mode, &op);
struct filename *tmp;


if (fd)
return fd;
tmp = getname(filename);
//获取文件名,其内部先创建存取文件名称的空间,然后从用户空间将文件名拷贝过来
if (IS_ERR(tmp))
return PTR_ERR(tmp);


fd = get_unused_fd_flags(flags);
/*获取一个可用的fd,调用alloc_fd从fd_table中获取一个可用的fd并简单初始化,注意对于fd,
它只对本进程有效,也就是它只在该进程中可见而在其他进程中代表完全不同的文件*/
if (fd >= 0) {
struct file *f = do_filp_open(dfd, tmp, &op);//创建file对象,进行路径解析
if (IS_ERR(f)) {
put_unused_fd(fd);
fd = PTR_ERR(f);
} else {
fsnotify_open(f);
/*文件已经被打开了,调用它,根据inode所指定的信息进行打开函数,
将该文件加入到文件监控的系统中,该系统是用来监控文件被打开、创建、读写、关闭、修改等操作的*/
fd_install(fd, f);
/*将文件指针安装到fd数组,将f加入到fd索引位置的数组中,
如果后续过程有对f继续操作的话,就会通过查找该数组得到对应的文件结构,进行操作*/
}
}
putname(tmp);
return fd;

}

struct file *do_filp_open(int dfd, struct filename *pathname,
const struct open_flags *op)
{
struct nameidata nd;
int flags = op->lookup_flags;
struct file *filp;

set_nameidata(&nd, dfd, pathname);
filp = path_openat(&nd, op, flags | LOOKUP_RCU);/*根据op的look_up方法解析路路路径*/
if (unlikely(filp == ERR_PTR(-ECHILD)))
filp = path_openat(&nd, op, flags);
if (unlikely(filp == ERR_PTR(-ESTALE)))
filp = path_openat(&nd, op, flags | LOOKUP_REVAL);
restore_nameidata();
return filp;
}

int vfs_open(const struct path *path, struct file *file,
    const struct cred *cred)
{
struct dentry *dentry = path->dentry;/*根据路径名解析dentry*/
struct inode *inode = dentry->d_inode;/*根据dentry找到inode*/


file->f_path = *path;
if (dentry->d_flags & DCACHE_OP_SELECT_INODE) {
inode = dentry->d_op->d_select_inode(dentry, file->f_flags);
if (IS_ERR(inode))
return PTR_ERR(inode);
}


return do_dentry_open(file, inode, NULL, cred);
}

static int do_dentry_open(struct file *f, struct inode *inode,int (*open)(struct inode *, struct file *),

 const struct cred *cred)

{

........

f->f_op = fops_get(inode->i_fop);//关键,根据inode的i_fop找到文件的f_op

if ((f->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
i_readcount_inc(inode);
if ((f->f_mode & FMODE_READ) &&
    likely(f->f_op->read || f->f_op->read_iter))
f->f_mode |= FMODE_CAN_READ;
if ((f->f_mode & FMODE_WRITE) &&
    likely(f->f_op->write || f->f_op->write_iter))
f->f_mode |= FMODE_CAN_WRITE;

}

路径查找 path_lookup  见链接 http://blog.csdn.net/kickxxx/article/details/9529961

nameidata

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值