您的位置:首页 > 运维架构 > Linux

文件结构体struct file(Linux 2.6.23内核)

2008-08-26 12:38 441 查看
一、定义:
struct
file结构体定义在/linux/include/linux/fs.h(Linux
2.6.11内核)中,其原型是:
721struct file
{
 722        /*
 723         * fu_list becomes invalid after file_free is called and queued via
 724         * fu_rcuhead for RCU freeing
 725         */
 726        union {
 727                struct list_head        fu_list;
 728                struct rcu_head         fu_rcuhead;
 729        } f_u;
 730        struct path             f_path;
 731#define f_dentry        f_path.dentry
 732#define f_vfsmnt        f_path.mnt
 733        const struct file_operations    *f_op;
 734        atomic_t                f_count;
 735        unsigned int            f_flags;
 736        mode_t                  f_mode;
 737        loff_t                  f_pos;
 738        struct fown_struct      f_owner;
 739        unsigned int            f_uid, f_gid;
 740        struct file_ra_state    f_ra;
 741
 742        unsigned long           f_version;
 743#ifdef CONFIG_SECURITY
 744        void                    *f_security;
 745#endif
 746        /* needed for tty driver, and maybe others */
 747        void                    *private_data;
 748
 749#ifdef CONFIG_EPOLL
 750        /* Used by fs/eventpoll.c to link all the hooks to this file */
 751        struct list_head        f_ep_links;
 752        spinlock_t              f_ep_lock;
 753#endif /* #ifdef CONFIG_EPOLL */
 754        struct address_space    *f_mapping;


755};
二、作用:

件结构体代表一个打开的文件,系统中每个打开的文件在内核空间都有一个关联的struct
file。它由内核在打开文件时创建,并传递给在文件上进行操作的任何函数。在文件的所有实例都关闭后,内核释放这个数据结构。在内核创建和驱动源码
中,struct
file的指针通常被命名为file或filp。
三、个字段详解:
1、
union
{
struct list_head fu_list;

struct rcu_head rcuhead;
}f_u;
其中的struct
list_head定义在
linux/include/linux/list.h中,原型为:
21struct list_head
{
  22        struct list_head *next, *prev;


23};
list_head是内核中最常用的建立双向循环链表的结构,在此用于通用文件对象链表的指针。
struct
rcu_head定义在linux/include/linux/rcupdate.h中,其原型为:
50struct rcu_head
{
  51        struct rcu_head *next;
  52        void (*func)(struct rcu_head *head);


53};
RCU(Read-Copy
Update)是Linux
2.6内核中新的锁机制,具体参考:
http://www.ibm.com/developerworks/cn/linux/l-rcu/
在此用于更新文件。fu_list在file_free()函数被调用以后就无效了,队列通过rcu_head来释放RCU。
2struct
path f_path;
被定义在linux/include/linux/namei.h中,其原型为:
32struct path
{
  33        struct vfsmount *mnt;
  34        struct dentry *dentry;


35};
在早些版本的内核中并没有此结构,而是直接将path的两个数据成员作为struct
file的数据成员,
struct
vfsmount *mnt的作用是指出该文件的已安装文件系统,
struct
dentry *dentry是与文件相关的目录项对象。
3、const
struct file_operations
*f_op;
被定义在linux/include/linux/fs.h中,其中包含着与文件关联的操作,如:
loff_t
(*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct
file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct
file *, const char __user *, size_t, loff_t
*);
等。当打开一个文件时,内核就创建一个与该文件相关联的struct
file结构,其中的*f_op就指向的是具
体对该文件进行操作的函数。例如用户调用系统调用read来读取该文件的内容时,那么系统调用read最终会陷入内核调用sys_read函数,而
sys_read最终会调用与该文件关联的struct
file结构中的f_op->read函数对文件内容进行读取。
4、atomic_t
f_count;
atomic_t被定义为:
typedef
struct { volatile int counter; }
atomic_t;
volatile修饰字段告诉gcc不要对该类型的数据做优化处理,对它的访问都是对内存的访问,而不是对寄存器的访问。
本质是int类型,之所以这样写是让编译器对基于该类型变量的操作进行严格的类型检查。此处f_count的作用是记录对文件对象的引用计数,也即当前有多少个使用CLONE_FILES标志克隆的进程在使用该文件。典型的应用是在POSIX线程中。就像在内核中普通的引用计数模块一样,最后一个进程调用put_files_struct()来释放文件描述符。
5、unsigned
int f_flags;
当打开文件时指定的标志,对应系统调用open的int
flags参数。驱动程序为了支持非阻塞型操作需要检查这个标志。
六、mode_t
f_mode;
对文件的读写模式,对应系统调用open的mod_t
mode参数。如果驱动程序需要这个值,可以直接读取这个字段。
mod_t被定义为:
typedef
unsigned int __kernel_mode_t;
typedef __kernel_mode_t
mode_t;
7、loff_t
f_pos;
当前的文件指针位置,即文件的读写位置。
loff_t被定义为:
typedef
long long __kernel_loff_t;
typedef __kernel_loff_t
loff_t;
8、struct
fown_struct f_owner;
struct
fown_struct在linux/include/linux/fs.h被定义,原型为:
 688struct fown_struct {
 689  rwlock_t lock;          /* protects pid, uid, euid fields */
 690  struct pid *pid;        /* pid or -pgrp where SIGIO should be sent */
 691  enum pid_type pid_type;/*Kind of process group SIGIO should be sent to*/
 692  uid_t uid, euid;        /* uid/euid of process setting the owner */
 693  int signum;             /* posix.1b rt signal to be delivered on IO */
 694};

