Linux系统成功的关键因素之一就是具有与其他操作系统和谐共存的能力。Linux系统的文件系统由两层结构构建:第一层是虚拟文件系统(VFS),第二层是各种不同的具体的文件系统。 
VFS就是把各种具体的文件系统的公共部分抽取出来,形成一个抽象层,是系统内核的一部分,它位于用户程序和具体的文件系统之间。它对用户提供了标准的文件系统调用接口,对具体的文件系统(如EXT2、FAT32等),它通过一系列的对不同文件系统公用的函数指针来实际调用具体的文件系统函数,完成实际的各有差异的操作。任何使用文件系统的程序必须经过这层接口来使用它。通过这样的方式,VFS就对用户屏蔽了底层文件系统的实现细节和差异。 
在VFS的支持下,用户态进程读写任何类型的文件系统都可以使用read和write着两个系统调用,但是在linux内核中没有这样的系统调用我们如何操作文件呢?我们知道read和write在进入内核态之后,实际执行的是sys_read和sys_write,但是查看内核源代码,发现这些操作文件的函数都没有导出(使用EXPORT_SYMBOL导出),也就是说在内核模块中是不能使用的.通过查看sys_open的源码我们发现,其主要使用了do_filp_open()函数,该函数在fs/namei.c中,而在改文件中,filp_open函数也是调用了do_filp_open函数,并且接口和sys_open函数极为相似,调用参数也和sys_open一样,并且使用EXPORT_SYMBOL导出了,所以我们猜想该函数可以打开文件,功能和open一样。使用同样的查找方法,我们找出了一组在内核中操作文件的函数,如下:

我们注意到在vfs_read和vfs_write函数中,其参数buf指向的用户空间的内存地址,如果我们直接使用内核空间的指针,则会返回-EFALUT。所以我们需要使用set_fs()和get_fs()宏来改变内核对内存地址检查的处理方式。 
另外,使用vfs_read()和vfs_write()需要注意的一点是最后的参数loff_t *pos,pos所指向的值要初始化,表明从文件的什么地方开始读写。例如,可以使用 loff_t pos = fp->f_pos; 
实例代码:

  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/sched.h>
  4. #include <linux/dcache.h>
  5. #include <linux/fs.h>
  6. #include <linux/err.h>
  7. #include <linux/string.h>
  8. #include <linux/errno.h>
  9. #include <asm/fcntl.h>
  10. #include <asm/processor.h>
  11. #include <asm/uaccess.h>
  12. int __init hello_init(void)
  13. {
  14. unsigned char buf1[12]="hello world.";
  15. unsigned char buf2[12]="kernel file.";
  16. struct file *fp;
  17. mm_segment_t fs;
  18. loff_t pos;
  19. printk("hello enter\n");
  20. fp = filp_open("/home/kernel_file", O_RDWR | O_CREAT, 0644);
  21. if (IS_ERR(fp)) {
  22. printk("create file error\n");
  23. return -1;
  24. }
  25. fs = get_fs();
  26. set_fs(KERNEL_DS);
  27. pos = fp->f_pos;
  28. vfs_write(fp, buf1, sizeof(buf1), &pos);
  29. fp->f_pos = pos;
  30. pos = fp->f_pos;
  31. vfs_write(fp, buf2, sizeof(buf2), &pos);
  32. fp->f_pos = pos;
  33. set_fs(fs);
  34. filp_close(fp, NULL);
  35. return 0;
  36. }
  37. void __exit hello_exit(void)
  38. {
  39. printk("hello exit\n");
  40. }
  41. module_init(hello_init);
  42. module_exit(hello_exit);
  43. MODULE_LICENSE("GPL");
  44. (转载自 网络 原创不详)

filp_open/filp_close/vfs_read/vfs_write的更多相关文章

  1. kernel中文件的读写操作可以使用vfs_read()和vfs_write

    需要在Linux kernel--大多是在需要调试的驱动程序--中读写文件数据.在kernel中操作文件没有标准库可用,需要利用kernel的一些函数,这些函数主要有: filp_open() fil ...

  2. (六)kernel中文件的读写操作可以使用vfs_read()和vfs_write

    需要在Linux kernel--大多是在需要调试的驱动程序--中读写文件数据.在kernel中操作文件没有标准库可用,需要利用kernel的一些函数,这些函数主要有: filp_open() fil ...

  3. 【转】 Linux内核中读写文件数据的方法--不错

    原文网址:http://blog.csdn.net/tommy_wxie/article/details/8193954 Linux内核中读写文件数据的方法  有时候需要在Linuxkernel--大 ...

  4. 内核驱动程序中如何读写user space的文件,方便调试程序

    需要在Linux kernel--大多是在需要调试的驱动程序--中读写文件数据.但是在kernel中操作文件没有标准库可用,需要利用kernel的一些函数,这些函数主要有: filp_open() f ...

  5. 向linux内核增加一个系统调用-2(利用proc打印信息)

    添加系统调用,打印/proc中的系统信息 前面关于proc和内核态函数的东西可以对比代码来看. 参考 http://blog.csdn.net/kylin_fire_zeng/article/deta ...

  6. linux内核驱动中对文件的读写 【转】

    本文转载自:http://blog.chinaunix.net/uid-13059007-id-5766941.html 有时候需要在Linux kernel--大多是在需要调试的驱动程序--中读写文 ...

  7. iscsi target IET架构

    IET(iSCSI Enterprise Target)是内核态实现的iscsi target,相比于用户态实现的target(比如tgt),iet比较稳定,并且也算是历史悠久,io都直接经过内核态, ...

  8. KVM虚拟机IO处理过程(一) ----Guest VM I/O 处理过程

    虚拟化技术主要包含三部分内容:CPU虚拟化,内存虚拟化,设备虚拟化.本系列文章主要描述磁盘设备的虚拟化过程,包含了一个读操作的I/O请求如何从Guest Vm到其最终被处理的整个过程.本系列文章中引用 ...

  9. Intel 80x86 Linux Kernel Interrupt(中断)、Interrupt Priority、Interrupt nesting、Prohibit Things Whthin CPU In The Interrupt Off State

    目录 . 引言 . Linux 中断的概念 . 中断处理流程 . Linux 中断相关的源代码分析 . Linux 硬件中断 . Linux 软中断 . 中断优先级 . CPU在关中断状态下编程要注意 ...

随机推荐

  1. Centos 利用yum安装卸载软件常用命令[转载]

    一.使用yum安装和卸载软件,有个前提是yum安装的软件包都是rpm格式的. 安装的命令是,yum install ~,yum会查询数据库,有无这一软件包,如果有,则检查其依赖冲突关系,如果没有依赖冲 ...

  2. NOT NULL constraint faile(慢就是快,少即是多)

    在学习数据库orm操作的过程中,遇到一个写不进去数据的问题 在创建数据库进行数据写入时出错,错误信息是 NOT NULL constraint faile(错误信息没有第一时间找到) 数据库,包括表都 ...

  3. 限流redis+lua

    限流==保险丝策略,可借助框架如spring cloud中Hystrix组件实现.今天介绍使用guava RateLimiter 类实现接口限流. 比如12306抢票: https://blog.cs ...

  4. 基于Redis的分布式锁真的安全吗?

    说明: 我前段时间写了一篇用consul实现分布式锁,感觉理解的也不是很好,直到我看到了这2篇写分布式锁的讨论,真的是很佩服作者严谨的态度, 把这种分布式锁研究的这么透彻,作者这种技术态度真的值得我好 ...

  5. EC20 R2.1

    1.模块开机成功前WAKEUP_IN. NET_MODE. BT_CTS. COEX_UART_TX(背部焊盘). COEX_UART_RX(背部焊盘) 和WLAN_EN(背部焊盘)引脚禁止上拉. 2 ...

  6. 野路子码农系列(3)plotly可视化的简单套路

    又双叒叕要跟客户汇报了,图都准备好了吗?matplotlib出图嫌丑?那用用plotly吧,让你的图看上去经费爆炸~ P1 起因 第一次接触plotly这个库是在我们做的一个列车信号数据挖掘的项目里, ...

  7. trackerClient.getConnection()为null

    如题,整了个fastDFS文件服务器.但是集成项目spring boot时上传文件失败! Debug到trackerClient.getConnection()时为null.于是看了服务器上track ...

  8. OAuth2

    OAuth2: 适合To C的应用场景, 比如我们开发一个app, 可以借用微信/微博用户认证开放接口, 达到免注册登陆, 企业内部系统没有必要引入. OAuth2的步骤较多, 角色也较多, 涉及到a ...

  9. 使用fork的str_cli函数

    void str_cli(FILE *fp, int sockfd) { pid_t pid; char sendline[MAXLINE], recvline[MAXLINE]; ) { /* ch ...

  10. CSS部分语法2

    <!-- 第1部分 尺寸与框模型 略 第2部分背景设置 2.1 背景颜色:background-color:value 2.2 背景图片:background-image body{ backg ...