般我们讲,都说进程有文件描述符表,文件描述符表中的指针指向某个inode,这中间省略了file,dentry对象,对准确理解VFS结构无益,本文结合网络所查,并根据APUE8.3和LKD13.11章节校对,总结在下,希望有用。
内核中,对应于每个进程都有一个文件描述符表,表示这个进程打开的所有文件。文件描述表中每一项都是一个指针,指向一个用于描述打开的文件的数据块———file对象,file对象中描述了文件的打开模式,读写位置等重要信息,当进程打开一个文件时,内核就会创建一个新的file对象。需要注意的是,file对象不是专属于某个进程的,不同进程的文件描述符表中的指针可以指向相同的file对象,从而共享这个打开的文件。file对象有引用计数,记录了引用这个对象的文件描述符个数,只有当引用计数为0时,内核才销毁file对象,因此某个进程关闭文件,不影响与之共享同一个file对象的进程.
在Linux中,进程是通过文件描述符(file descriptors,简称fd)而不是文件名来访问文件的,文件描述符实际上是一个整数。Linux中规定每个进程能最多能同时使用NR_OPEN个文件描述符,这个值在fs.h中定义,为1024*1024(2.0版中仅定义为256)。 fd是文件描述符表的索引!!!
每个文件都有一个32位的数字来表示下一个读写的 字节位置,这个数字叫做文件位置。每次打开一个文件,除非明确要求,否则文件位置都被置为0,即文件的开始处,此后的读或写操作都将从文件的开始处执行, 但你可以通过执行系统调用LSEEK(随机存储)对这个文件位置进行修改。Linux中专门用了一个数据结构file来保存打开文件的文件位置,这个结构 称为打开的文件描述(open file description)。这个数据结构的设置是煞费苦心的,因为它与进程的联系非常紧密,可以说这是VFS中一个比较难于理解的数据结构。
file结构中主要保存了文件位置,此外,还把指向该文件索引节点的指针也放在其中。file结构形成一个双链表,称为系统打开文件表,其最大长度是NR_FILE,在fs.h中定义为8192。
file结构在include\linux\fs.h中定义如下:
- struct file
- {
- struct list_head f_list;
- struct dentry *f_dentry;
- struct vfsmount *f_vfsmnt;
- struct file_operations *f_op;
- mode_t f_mode;
- loff_t f_pos;
- unsigned short f_flags;
- unsigned short f_count;
- unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin;
- int f_owner;
- unsigned int f_uid, f_gid;
- int f_error;
- unsigned long f_version;
- void *private_data;
- };
-
- struct inode {
- struct list_headi_hash;
- struct list_headi_list;
- struct list_headi_dentry;
- struct list_headi_dirty_buffers;
- unsigned longi_ino;
- atomic_t i_count;
- kdev_t i_dev;
- umode_t i_mode;
- nlink_t i_nlink;
- uid_t i_uid;
- gid_t i_gid;
- kdev_t i_rdev;
- off_t i_size;
- time_t i_atime;
- time_t i_mtime;
- time_t i_ctime;
- unsigned long i_blksize;
- unsigned long i_blocks;
- unsigned long i_version;
- unsigned short i_bytes;
- struct semaphore i_sem;
- struct rw_semaphore i_truncate_sem;
- struct semaphore i_zombie;
- struct inode_operations *i_op;
- struct file_operations *i_fop;
- struct super_block *i_sb;
- wait_queue_head_t i_wait;
- struct file_lock *i_flock;
- struct address_space *i_mapping;
- struct address_space i_data;
- struct dquot *i_dquot [MAXQUOTAS];
- struct pipe_inode_info *i_pipe;
- struct block_device *i_bdev;
- struct char_device *i_cdev;
- unsigned longi_dnotify_mask;
- struct dnotify_struct *i_dnotify;
- unsigned long i_state;
- unsigned int i_flags;
- unsigned char i_sock;
- atomic_t i_write count;
- unsigned int i_attr_flags;
- __u32 i_generation;
- union {
- struct minix_inode_info minix_i;
- struct ext2_inode_info ext2_i;
- struct ext3_inode_info ext3_i;
- struct hpfs_inode_info hpfs_i;
- struct ntfs_inode_info ntfs_i;
- struct msdos_inode_info msdos_i;
- struct umsdos_inode_info umsdos_i;
- struct iso_inode_info isofs_i;
- struct sysv_inode_info sysv_i;
- struct affs_inode_info affs_i;
- struct ufs_inode_info ufs_i;
- struct efs_inode_info efs_i;
- struct romfs_inode_info romfs_i;
- struct shmem_inode_info shmem_i;
- struct coda_inode_info coda_i;
- struct smb_inode_info smbfs_i;
- struct hfs_inode_info hfs_i;
- struct adfs_inode_info adfs_i;
- struct qnx4_inode_info qnx4_i;
- struct reiserfs_inode_info reiserfs_i;
- struct bfs_inode_info bfs_i;
- struct udf_inode_info udf_i;
- struct ncp_inode_info ncpfs_i;
- struct proc_inode_info proc_i;
- struct socketsocket_i;
- struct usbdev_inode_info usbdev_i;
- struct jffs2_inode_infojffs2_i;
- void *generic_ip;
- } u;
- };