该结构的作用是通过信号进行I/O时间通知的数据。
9、unsigned
int f_uid, f_gid;
标识文件的所有者id,所有者所在组的id.
10、struct
file_ra_state f_ra;
struct
file_ra_state结构被定义在/linux/include/linux/fs.h中,原型为:
699struct file_ra_state
{
 700        pgoff_t start;                  /* where readahead started */
 701        unsigned long size;             /* # of readahead pages */
 702        unsigned long async_size;       /* do asynchronous readahead when
 703                                           there are only # of pages ahead */
 704
 705        unsigned long ra_pages;         /* Maximum readahead window */
 706        unsigned long mmap_hit;       /* Cache hit stat for mmap accesses */
 707        unsigned long mmap_miss;  /* Cache miss stat for mmap accesses */
 708       unsigned long prev_index;       /* Cache last read() position */
 709     unsigned int prev_offset; /* Offset where last read() ended in a page */


710};
文件预读状态,文件预读算法使用的主要数据结构,当打开一个文件时,f_ra中出了perv_page(默认为-1)和ra_apges(对该文件允许的最大预读量)这两个字段外,其他的所有字端都置为0。
11、unsigned
long f_version;
记录文件的版本号,每次使用后都自动递增。
12、
#ifdef
CONFIG_SECURITY

void *f_security;
#endif
此处我的理解是如果在编译内核时配置了安全措施,那么struct
file结构中就会有void
*f_security数据项,用来描述安全措施或者是记录与安全有关的信息。
13、void
*private_data;
系统在调用驱动程序的open方法前将这个指针置为NULL。驱动程序可以将这个字段用于任意目的,也可以忽略这个字段。驱动程序可以用这个字段指向已分配的数据,但是一定要在内核释放file结构前的release方法中清除它。
14、
#ifdef
CONFIG_EPOLL
/* Used by fs/eventpoll.c to link all the hooks to
this file */
struct list_head f_ep_links;
spinlock_t
f_ep_lock;
#endif /* #ifdef CONFIG_EPOLL
*/
被用在fs/eventpoll.c来链接所有钩到这个文件上。其中f_ep_links是文件的事件轮询等待者链表的头,f_ep_lock是保护f_ep_links链表的自旋锁。
15、struct
address_space *f_mapping;
struct
address_space被定义在/linux/include/linux/fs.h中,此处是指向文件地址空间的指针。
四、应用:

在驱动开发中,文件读/写模式mode、标志f_flags都是设备驱动关心的内容,而私有数据指针private_data在驱动中被广泛使用,大多被指向设备驱动自定义的用于描述设备的结构体。驱动程序中常用如下类似的代码来检测用户打开文件的读写方式:
if
(file->f_mode & FMODE_WRITE) //用户要求可写

{
}
if (file->f_mode & FMODE_READ)
//用户要求可读

{
}
下面的代码可用于判断以阻塞还是非阻塞方式打开设备文件:

if (file->f_flags & O_NONBLOCK)
//非阻塞
pr_debug("open:non-blocking/n");

else //阻塞

pr_debug("open:blocking/n");

******************
inode结构与file结构的区别:
内核用inode结构在内部表示文件。file结构表示打开的文件描述符,对单个文件,可能会有许多个表示打开的文件描述符的file结构,但他们都指向单个inode结构。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: