Linux文件系统之文件的读写.doc
《Linux文件系统之文件的读写.doc》由会员分享,可在线阅读,更多相关《Linux文件系统之文件的读写.doc(35页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、Linux文件系统之文件的读写(续二) - 本文系本站原创,欢迎转载!转载请注明出处:-八:VFS层的I/O操作VFS层是与用户界面直接交互的接口,在这一节里,我们将分为读写两部份来介绍VFS层的操作以及跟上层用用的交互.8.1:文件的读操作在用户空间,读文件操作的常用函数为read()。对应在系统空间的调用入口是sys_read().它的代码如下:asmlinkage ssize_t sys_read(unsigned int fd, char _user * buf, size_t count) struct file *file; ssize_t ret = -EBADF; int fp
2、ut_needed; /根据fd从进程中取出相应的file对象 file = fget_light(fd, &fput_needed); if (file) loff_t pos = file_pos_read(file); /文件的当前位置 ret = vfs_read(file, buf, count, &pos); /更新当前的文件位置 file_pos_write(file, pos); fput_light(file, fput_needed); return ret;从进程中取得文件描述符后和文件当前的操作位置后会调用vfs_read()执行具体的操作过程.它的代码如下:ssize
3、_t vfs_read(struct file *file, char _user *buf, size_t count, loff_t *pos) struct inode *inode = file-f_dentry-d_inode; ssize_t ret; if (!(file-f_mode & FMODE_READ) return -EBADF; if (!file-f_op | (!file-f_op-read & !file-f_op-aio_read) return -EINVAL;/检查当前区段是否允许读操作 ret = locks_verify_area(FLOCK_VER
4、IFY_READ, inode, file, *pos, count); if (!ret) /是否有权限 ret = security_file_permission (file, MAY_READ); if (!ret) /如果有read 操作,调用之 if (file-f_op-read) ret = file-f_op-read(file, buf, count, pos); else /否则调用aio_read ret = do_sync_read(file, buf, count, pos); /ret: 写入的字节数 if (ret 0) /产生通告 dnotify_parent
5、(file-f_dentry, DN_ACCESS); return ret;从上面看到,会最终调用file的相关操作完成文件的读操作.曾记得我们在文件的打开一节中分析了文件的打开过程。在打开文件过程中,文件描述符的相关操作会被赋值为inode-f_op.对于ext2文件系统,inode的相关信息如下: inode-i_fop = &ext2_file_operations;struct file_operations ext2_file_operations = .llseek = generic_file_llseek, .read = generic_file_read, .write
6、= generic_file_write, .aio_read = generic_file_aio_read, .aio_write = generic_file_aio_write, .ioctl = ext2_ioctl, .mmap = generic_file_mmap, .open = generic_file_open, .release = ext2_release_file, .fsync = ext2_sync_file, .readv = generic_file_readv, .writev = generic_file_writev, .sendfile = gene
7、ric_file_sendfile,相应文件读操作入口为generic_file_read():ssize_tgeneric_file_read(struct file *filp, char _user *buf, size_t count, loff_t *ppos) /用户空间的地址和长度 struct iovec local_iov = .iov_base = buf, .iov_len = count ; /记录完成状态 struct kiocb kiocb; ssize_t ret; /kiocb.ki_key=KIOCB_SYNC_KEY; kiocb.ki_filp=filp;
8、kiocb.ki_obj=current; init_sync_kiocb(&kiocb, filp); /返回读写完成的字节数 ret = _generic_file_aio_read(&kiocb, &local_iov, 1, ppos); /异步操作,需用等待 if (-EIOCBQUEUED = ret) ret = wait_on_sync_kiocb(&kiocb); /返回完成的字节数 return ret;_generic_file_aio_read()是一个很重要的函数,它是读操作的入口。代码如下:ssize_t_generic_file_aio_read(struct k
9、iocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t *ppos) struct file *filp = iocb-ki_filp; ssize_t retval; unsigned long seg; size_t count; count = 0; for (seg = 0; seg iov_len; if (unlikely(ssize_t)(count|iv-iov_len) iov_base 开始的iov_len区间的合法性 if (access_ok(VERIFY_WRITE, iv-iov_base
10、, iv-iov_len) continue; if (seg = 0) return -EFAULT; /nr_seg: 有效的数据段数目 nr_segs = seg; /上一个数据段无效,将其长度减下来 count -= iv-iov_len; /* This segment is no good */ break; /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */ /如果定义了O_DIRECT:直接传送数据绕过了页高速缓存 if (filp-f_flags & O_DIRECT) loff_t pos = *ppos,
11、 size; struct address_space *mapping; struct inode *inode; mapping = filp-f_mapping; inode = mapping-host; retval = 0; if (!count) goto out; /* skip atime */ size = i_size_read(inode); if (pos = 0 & !is_sync_kiocb(iocb) retval = -EIOCBQUEUED; if (retval 0) *ppos = pos + retval; file_accessed(filp);
12、goto out; /count:读取文件的长度 retval = 0; if (count) for (seg = 0; seg host; unsigned long index, end_index, offset; loff_t isize; struct page *cached_page; int error; struct file_ra_state ra = *_ra; cached_page = NULL; /找到页面的偏移量。即确定是存储在那个存面中 index = *ppos PAGE_CACHE_SHIFT; /第一个请求字节在页面的偏移量 /亦即请求的字节在页面中的偏
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux 文件系统 文件 读写
限制150内