Transferred from: http://www.cnblogs.com/Jezze/archive/2011/12/23/2299861.html
Simple generalization: FD is just an integer that is generated when open. As an index, the process uses the file descriptor in the PCB to find the file pointer Filp that the FD points to.
Open: The operation of the file descriptor (for example: Open) returns a file descriptor (int fd), which maintains a file descriptor table in each process space, and all open files are referenced by the file descriptor (Fd1,fd2,fd3 ...) in this form.
Fopen: While the stream (for example: fopen) returns a file structure pointer that contains a document descriptor, the files structure function can be considered as encapsulation of the system call to the FD direct operation, which has the advantage of having an I/O cache.
Linux supports a wide variety of file system formats, such as Ext2, Ext3, ReiserFS, FAT, NTFS, iso9660, and so on, and different disk partitions, discs, or other storage devices have different file system formats, but these file systems can be in mount
a directory, So that we see a unified directory tree, directories and files on various file systems we use ls
commands to look the same, and read and write operations are the same, how is this done? The Linux kernel makes an abstraction layer on top of various file system formats, making the concepts of files, directories, read-write access, and so on, a concept of abstraction, so that the various file systems look the same (VFS), an abstraction layer called the virtual file system (VFS, Virtual Filesystem), this section describes the runtime file system representation in the kernel.
the VFS subsystem of the Linux kernel can be illustrated as follows:
Each process holds a file Descriptor table in the PCB (Process Control block), which is an index to the list, and each table entry in the File description table has a pointer to the open file. Now let's be clear: The open file is represented in the kernel by the file
struct, the pointer in the file descriptor table points to the file
struct ( understanding : FD is the file descriptor of the open file, and each process has a file description table, and the FD file descriptor is the index of this table. Also in this table is a table item, which again points to the file structure that mentions the open files, and the file struct is the struct in the kernel that describes the properties of the files.
struct file-----define in Inlcude/linux/fs.h
struct file_operations------define in Include/linux/fs.h
1 structfile {2 Union {3 structLlist_node fu_llist;4 structRcu_head Fu_rcuhead;5 } F_u;6 structpath F_path;7 #defineF_dentry F_path.dentry8 structInode *f_inode;/*Cached Value*/9 Const structFile_operations *F_op;Ten One /* A * Protects F_ep_links, f_flags. - * must not being taken from IRQ context. - */ the spinlock_t F_lock; - atomic_long_t F_count; -Unsignedintf_flags; - fmode_t F_mode; + structMutex F_pos_lock; - loff_t F_pos; + structfown_struct F_owner; A Const structCred *f_cred; at structfile_ra_state F_ra; - - U64 f_version; - #ifdef config_security - void*f_security; - #endif in /*needed for TTY driver, and maybe others*/ - void*Private_data; to + #ifdef Config_epoll - /*used by fs/eventpoll.c to link all the hooks to this file*/ the structList_head f_ep_links; * structList_head F_tfile_llink; $ #endif/* #ifdef Config_epoll */Panax Notoginseng structAddress_space *f_mapping; - #ifdef Config_debug_writecount theUnsignedLongf_mnt_write_state; + #endif A} __attribute__ ((Aligned (4)));/*lest something weird decides that 2 is OK*/
struct File
1 structfile_operations {2 structModule *owner;3loff_t (*llseek) (structFile *, loff_t,int);4ssize_t (*read) (structFile *,Char__user *, size_t, loff_t *);5ssize_t (*write) (structFile *,Const Char__user *, size_t, loff_t *);6ssize_t (*aio_read) (structKIOCB *,Const structIovec *, unsignedLong, loff_t);7ssize_t (*aio_write) (structKIOCB *,Const structIovec *, unsignedLong, loff_t);8 int(*iterate) (structFile *,structDir_context *);9Unsignedint(*poll) (structFile *,structPoll_table_struct *);Ten Long(*UNLOCKED_IOCTL) (structFile *, unsignedint, unsignedLong); One Long(*COMPAT_IOCTL) (structFile *, unsignedint, unsignedLong); A int(*mmap) (structFile *,structVm_area_struct *); - int(*open) (structInode *,structFile *); - int(*flush) (structFile *, fl_owner_t ID); the int(*release) (structInode *,structFile *); - int(*fsync) (structFile *, loff_t, loff_t,intdatasync); - int(*aio_fsync) (structKIOCB *,intdatasync); - int(*fasync) (int,structFile *,int); + int(*Lock) (structFile *,int,structFile_lock *); -ssize_t (*sendpage) (structFile *,structPage *,int, size_t, loff_t *,int); +UnsignedLong(*get_unmapped_area) (structFile *, unsignedLong, unsignedLong, unsignedLong, unsignedLong); A int(*check_flags) (int); at int(*flock) (structFile *,int,structFile_lock *); -ssize_t (*splice_write) (structPipe_inode_info *,structFILE *, loff_t *, size_t, unsignedint); -ssize_t (*splice_read) (structFILE *, loff_t *,structPipe_inode_info *, size_t, unsignedint); - int(*setlease) (structFile *,Long,structFile_lock * *); - Long(*fallocate) (structFile *file,intmode, loff_t offset, - loff_t len); in int(*show_fdinfo) (structSeq_file *m,structFile *f); -};
struct File_operations
1.file. File Status Flag and File.f_count
Maintains file
the file Status Flag ( file
the members of the struct f_flags
) and the current read-write location ( file
members of the struct f_pos
) in the struct. In, process 1 and Process 2 both open the same file, but correspond to different file
structures , so you can have different file Status flags and read and write locations. The file
more important members of the struct are the f_count
reference count (Reference count), which we'll talk about, and dup
so on, and fork
so on, the system call causes multiple file descriptors to point to the same file
struct . For example, the reference count fd1
fd2
file
of the same struct is 2, when the close(fd1)
struct is not released file
, but only the reference count is reduced to 1, and if again close(fd2)
, the reference count is reduced to 0 and released file
Structure, which really closed the file.
2.file.file_operations
Eachfile
Structs all point to a file_operations
Structural Body, the members of this struct are function pointers, which point to kernel functions that implement various file operations. For example, in the user programread
A file descriptor,read
Through the system call into the kernel, and then find the file descriptor pointing to thefile
Structure, findfile
The structure is pointing to thefile_operations
struct, call it'sread
The kernel function that the member points to to complete the user request (Application Layer-to-kernel layer invocation process)。 Called in the user programlseek
、read
、write
、ioctl
、open
And so on, which is ultimately called by the kernelfile_operations
The kernel functions that each member points to to complete the user request.file_operations
In the structurerelease
Member is used to complete the user program'sclose
Request, the reason is calledrelease
Rather than callingclose
Because it does not necessarily close the file, but reduces the reference count, only the reference count is reduced to 0 to close the file. For regular files that are open on the same file system,read
、write
such as the steps and methods of the file operation should be the same, the calling function should be the same, so the diagram of the three open filefile
The struct points to the samefile_operations
Structural body. If you open a character device file, then it'sread
、write
Operation must not be the same as regular files, not read and write disk data blocks but read and write hardware devices,so file
the struct should point to a different file_operations
struct (there is also a user-defined struct object or a kernel custom struct object), where the various file manipulation functions are implemented by the driver for the device.
3.file.dentry
Each file
struct has a dentry
pointer to the struct, and"Dentry" is an abbreviation for directory entry (directory entry) . The open
parameters of the function that we pass to, and stat
so on, are a path, for example /home/akaedu/a
, to find the inode of the file based on the path. in order to reduce the number of reads, the kernel caches the tree structure of the directory, called the Dentry cache, where each node is a dentry
struct, as long as the dentry is searched along the parts of the path, and the directory is found from the root directory. /
home
Then locate akaedu
the directory, and then locate the file a
. Dentry cache saves only recently accessed directory entries, and if the directory entry you are looking for is not in the cache, it will be read from disk to memory.
4.dentry.inode
Each dentry
struct has a pointer to the inode
struct body. inode
The structure holds the information read from the disk Inode . In the example, there are two dentry, respectively, /home/akaedu/a
and /home/akaedu/b
They all point to the same inode, stating that the two files are hard links to each other . The inode
structure holds information from the inode of the partition, such as the owner, file size, file type, and permission bit (Inode has parameters that normally understand that the file structure may contain this information, in fact, File.inode members manage this information) . Each inode
struct has a inode_operations
pointer to the struct, which is a set of function pointers that point to some kernel functions that complete the file directory operation. and file_operations
different, the inode_operations
point is not to operate on a file function, but to affect the file and directory layout of functions, such as the addition of deleted files and directories, trace symbolic links, and so on, the same file system can point to the same structure of the structure of the inode
inode_operations
body.
5.inod.super_block
inode
The struct has a super_block
pointer to the struct body. The super_block
structure holds information that is read from the Super block of the disk partition , such as file system type, block size, and so on. The member of the super_block
struct s_root
is a pointer to the location of the dentry
mount
root directory of the file system, in which case the partition is taken mount
to the /home
directory.
, and, file
dentry
inode
super_block
These structures constitute the core concept of VFS . For ext2 file systems, there is also the concept of inode and Super block on disk storage layouts, so it is easy to establish correspondence with the concepts in VFS. Other file system formats from non-UNIX systems (such as Windows FAT32, NTFS), may not have the inode or Super block concept, but in order to get mount
to the Linux system, but also in the driver hard to gather, Looking at FAT32 and NTFS partitions under Linux, you will find that the permissions bits are wrong, and all the files are rwxrwxrwx
, because they don't have the concept of inode and permission bit, which is hard to come by.
Understanding of File Descriptor fd and file pointer flip in Linux