Virtual file system

Levels of VFS

Between the file system implementation and the user process (or C library).

 

File system classification

Disk-based file system (ext2/3 fat iso9660...), virtual file system (proc), network file system (nfs)

 

 

Common file model

VFS provides a structural model that contains all the components that a powerful file system should have. All file system implementations must provide routines that cooperate with the structure defined by the VFS to make up for the difference between the two attempts.

 

File descriptor

An integer used to identify a file in all file-related operations in the user layer. It is created by the kernel when the file is opened and is process-specific.

 

 

inode

 

l What is inode?

² Inode is used to store the metadata of the file (for example, the creator of the file, the creation date of the file, the size of the file, etc.)

² Note that the inode does not include the file name.

 

l inode content

The inode contains the meta information of the file, specifically the following content:

² The size of the file, the User ID and Group ID of the file owner

 

² File read, write, and execute permissions

² The timestamp of the file: ctime (the time when the inode was last changed), mtime (the time when the file content was last changed), and atime (the time when the file was last opened).

² The number of links, that is, how many file names point to this inode.

² In which disk blocks the file data is distributed.

 

l inode status

Each inode is in one of three states:

² The inode is located in the memory and is not associated with the file; (inode_unused)

² The inode is located in the memory, used by one or more processes, and has been synchronized with the disk; (inode_in_used)

² The inode is in active use, not synchronized with the content on the disk, and the inode is dirty;

 

l How is inode organized?

² The kernel uses two ways to organize inodes.

² Linked list: Each inode has an i_list member, and the inode can be stored in the linked list. (The inode appears in i_sb_list in the super block-specific linked list, and also appears in the state-specific linked list, such as inode_in_used)

² Hash: each inode appears in a hash table at the same time (according to the inode number to quickly access the inode).

 

l What is the directory?

² Under Linux, directories are also files, as well as inode and data parts. The contents of the data part are as follows:

The first part indicates the number of the corresponding inode (unique in the system), and the second part indicates the name of the file or directory.

How does the kernel access /user/bin/emacs

 

First read the root directory (this is always maintained in the kernel), find the user directory entry in the data part of the root directory file, and obtain the inode according to the inode number in it. The bin search is similar, until emacs is found, and the inode corresponding to emacs is found. The data part of the inode is the content of the emacs file (ordinary data file).

Icon:

 

 

Directory item cache dentry :

 

l Introduce dentry

 

The above process of accessing /user/bin/emacs is very time-consuming, and it is necessary to continuously read the inode and the corresponding data part. In order to speed up, the kernel caches previously accessed directories or files (collectively referred to as directory entries). Next time you access the same directory entry (for example, the /user/bin/ part of /user/bin/vi), you can directly Find the corresponding inode (number 10 in the picture above).

 

l The purpose of dentry:

The main purpose of dentry is to establish the association between file name and inode.

So the structure includes the two most important fields, d_inode and d_name .

Among them, d_name is the file name. qstr is the kernel's encapsulation of strings (can be understood as char* with a hash value).

d_inode is the inode corresponding to the file name.

 

l dentry structure:

struct dentry {

    

 

/* Where the name belongs to - NULL is negative */

    struct inode *d_inode; 

 

struct qstr d_name;

 

struct dentry *d_parent/* parent directory */

    union {

    struct list_head d_child/* child of parent list */

    struct rcu_head d_rcu;

    } d_u;

    struct list_head d_subdirs/* our children */

    struct dentry_operations *d_op;

    struct super_block *d_sb/* The root of the dentry tree */

    unsignedchard_iname[DNAME_INLINE_LEN_MIN]; /* small names */

 

};

 

l When was it created

After the VFS (and the file system implementation) reads a directory entry (directory or ordinary file), a dentry is created to cache the data found.

 

l How to organize and manage these dentry in memory

² Structure: Each dentry instance forms a network, for example, all files and subdirectories associated with the current dentry instance are included in d_subdirs.

² Organization method 1: All active dentry instances of the kernel are stored in a hash table, which is implemented using dentry_hashtable (global dentry hash table).

² Organization 2: LRU linked list, dentry that is not used for a long time will be deleted.

 

 

Link

 

l Two types of links: symbolic links (soft links) and hard links.

l The symbolic link (soft link) file uses its own inode. The data part of the inode contains a string that gives the path of the link target.

l When the hard link is created, the existing inode number is used. After the hard link is established, it is impossible to distinguish between the original file and the newly created hard link file. In this case, the inode uses a counter to ensure that in the file deletion operation, the inode can be deleted when there is no other file using the inode.

Schematic diagram:

 

 

 

 

Process-specific information

struct task_struct {

     ...

     /* Information about the file system of the process*/

     struct fs_struct *fs;

     /* Files opened by this process*/

     struct files_struct *files;

     ...

}

 

struct files_struct {

     ...

     struct fdtable fdtab;

     struct file * fd_array[NR_OPEN_DEFAULT];

};

 

struct file {

     ...

 

struct path *f_path;

     loff_t   f_pos;

     ...

 

};

 

 

struct file_operations {

     ...

     ssize_t (*write) (struct file *, constchar __user *, size_t, loff_t *);

     int (*readdir) (struct file *, void *, filldir_t);

     unsignedint (*poll) (struct file *, struct poll_table_struct *);

     int (*ioctl) (struct inode *, struct file *, unsignedintunsignedlong);

     int (*mmap) (struct file *, struct vm_area_struct *);

     int (*open) (struct inode *, struct file *);

     ...

};

 

The struct  file_operations->open function essentially associates a file object to an inode.

The poll function is also among them.

 

 

 

From task to dentry/inode

 

Guess you like

Origin blog.csdn.net/daocaokafei/article/details/114873160