转自:http://www.cnblogs.com/Jezze/archive/2011/12/23/2299861.html

简单归纳:fd只是一个整数,在open时产生。起到一个索引的作用,进程通过PCB中的文件描述符表找到该fd所指向的文件指针filp。

open:文件描述符的操作(如: open)返回的是一个文件描述符(int fd),内核会在每个进程空间中维护一个文件描述符表, 所有打开的文件都将通过此表中的文件描述符来引用(fd1,fd2,fd3...); 
fopen:而流(如: fopen)返回的是一个FILE结构指针, FILE结构是包含有文件描述符的,FILE结构函数可以看作是对fd直接操作的系统调用的封装, 它的优点是带有I/O缓存.

Linux支持各种各样的文件系统格式,如ext2、ext3、reiserfs、FAT、NTFS、iso9660等等,不同的磁盘分区、光盘或其它存储设备都有不同的文件系统格式,然而这些文件系统都可以mount到某个目录下,使我们看到一个统一的目录树,各种文件系统上的目录和文件我们用ls命令看起来是一样的,读写操作用起来也都是一样的,这是怎么做到的呢?Linux内核在各种不同的文件系统格式之上做了一个抽象层,使得文件、目录、读写访问等概念成为抽象层的概念,因此各种文件系统看起来用起来都一样(VFS作用),这个抽象层称为虚拟文件系统(VFS,Virtual Filesystem),这一节我们介绍运行时文件系统在内核中的表示。

Linux内核的VFS子系统可以图示如下:

Linux中文件描述符fd和文件指针flip的理解

每个进程在PCB(Process Control Block)即进程控制块中都保存着一份文件描述符表,文件描述符就是这个表的索引,文件描述表中每个表项都有一个指向已打开文件的指针,现在我们明确一下:已打开的文件在内核中用file结构体表示,文件描述符表中的指针指向file结构体(理解:fd为打开文件的文件描述符,而每个进程都有一张文件描述表,fd文件描述符就是这张表的索引,同样这张表中有一表项,该表项又是指向前面提到打开文件的file结构体,file结构体才是内核中用于描述文件属性的结构体)。

struct file-----define in inlcude/linux/fs.h

struct file_operations------define in include/linux/fs.h

 1 struct file {
 2     union {
 3         struct llist_node    fu_llist;
 4         struct rcu_head     fu_rcuhead;
 5     } f_u;
 6     struct path        f_path;
 7 #define f_dentry    f_path.dentry
 8     struct inode        *f_inode;    /* cached value */
 9     const struct file_operations    *f_op;
10 
11     /*
12      * Protects f_ep_links, f_flags.
13      * Must not be taken from IRQ context.
14      */
15     spinlock_t        f_lock;
16     atomic_long_t        f_count;
17     unsigned int         f_flags;
18     fmode_t            f_mode;
19     struct mutex        f_pos_lock;
20     loff_t            f_pos;
21     struct fown_struct    f_owner;
22     const struct cred    *f_cred;
23     struct file_ra_state    f_ra;
24 
25     u64            f_version;
26 #ifdef CONFIG_SECURITY
27     void            *f_security;
28 #endif
29     /* needed for tty driver, and maybe others */
30     void            *private_data;
31 
32 #ifdef CONFIG_EPOLL
33     /* Used by fs/eventpoll.c to link all the hooks to this file */
34     struct list_head    f_ep_links;
35     struct list_head    f_tfile_llink;
36 #endif /* #ifdef CONFIG_EPOLL */
37     struct address_space    *f_mapping;
38 #ifdef CONFIG_DEBUG_WRITECOUNT
39     unsigned long f_mnt_write_state;
40 #endif
41 } __attribute__((aligned(4)));    /* lest something weird decides that 2 is OK */
struct file
 1 struct file_operations {
 2     struct module *owner;
 3     loff_t (*llseek) (struct file *, loff_t, int);
 4     ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
 5     ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
 6     ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
 7     ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
 8     int (*iterate) (struct file *, struct dir_context *);
 9     unsigned int (*poll) (struct file *, struct poll_table_struct *);
10     long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
11     long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
12     int (*mmap) (struct file *, struct vm_area_struct *);
13     int (*open) (struct inode *, struct file *);
14     int (*flush) (struct file *, fl_owner_t id);
15     int (*release) (struct inode *, struct file *);
16     int (*fsync) (struct file *, loff_t, loff_t, int datasync);
17     int (*aio_fsync) (struct kiocb *, int datasync);
18     int (*fasync) (int, struct file *, int);
19     int (*lock) (struct file *, int, struct file_lock *);
20     ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
21     unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
22     int (*check_flags)(int);
23     int (*flock) (struct file *, int, struct file_lock *);
24     ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
25     ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
26     int (*setlease)(struct file *, long, struct file_lock **);
27     long (*fallocate)(struct file *file, int mode, loff_t offset,
28               loff_t len);
29     int (*show_fdinfo)(struct seq_file *m, struct file *f);
30 };
struct file_operations

相关文章: