文件对象

文件对象是进程已经打开文件描述符的内存中的表示,单个文件可能有多个表示打开文件描述符的file结构;

  1. struct file {
  2. union {
  3. struct llist_node fu_llist; /* 文件对象链表 */
  4. struct rcu_head fu_rcuhead; /* 释放之后的RCU链表 */
  5. } f_u;
  6. /* 目录项 */
  7. struct path f_path;
  8. /* inode */
  9. struct inode *f_inode; /* cached value */
  10. /* 文件操作 */
  11. const struct file_operations *f_op;
  12.  
  13. /*
  14. * Protects f_ep_links, f_flags.
  15. * Must not be taken from IRQ context.
  16. */
  17. /* 锁 */
  18. spinlock_t f_lock;
  19. /* 引用计数 */
  20. atomic_long_t f_count;
  21. /* 打开文件时所指定的标志 */
  22. unsigned int f_flags;
  23. /* 文件访问模式 */
  24. fmode_t f_mode;
  25. struct mutex f_pos_lock;
  26. /* 文件当前偏移量 */
  27. loff_t f_pos;
  28. /* 拥有者通过信号进行异步IO数据传送 */
  29. struct fown_struct f_owner;
  30. /* 文件的信任状 */
  31. const struct cred *f_cred;
  32. /* 预读状态 */
  33. struct file_ra_state f_ra;
  34. /* 版本号 */
  35. u64 f_version;
  36. #ifdef CONFIG_SECURITY
  37. /* 安全模块 */
  38. void *f_security;
  39. #endif
  40. /* needed for tty driver, and maybe others */
  41. /* tty设备驱动的钩子 */
  42. void *private_data;
  43.  
  44. #ifdef CONFIG_EPOLL
  45. /* Used by fs/eventpoll.c to link all the hooks to this file */
  46. /* 事件池链表 */
  47. struct list_head f_ep_links;
  48. struct list_head f_tfile_llink;
  49. #endif /* #ifdef CONFIG_EPOLL */
  50. /* 页缓存映射 */
  51. struct address_space *f_mapping;
  52. } __attribute__((aligned())); /* lest something weird decides that 2 is OK */
文件操作

file_operations提供了文件操作函数,这些函数与系统调用进行关联;

  1. /* 文件操作 */
  2. struct file_operations {
  3. /* 拥有该模块的指针,通常被初始化为THIS_MODULE */
  4. struct module *owner;
  5. /*
  6. 用来修改文件的当前读写位置,并将新位置作为返回值,由系统调用lseek调用
  7. 参数2是一个"长偏移量";
  8. 参数3是SEEK_SET,SEEK_CUR,SEEK_END中的一个:
  9. SEEK_SET-参数2设置为新的读写位置
  10. SEEK_CUR-当前读写位置后增加参数2个偏移量
  11. SEEK_END-读写位置指向文件尾后再增加参数2个偏移量
  12. */
  13. loff_t (*llseek) (struct file *, loff_t, int);
  14. /*
  15. 从给定文件的offset偏移出读取count字节数据到buf中,
  16. 同时更新文件指针,由系统调用read调用
  17. */
  18. ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
  19. /*
  20. 从给定buf中读取count字节数据,写入给定文件offset偏移处,
  21. 同时更新文件指针,由系统调用write调用
  22. */
  23. ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
  24. /* 同步异步读写 */
  25. ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
  26. ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
  27.  
  28. int (*iterate) (struct file *, struct dir_context *);
  29. int (*iterate_shared) (struct file *, struct dir_context *);
  30. /* 睡眠等待给定文件活动,由系统调用poll调用 */
  31. unsigned int (*poll) (struct file *, struct poll_table_struct *);
  32. /*
  33. 用来给设备发送名称参数对,当文件是一个被打开的设备节点时,
  34. 可以通过它进行设置,由系统调用iotcl调用
  35. */
  36. long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
  37. /*
  38. 是ioctl函数的可移植变种,被32位应用程序用在64位系统上,
  39. 新的驱动程序应该设计自己的ioctl命令,以便所有的驱动程序都是可移植的,
  40. 从而使得compat_ioctl和unlocked_ioctl指向同一个函数
  41. */
  42. long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
  43. /* 将给定的文件映射到指定地址空间行,由系统调用mmap调用 */
  44. int (*mmap) (struct file *, struct vm_area_struct *);
  45. /* 创建一个新的文件对象,并将它和响应的索引节点对象关联起来,由系统调用open调用 */
  46. int (*open) (struct inode *, struct file *);
  47. /* 当已打开文件的引用计数减少时,该函数被VFS调用,它的作用根据具体文件系统而定 */
  48. int (*flush) (struct file *, fl_owner_t id);
  49. /*
  50. 当文件最后一个引用被注销时(如当最后一个共享文件描述符进程调用了close()或者退出),
  51. 该函数被VFS调用,它的作用根据具体文件系统而定
  52.  
  53. */
  54. int (*release) (struct inode *, struct file *);
  55. /* 将给定文件的所有被缓存数据写回磁盘,由系统调用fsync调用 */
  56. int (*fsync) (struct file *, loff_t, loff_t, int datasync);
  57. /* 打开或者关闭异步IO的通告信号 */
  58. int (*fasync) (int, struct file *, int);
  59. /* 给指定文件上锁 */
  60. int (*lock) (struct file *, int, struct file_lock *);
  61. /* 用来从一个文件向另外一个文件发送数据 */
  62. ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
  63. /* 在进程和地址空间中找到一个合适的位置,以便将底层设备中的内存段映射到该位置 */
  64. unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
  65. /* 允许模块检查传递给fcntl(F_SETFL...)调用的标志 */
  66. int (*check_flags)(int);
  67. /* 实现flock()系统调用,该调用提供忠告锁 */
  68. int (*flock) (struct file *, int, struct file_lock *);
  69. ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
  70. ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
  71. int (*setlease)(struct file *, long, struct file_lock **, void **);
  72. long (*fallocate)(struct file *file, int mode, loff_t offset,
  73. loff_t len);
  74. void (*show_fdinfo)(struct seq_file *m, struct file *f);
  75. #ifndef CONFIG_MMU
  76. unsigned (*mmap_capabilities)(struct file *);
  77. #endif
  78. ssize_t (*copy_file_range)(struct file *, loff_t, struct file *,
  79. loff_t, size_t, unsigned int);
  80. int (*clone_file_range)(struct file *, loff_t, struct file *, loff_t,
  81. u64);
  82. ssize_t (*dedupe_file_range)(struct file *, u64, u64, struct file *,
  83. u64);
  84. };
inode对象

内核用inode结构在内部表示文件,因此它和file结构不同,后者表示打开的文件描述符。对单个文件,可能会有多个表示打开文件描述符的file结构,但它们都指向单个inode结构;

inode结构中包含了大量有关文件的信息。作为常规,只有下面两个字段对编写驱动程序代码有用

dev_t i_rdev:

对表示设备文件的inode结构,该字段包含了真正的设备编号;

struct cdev *i_cdev:

表示字符设备的内核的内部结构,当inode指向一个字符设备文件时,该字段包含了指向struct cdev结构的指针;

从inode中获取主设备号和次设备号,使用下面函数,不要直接操作i_rdev:

  1. static inline unsigned iminor(const struct inode *inode)
  2. {
  3. return MINOR(inode->i_rdev);
  4. }
  5.  
  6. static inline unsigned imajor(const struct inode *inode)
  7. {
  8. return MAJOR(inode->i_rdev);
  9. }

