Linux-0.11 文件系统read_write.c详解

这篇具有很好参考价值的文章主要介绍了Linux-0.11 文件系统read_write.c详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Linux-0.11 文件系统read_write.c详解

模块简介

该模块实现了文件系统通用的读写的方法read/write/lseek。

根据文件类型的不同,在内部将调用不同的方法。如果是管道文件,则调用pipe.c中的读写方法,如果是字符设备,则会调用char_dev.c中的方法,如果是目录或者普通文件,将调用file_dev.c中的读写方法,如果是块设备文件,将调用block_dev.c中的读写方法。

函数详解

sys_read

int sys_read(unsigned int fd,char * buf,int count)

该函数是read函数的系统调用函数, 主要作用是实现各种类型的读的方法。

其实现原理是通过fd找到对应的inode节点, 然后根据inode节点的属性去调用对应的read方法, 包括read_pipe,rw_char,block_read,file_read。

这里首先对参数进行校验。如果fd大于进程对于fd的限制值NR_OPEN(20), 会返回错误。除此以外, 如果需要读取的字符数量小于0或者fd对应的文件指针为空, 也都会返回错误。

如果count数量为0, 则直接返回0。

struct file * file;
struct m_inode * inode;

if (fd>=NR_OPEN || count<0 || !(file=current->filp[fd]))
    return -EINVAL;
if (!count)
    return 0;

接下来就是通过if语句判断inode的属性去调用对应的read方法, 如果是管道文件, 就调用read_pipe,如果是字符型文件,就调用rw_char进行读取, 如果是块设备文件,就调用block_read, 如果是目录文件或者常规文件, 就调用file_read。

inode = file->f_inode;
if (inode->i_pipe)
    return (file->f_mode&1)?read_pipe(inode,buf,count):-EIO;
if (S_ISCHR(inode->i_mode))
    return rw_char(READ,inode->i_zone[0],buf,count,&file->f_pos);
if (S_ISBLK(inode->i_mode))
    return block_read(inode->i_zone[0],&file->f_pos,buf,count);
if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode)) {
    if (count+file->f_pos > inode->i_size)
        count = inode->i_size - file->f_pos;
    if (count<=0)
        return 0;
    return file_read(inode,file,buf,count);

sys_write

int sys_write(unsigned int fd,char * buf,int count)

该函数的作用与sys_read是有相似之处的,其实现原理是通过fd找到对应的inode节点, 然后根据inode节点的属性去调用对应的write方法, 包括write_pipe,rw_char,block_write,file_write。

接下来就是通过if语句判断inode的属性去调用对应的write方法, 如果是管道文件, 就调用write_pipe,如果是字符型文件,就调用rw_char进行读取, 如果是块设备文件,就调用block_write, 如果是目录文件或者常规文件, 就调用file_write。

if (inode->i_pipe)
    return (file->f_mode&2)?write_pipe(inode,buf,count):-EIO;
if (S_ISCHR(inode->i_mode))
    return rw_char(WRITE,inode->i_zone[0],buf,count,&file->f_pos);
if (S_ISBLK(inode->i_mode))
    return block_write(inode->i_zone[0],&file->f_pos,buf,count);
if (S_ISREG(inode->i_mode))
    return file_write(inode,file,buf,count);

sys_lseek

int sys_lseek(unsigned int fd,off_t offset, int origin)

该函数是重定位文件读写指针的系统调用。文章来源地址https://www.toymoban.com/news/detail-462012.html

	struct file * file;
	int tmp;

	if (fd >= NR_OPEN || !(file=current->filp[fd]) || !(file->f_inode)
	   || !IS_SEEKABLE(MAJOR(file->f_inode->i_dev)))//首先判断参数的有效性
		return -EBADF;
	if (file->f_inode->i_pipe)//管道节点头尾指针不能随意移动
		return -ESPIPE;
	switch (origin) {
		case 0://SEEK_SET  绝对值
			if (offset<0) return -EINVAL;
			file->f_pos=offset;
			break;
		case 1://SEEK_CUR  相对于当前偏移值
			if (file->f_pos+offset<0) return -EINVAL;
			file->f_pos += offset;
			break;
		case 2://SEEK_END
			if ((tmp=file->f_inode->i_size+offset) < 0)
				return -EINVAL;
			file->f_pos = tmp;
			break;
		default:
			return -EINVAL;
	}
	return file->f_pos;
}

