The fifth day of the 10-day learning Linux Kernel---questions about the Linux file system implementation

Source: Internet
Author: User

Have time to sleep, but still five point more awake, but have been lying down nine points more to calculate up, last night has been the embedded Development Board, some problems did not solve, their computer system problems, although Win10 released,, but I still like XP Ah, good want to go home with the Home XP to play this piece of board, Unconsciously also the fifth day, feel the code is a little vague, even their own are not very clear, worry about sharing now more confused, the way the big God more criticism ah, think Slag slag as far as possible, pull out criticism, today or to summarize about the Linux file system problem it ~
The use of Linux and user space program programming and file system has a close relationship, the concept of file system everyone should be some familiar, here I do not say, because said also and we have explained before, these concepts can understand is, we want to know casually can Baidu get. I'll start with the Linux virtual file system. The implementation of the file system differs depending on the system, one of the best features of Linux is that he supports many file systems, such as the structure of the file system:

The VFS (virtual file system) relies on data structures to preserve its general representation of a file system, where the data structure is listed as follows:

    • Super Block structure: Store information about the installed file system;
    • Index node Structure: Store information about the file;
    • File structure: Holds information about files that are opened by the process;
    • Directory Entry Structure: holds information about the path name and the file that the pathname points to.

The Linux kernel uses global variables to hold pointers to structures previously mentioned, and all structures are saved with a doubly linked list, and the kernel holds pointers to the list header, and it is used as the access point for the linked list, which uses the List_head type field to point to the previous element in the list. The following table is the global variables that the kernel holds and the list types that these variables point to (the global variables associated with the VFS)

Global variables Structure type
Super_blocks Super_block
File_systems File_systems_type
Dentry_unused Dentry
Vfsmntlist Vfsmount
Inode_in_use Inode
Inode_unused Inode

Super_block, File_system_type, dentry, and vfsmoubt structures are stored in their own linked lists, and the index nodes can find themselves on the global Inode_in_use or on the inode_unused. Or they can find themselves on the super fast local linked list.

In addition to the main VFS structure, there are several other structures that interact with the VFS, Fs_struct and Files_struct,namespace,fd_set, which tell how the process descriptor is associated with a file-related structure.

First to introduce the FS_STRUCT structure, fs_struct structure can be referenced by a number of process descriptors, the following code in Include/linux/fs_struct.h can be found Oh, the code explanation is not good please God teach

struct  fs_struct{    atomic_t count; Save the number    of process descriptors that reference a specific fs_struct lock;     int  umask;  Save a mask that    represents the permissions that will be set on the open file struct dentry * root, *pwd, *altroot;  All are pointers,,,,    struct vfsmount * rootmnt, *PWDMNT,  *altrootmnt; Pointer,};

Files_struct contains information about opening a file and its descriptors, which use these collections to group its descriptors. The following code can be found on include/linux/file.h

structfiles_struct{atomic_t Count;    Similar to fs_struct spinlock_t File_lock; intMax_fds; Represents the maximum number of files that a process can openintMax_fdset; Represents the maximum number of descriptorsintnext_fd; Save the next value of the file descriptor that will be assignedstructFILE * *FD; An FD array that points to an array of open file objects Fd_set*close_on_exec;//is a pointer to a set of file descriptors that will be closed by the flag bit at exec (), if the number of file descriptors "open" at exec () is more than close_on_exec_ The size of the Init field, the value of the Close_on_exec field is changed; Fd_set*Open_fds;//is a pointer to a collection of file descriptors labeled "Open", Fd_set close_on_exec_init;    Saves a bit field that represents the file descriptor for the open file Fd_set open_fds_init; These are fd_set types of domain, in fact, do not understand,,,structFile *the Fd_array[nr_open_default];//fd_array array pointer points to the first 32 open file Description methods};

Initialize the FS_STRUCT structure with Init_files macros:

#defineInit_files \{. Count= Atomic_init (1),. File_lock=spin_lock_unlocked,. Max_fds=Nr_open_default,. Max_fdset=__fd_setsize,. NEXT_FD=0,. FD= &init_files.fd_array[0]; . close_on_exec= &init_files.close_on_exec_init,. Open_fds= &init_files.open_fds_init,. Close_on_exec_init= {{0,}},. open_fda_init= {{0,}},. Fd_array={NULL,}}

The global definition of Nr_open_default is set to Bits_per_long,bits_per_long in 32-bit systems and is 64 in 64-bit systems.

Here's a look at page buffering, and let's see how it works and implements it. In Linux, memory is partitioned, each linked list with active pages and inactive linked lists, when the page is inactive, is written back to disk, indicating the above relationship:

The core of the page buffer is the Address_space object, and its code can be viewed in include/linux/fs.h ( This code is not very understanding, ask the great God advice ):

structaddress_space{structInode *host; structRadix_tree_root Page_tree;    spinlock_t Tree_lock; unsignedLongnrpages;    pgoff_t writeback; structAddress_space_operations *A_ops; structPrio_tree_root I_map;    unsigned INR i_map_lock; structList_head i_mmap_nonlinear;    spinlock_t I_mmap_lock;    atomic_t Truncate_count; unsignedLongflags; structBacking_dev_info *Backing_dev_info;    spinlock_t Private_lock; structList_head private_list; structAddress_space *assoc_mapping;};

The Linux kernel also represents each sector on a block device as a buffer_head structure, and the physical area applied to the BUFFER_HEAD structure is the logical block B_BLOCKNR of the device B_dev, and the referenced physical memory is the one that starts at the block size b_size bytes b_ Data memory block, the memory block in the physical page b_page, its structure such as:

In the end, the VFS system calls and the file system layer, and tracking their execution until the kernel level, we have to understand four functions: open (), close (), read (), write ().

Open () function:

The open function is used for opening and creating files. The following is a simple description of the Open function

#include <fcntl.h>int open (constcharint oflag, ...);

Return value: Success returns the file descriptor, otherwise returns-1

For an open function, the third argument (...) is used only when creating a new file, which specifies the access bit (access permission bits) for the file. Pathname is the pathname of the file to open/create (such as C:/cpp/a.cpp), Oflag is used to specify the open/create mode of the file, which can be logically or constituted by the following constants (defined by Fcntl.h).

    • O_rdonly read-only mode
    • O_wronly Write-only mode
    • O_RDWR Read/write mode

When opening/creating a file, use at least one of the three constants above . The following constants are selected:

    • O_append each write operation to the end of the file
    • O_creat If the specified file does not exist, the file is created
    • O_EXCL returns 1 if the file to be created already exists, and modifies the value of errno
    • O_trunc if the file exists and opens in write/read-only mode, the entire contents of the file are emptied
    • O_noctty if the path name is pointing to the end device, do not use it as a control terminal.
    • O_nonblock if the path name points to a fifo/block file/character file, the open and subsequent I/O of the file are set to nonblocking mode (nonblocking modes)

The following three constants are also selected for synchronous input and output

    • O_dsync wait for physical I/O to finish before write. Does not wait for the file property to be updated without affecting the reading of the newly written data.
    • O_rsync read waits for all write operations to be written to the same region to complete before
    • O_sync wait for physical I/O to finish before write, including I/O to update file properties

The file descriptor returned by open must be the smallest descriptor that is not used.

If Name_max (the maximum length of the file name, excluding ' \ S ') is 14, and we want to create a file with a filename longer than 14 bytes in the current directory, the earlier system V systems (such as SVR2) truncate the out-of-section, preserving only the first 14 bytes, and BSD-derived (bsd-de rived) The system returns an error message and errno is set to Enametoolong.

posix.1 introduces constant _posix_no_trunc to determine whether to truncate long file names/long path names. If _posix_no_trunc is set to prohibit truncation and the path name is longer than Path_max (including ' \ "), or if any filename that makes up the pathname exceeds Name_max, an error message is returned, and the errno to Enametoolong.

Close () function

 When the process finishes using the file, it issues a close () system call:

Sysopsis

#include <uniste.h>int close (int fd);

Parameter: FD file descriptor

function return value: 0 successful, 1 error

The parameter fd is the file descriptor to be closed. It should be stated that:When a process terminates, the kernel calls close for all file descriptors that have not yet been closed for the process, so even if the user program does not call close, the kernel will automatically close any files it opens at the time of termination. However, for a running program (such as a Web server), open file descriptors must remember to close, or as more open files, will occupy a large number of file descriptors and system resources.

Read () function

When a user-level program calls the Read () function, Linux converts it into a system call Sys_read ():

Function Description: Reads data from a file.
Required header files: #include <unistd.h>

Function prototypes:ssize_t read(int fd, void *buf, size_t count);

Parameters:

    • FD: The file descriptor that will read the data.
    • buf: Refers to the buffer, that is, the read data will be placed in this buffer.
    • Count: Represents the number of characters that should be read when a read operation is called.

Return value: Returns the number of bytes read, 0 (read to EOF), 1 (Error).

The following conditions cause the number of bytes read to be less than count:

    • When reading a normal file, it is not enough to read the end of the file count bytes. Example: If the file is only 30 bytes, and we want to read 100, bytes, then the actual read only 30 bytes, the function returns 30. Using the Read function at this time will cause read to return 0

    • When reading from an end device (terminal device), only one line is normally read at a time .
    • When reading from the network, the network cache may cause the number of bytes read to be less than the count bytes.
    • When reading a pipe or FIFO, the number of bytes in the pipe or FIFO may be less than count.
    • When reading from a record-oriented (record-oriented) device, some record-oriented devices, such as tapes, can return a maximum of one record at a time.
    • The signal is interrupted when part of the data is read, and the read operation starts with the CFO. Before the successful return, the CFO increments to the actual number of bytes read.

The routine is as follows (the program is an example of online search, pasted down for everyone to understand )::

1#include <stdio.h>2#include <io.h>3#include <alloc.h>4#include <fcntl.h>5#include <process.h>6#include <sys\stat.h>7 intMainvoid)8 {9     void*buf;Ten     inthandle; One     intbytes; ABuf=malloc (Ten); -     /* - looksforafileinthecurrentdirectorynamedtest.$$ $andattempts the Toread10bytesfromit. Tousethisexampleyoushouldcreatethe - filetest.$$$ -     */ -Handle=open ("test.$$$", o_rdonly| o_binary,s_iwrite|s_iread); +     if(handle==-1) -     { +printf"erroropeningfile\n"); AExit1); at     } -Bytes=read (Handle,buf,Ten); -     if(bytes==-1) -     { -printf"readfailed.\n"); -Exit1); in     } -     Else  to     { +printf"read:%dbytesread.\n", bytes); -     } the Return0; *}

Write () function

Function Description: Writes data to a file.
Required header files: #include <unistd.h>

Function prototypes:ssize_t write (int fd, void *buf, size_t count);

Return value: Number of bytes written to the file (success);-1 (Error)

function: The Write function writes count byte data to filedes and the data source is BUF. The return value is always equal to count, otherwise it is an error. A common cause of error is that disk space is full or exceeds the file size limit. For normal files, the write operation starts with the CFO. If O_append is used when the file is opened, each write writes the data to the end of the file. After a successful write, the CFO increments to the actual number of bytes written.

The routine is as follows (the program is an example of online search, pasted down for everyone to understand ):

1#include <stdio.h>2#include <stdlib.h>3#include <fcntl.h>4#include <sys\stat.h>5#include <io.h>6#include <string.h>7 intMainvoid)8 {9 int*handle;Char string[ +];Ten intLength, Res;/*Create a file named "test.$$$" in the current directory and write a string to it. If "test.$$$" already exists, it'll be overwritten. */ One if(Handle = open ("test.$$$", O_wronly | O_creat | O_trunc, S_iread | S_iwrite)) = =-1) A { -printf"Error Opening file.\n"); -Exit1); the } -strcpystring,"Hello, world!\n."); -Length = strlen (string); - if(res = write (handle,string, length))! =length) + { -printf"Error Writing to the file.\n"); +Exit1); A } atprintf"wrote%d bytes to the file.\n", res); -Close (handle);return 0; }

 Summary

Today look at the code is not much, almost all online search for code, some of the explanation is also read the data written up, some still do not understand, I hope that the way the great God, here I summed up the Linux file system implementation of the problem, but the specific details are not mentioned, We should only have a general understanding of the most Linux file system, and the reader asked me what books I read, here I explain, read the Linux kernel programming, and have a deep understanding of the Linux kernel as well as the various materials on the Web or other good blog written by Daniel. Here I summed up a bit, and I do not understand and feel important to say a bit, I hope that the great God to give some advice, thanks~

All rights reserved, reprint please specify reprint address: http://www.cnblogs.com/lihuidashen/p/4246121.html

The fifth day of the 10-day learning Linux Kernel---questions about the Linux file system implementation

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.