Linux设备驱动程序 之 重要数据结构的更多相关文章

  1. linux设备驱动程序该添加哪些头文件以及驱动常用头文件介绍(转)

    原文链接:http://blog.chinaunix.net/uid-22609852-id-3506475.html 驱动常用头文件介绍 #include <linux/***.h> 是 ...

  2. 【转】linux设备驱动程序之简单字符设备驱动

    原文网址:http://www.cnblogs.com/geneil/archive/2011/12/03/2272869.html 一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用 ...

  3. 【转】linux设备驱动程序中的阻塞机制

    原文网址:http://www.cnblogs.com/geneil/archive/2011/12/04/2275272.html 阻塞与非阻塞是设备访问的两种方式.在写阻塞与非阻塞的驱动程序时,经 ...

  4. Linux设备驱动程序学习----2.内核模块与应用程序的对比

    内核模块与应用程序的对比 更多内容请参考Linux设备驱动程序学习----目录 1. 内核模块与应用程序的对比 内核模块和应用程序之间的不同之处: 大多数中小规模的应用程序是从头到尾执行单个任务,而模 ...

  5. Linux设备驱动程序学习----3.模块的编译和装载

    模块的编译和装载 更多内容请参考Linux设备驱动程序学习----目录 1. 设置测试系统 第1步,要先从kernel.org的镜像网站上获取一个主线内核,并安装到自己的系统中,因为学习驱动程序的编写 ...

  6. Linux设备驱动程序 第三版 读书笔记(一)

    Linux设备驱动程序 第三版 读书笔记(一) Bob Zhang 2017.08.25 编写基本的Hello World模块 #include <linux/init.h> #inclu ...

  7. Linux设备驱动程序学习之分配内存

    内核为设备驱动提供了一个统一的内存管理接口,所以模块无需涉及分段和分页等问题. 我已经在第一个scull模块中使用了 kmalloc 和 kfree 来分配和释放内存空间. kmalloc 函数内幕 ...

  8. 教你写Linux设备驱动程序:一个简短的教程

    教你写Linux设备驱动程序:一个简短的教程 http://blog.chinaunix.net/uid-20799298-id-99675.html

  9. linux设备驱动程序_hello word 模块编译各种问题集锦

    在看楼经典书籍<linux设备驱动程序>后,第一个程序就是编写一个hello word 模块. 原以为非常easy,真正弄起来,发现问题不少啊.前两天编过一次,因为没有记录,今天看的时候又 ...

随机推荐

  1. VBA学习资料分享-5

    工作中经常要从数据库把数据跑出来放到EXCEL上,才能进行下一步的操作,那么除了ADO,还有什么方法可以导入数据库数据呢? 推荐使用QueryTable对象 Dim qt As querytable ...

  2. 记录一次SourceTree无法push问题排查及解决

    1.push代码卡住,一直转圈2.试了下拉取代码也拉不到3.试了使用git命令行push可以4.使用Sourcetree新建项目,一直在检查url.5.初步判断原因,SourceTree无法联网.6. ...

  3. Shell中比较判断

    一.shell判断数组中是否包含某个元素:ary=(1 2 3)a=2if [[ "${ary[@]}" =~ "$a" ]] ; then    echo & ...

  4. explicit和implicit

    explicit是C++中的一个关键字,只用于修饰只有一个参数的构造函数: class A{ explicit A(const T obj); }; 该关键字告诉编译器该类只能显式的转换,不能隐式(i ...

  5. django请求周期和请求信息

    Django的请求周期 1,概述 首先我们知道HTTP请求及服务端响应中传输的所有数据都是字符串. 在Django中,当我们访问一个的url时,会通过路由匹配进入相应的html网页. 那么: Djan ...

  6. identity server4获取token和userInfo

    一.简介 IdentityServer4(ids4)是用于ASP.NET Core的OpenID Connect和OAuth 2.0框架.在许多成熟的.net core框架中都完美的集成的该身份服务框 ...

  7. PAT Basic 1087 有多少不同的值 (20 分)

    当自然数 n 依次取 1.2.3.…….N 时,算式 ⌊ 有多少个不同的值?(注:⌊ 为取整函数,表示不超过 x 的最大自然数,即 x 的整数部分.) 输入格式: 输入给出一个正整数 N(2). 输出 ...

  8. CentOS7 基于 subversion 配置 SVN server

    由于 Window Server 环境下,VisualSVN Server Community 版本只支持 15 个同时在线用户,所以彻底放弃 Windows Server,在 Linux Serve ...

  9. javascript 常用的一些原生方法

    一丶javascript------ reduce() reduce()方法: arr.reduce(function(prev,cur,index,arr){ ... }, init); 参数解释: ...

  10. use redir to make port redirecting

    Step 1: install redir apt-get update apt-get install redir -y Step2 : add port mapping redir --lport ...