到了这里,关于Linux-0.11 文件系统read_write.c详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux-0.11 boot目录head.s详解

    在head.s中,操作系统主要做了如下几件事: 重新设置中断描述符和全局描述符 检查A20地址线是否开启 检查数学协处理器 初始化页表并开启分页 跳转到main函数执行 重新设置IDT和GDT 在setup.s中我们已经设置过了IDT和GDT, 为什么还要再设置一遍? 因为setup.s中设置的IDT和GDT后面

    2024年02月06日
    浏览(30)
  • Linux-0.11 kernel目录进程管理asm.s详解

    该模块和CPU异常处理相关,在代码结构上asm.s和traps.c强相关。 CPU探测到异常时,主要分为两种处理方式,一种是有错误码,另一种是没有错误码,对应的方法就是 error_code 和 no_error_code 。在下面的函数详解中,将主要以两个函数展开。 no_error_code 对于一些异常而言,CPU在出现

    2024年02月07日
    浏览(48)
  • 【Linux操作系统】深入理解系统调用中的read和write函数

    在操作系统中,系统调用是用户程序与操作系统之间进行交互的重要方式。其中,read和write函数是常用的系统调用函数,用于在用户程序和操作系统之间进行数据的读取和写入。本文将深入介绍read和write函数的工作原理、用法以及示例代码,以帮助读者更好地理解和应用这两

    2024年02月13日
    浏览(33)
  • 操作系统实验 2.3系统调用:linux-0.11-lab “为版本0内核增加一个系统调用getjiffies” 和 “在用户程序中使用新增的系统调用”

    打开 vscode ,在如图所示位置打开 ~/os/linux-0.11-lab/0 文件夹 1.定义getjiffies系统调用 题目中给的提示:进入到 unistd.h 文件中 阅读代码,可以发现上图划线处有个系统调用名为 getpid :返回当前进程号——这与我们期望实现的功能类似:通过系统调用返回jiffies值。 于是此时希望

    2023年04月08日
    浏览(83)
  • Linux 0.11: 从开机到执行shell

    参考闪客的系列,将开机到执行shell的整个过程浓缩成本文。 https://github.com/dibingfa/flash-linux0.11-talk 当按下开机键的那一刻,在主板上提前写死的固件程序  BIOS  会将硬盘中 启动区的 512 字节 的数据,原封不动复制到 内存中的 0x7c00  这个位置,并跳转到那个位置进行执行。

    2024年04月13日
    浏览(19)
  • Linux-open、read、write函数

    1、open函数 详细使用可以使用Linux命令:man 2 open flags参数 :(注意这里可以使用 |来添加多个参数),如: flags三个访问权限参数:( 注意这三个参数在flags中只能出现其中一个 ) O_RDONLY:只读          O_WRONLY:只写          O_RDWR:读写 flags其他参数: O_CREAT:若文件不

    2024年02月15日
    浏览(33)
  • IO学习系列之使用read和write复制文件内容

    read函数: 功能:从 文件fd 中读取 count个字节 ,存放进 指针buf ; 具体内容: write函数: 功能:把 指针buf 中的内容,写 count个字节 到 文件fd 中; 具体内容: 示例代码:

    2024年02月07日
    浏览(33)
  • C#,入门教程(28)——文件夹(目录)、文件读(Read)与写(Write)的基础知识

    上一篇:   C#,入门教程(27)——应用程序(Application)的基础知识 https://blog.csdn.net/beijinghorn/article/details/125094837 C#知识比你的预期简单的多,但也远远超乎你的想象! 与 文件 相关的知识,不算多。 作为初学者,先学习 文本文件 的读写,就足够应付好几年了。 文件 自然是

    2024年01月23日
    浏览(50)
  • Python---文件、基本操作:打开open,写入write,关闭close,读取read/readlines,移动光标seek,mode模式

    文件: 内存中存放的数据在计算机关机后就会消失。 要长久保存数据 ,就要使用硬盘、光盘、U 盘等设备。 为了便于数据的管理和检索,引入了 “文件 ”的概念。 像移动硬盘,内存卡,网盘等等。 一篇文章、一段视频、一个可执行程序,都可以被保存为一个文件,并赋予

    2024年02月03日
    浏览(43)
  • C语言读写文件函数:read/write,pread/pwrite,readv/writev,preadv/pwritev,preadv2/pwritev2

    函数原型 示例程序 read/write/pread/pwrite函数比较直观,这里仅示例readv/writev函数用法。 把程序中定义的buf通过writev函数输出到屏幕上。 分析 读写多个缓冲区,有几种策略: 调用read、write分别操作多次 这种方式多次切换内核态,效率最低。 把多个缓冲区复制合并到同一个大的

    2024年02月12日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包