_bmap ()
1. The _bmap () function is used to map a block of file data to the processing operation of the disk block.
Because an I node corresponds to a file, so the logical block number of the I node map above is the logical block number stored in the file data; i_zone[0] to i_zone[6] is a direct logical block number, i_zone[7] is an indirect logical block number, and I_zone[8 is a two-time indirect logic block number That the data in the file is stored on a logical block on which hard disk is mapped by this array, and it is possible to know the maximum amount of storage for a file.
Mapping the data blocks on the file to disk, Inode file I node, block file, create whether creating flag static int _bmap (struct M_inode * inode,int block,int Create) {s
Truct Buffer_head * BH;
int i;
Determine if the file block number blocks are out of range if (block<0) Panic ("_bmap:block<0");
if (block >= 7+512+512*512)//File logical blocks Range panic ("_bmap:block>big"); Use the direct block if (block<7) {if (create &&!inode->i_zone[block])//To create a flag position, the logical block field for the I node is 0 if (inode->i_zone
[Block]=new_block (Inode->i_dev)) {//Request a new disk logical block, return logical number inode->i_ctime=current_time;
inode->i_dirt=1;
Return inode->i_zone[block];//Returns the logical block number on the device//using an indirect block-= 7; if (block<512) {if (create &&!inode->i_zone[7])//indicates that the file is using an indirect block for the first time, a disk block is requested to hold the indirect block information if (inode->i_zone[7
]=new_block (Inode->i_dev)) {inode->i_dirt=1;
inode->i_ctime=current_time;
} if (!inode->i_zone[7])//indicates that the creation of an indirect block disk failed, or create is not set 1 return 0; if (!) (
BH = Bread (inode->i_dev,inode->i_zone[7]))//Read the information of the indirect block return 0; i = ((unsigned Short *) (bh->b_data) [block];//gets the position of the block on the indirect chunk to determine whether it is 0 if (create &&!i)//if the block position on the indirect chunk is 0,create place if (I=new_block (Inode->i_dev))
{//apply for a new logical chunk to block ((unsigned short *) (bh->b_data)) [Block]=i;
bh->b_dirt=1;
} brelse (BH);
return i;
//Use two secondary block-= 512; Two-time indirect block request Logic block if (create &&!inode->i_zone[8]) if (Inode->i_zone[8]=new_block (Inode->i_dev)) {//
Map to a class of logical block in Level two indirect block inode->i_dirt=1;
inode->i_ctime=current_time;
} if (!inode->i_zone[8]) return 0; Read Level two indirect block information if (!) (
Bh=bread (Inode->i_dev,inode->i_zone[8])) return 0; Gets the block two-level indirect chunk number one level block i = ((unsigned short *) bh->b_data) of the specified two-level indirect block [block>>9];//9-bit to the right to divide 512, to get the first level block number if (create &&!i)//If the level two block in the level two indirect block does not exist, apply a logical block number to the two block if (I=new_block (Inode->i_dev)) {//Get a logical block to hold the two-level indirect block number in the two-level indirect block (
unsigned short *) (bh->b_data) [block>>9]=i;//block>>9 = = block/512 to map a logical block for level two blocks bh->b_dirt=1;
} brelse (BH);
if (!i) return 0; if (!) (
Bh=bread (Inode->i_dev,i))//Read two-level indirect block map of the two block of cache block return 0; i = ((unsigned short *) bh->b_data) [block&511];//represents the first few array elements in level two blocks in level two indirect blocks if (create &&!i) if (i=new_block (Inode->i_dev))
{//apply for a logical block to hold the final data ((unsigned short *) (bh->b_data)) [two-level block in the file block&511]=i;//map bh->b_dirt=1;
} brelse (BH); Return i;//back logical block number}
input ()
2. The Iput () function is to decrement the reference of the I node and, if the I node reference is 1, decrements the Delete I node and sets the related property; if it is a pipe file or a block device file, it is otherwise processed;
Place an I node minus 1 I-node references void iput (struct M_inode * inode) {if (!inode) return;
Wait_on_inode (Inode);
if (!inode->i_count)//If I node is already 0, then the Panic panic ("iput:trying to free Free inode"); if (inode->i_pipe) {//If it is a pipe file wake_up (&inode->i_wait);//Wake up waiting for the pipeline process if (--inode->i_count)//reference minus 1 return
;//If it is also referenced by another program, return it directly, otherwise set some properties and free memory free_page (inode->i_size);//Release the memory page used by the pipeline inode->i_count=0;//the I-Node property field setting
inode->i_dirt=0;
inode->i_pipe=0;
Return
The//i node corresponds to a device number of 0 and returns after the reference is decremented; for example, the pipe Operation I node if (!inode->i_dev) {inode->i_count--;
Return //If it is the I node of the block device file, refresh the device if (S_ISBLK (Inode->i_mode)) {Sync_dev (inode->i_zone[0));//zone[0] is the device number Wait_on_inode (in
ODE);
} repeat:if (inode->i_count>1) {//reference decrement return inode->i_count--;
Return
The IF (!inode->i_nlinks) {//link number is 0, indicating that the file has been deleted, the file length is 0, the release I node truncate (inode);
Free_inode (Inode);
Return } if (Inode->i_dirt) {//Write_inode (Inode) has been changed;/* We can sleep-so do again *///writes I node information to cacheMedium Wait_on_inode (inode);
Goto repeat;//After sleep, to confirm again} inode->i_count--;//returns, the file also exists return;
}
Get_empty_inode ()3, the Get_empty_inode (void) function means to look for an idle I node in an array of I nodes, set it, and then return the I node;
//obtains an idle I node entry from the I node table struct M_inode * Get_empty_inode (void) {struct M_inode * inode;
static struct M_inode * Last_inode = inode_table;
int i;
do {inode = NULL; for (i = Nr_inode i; i--) {if (++last_inode >= inode_table + nr_inode)//If Last_inode has arrived at the last entry, rescan Last_inode
= inode_table;
if (!last_inode->i_count) {//reference is 0, inode = last_inode;
if (!inode->i_dirt &&!inode->i_lock)/No modification, without locking, select this I node break; }//No I node is found, print I list for debugging, crash if (!inode) {for (i=0; I<nr_inode i++) PRINTK ("%04x:%6d\t", inode_tabl
E[i].i_dev, Inode_table[i].i_num);
Panic ("No free inodes in mem");
}//Check if locked Wait_on_inode (inode);
If the I node information is modified, then the refresh waits for I node to unlock while (Inode->i_dirt) {write_inode (inode);
Wait_on_inode (Inode);
} while (inode->i_count);//If I node is used by another process, then find an I node//The free I node details clear zero, set the reference, return I node pointer memset (inode,0,sizeof (*inode));
Inode->i_count = 1;
return inode; }
iget ()
4. The iget (int dev, int nr) function obtains the I node information according to the device number and the I node number; One of the key points is whether the I node is an installation node of a file system. If so, the I node is freed of a reference and the I node (that is, the root node) is found again in the filesystem.
Reads the I/L node information/parameter dev device number from the device on the specified I node number, nr I-node number//1, scan in the I-node list in memory, if found, return I-node pointer//2, if no above, then read the I-node information of the specified I node from the device into the Memory I node table
, returns the I node pointer struct m_inode * iget (int dev,int nr) {struct M_inode * inode, * empty;
if (!dev) Panic ("Iget with dev==0"); empty = Get_empty_inode ()//Get an idle i node Inode = inode_table;//i Node list array while (Inode < nr_inode+inode_table) {if Ode->i_dev!= Dev | |
Inode->i_num!= nr) {//device number or I node number is not equal, then look at the next inode++;
Continue
/unlock, and then confirm that the device number and I node number changed the Wait_on_inode (Inode);
if (inode->i_dev!= dev | | inode->i_num!= NR) {inode = inode_table;
Continue
inode->i_count++;//Reference//If the I node found is the installation node of the other file system if (inode->i_mount) {int i;
for (i = 0; I<nr_super i++) if (super_block[i].s_imount==inode)//See which File System installation node break;
If the Super block installed on this I node is not found, the free I node of the request is released if (I >= nr_super) {PRINTK ("mounted inode hasn ' t got sb\n");
if (empty) iput (empty);/Free I node return inode; //Find the I node installed superblock, obtain the device number of the file system, get NR to root node 1, re-find the root i node Iput (inode) in the file system;
dev = Super_block[i].s_dev;
NR = Root_ino;
Inode = inode_table;
Continue
//If the I node found is not, the other file system installation node,//Then free the empty node, return I node if (empty) iput (empty);
return inode;
//If the specified I node is not found in the I-node list, create a new if (!empty) return (NULL);
Inode=empty;
Inode->i_dev = Dev;
Inode->i_num = nr;
Read_inode (inode);//Read the I-node return inode from the device; }
Read_inode ()
5, read the device on the specified I node information to the cache, it is clear that the I node in the parameter is used in memory I node, and after the program is read to the hard disk of the I node, this should be from the hard disk in the I node to load its information to the memory of the I node, that is, Update I node information ; So read the I node information (read the I node information from the hard disk to the cache, and update the I node used from the hard disk to the memory use I node)
Reads the specified I node information from the device to the cache
static void Read_inode (struct m_inode * inode)
{
struct super_block * SB;
struct buffer_head * BH;
int block;
Lock_inode (inode);
if (!) ( Sb=get_super (Inode->i_dev))//access to Super Block
panic ("trying to read inode without dev") according to the device number;
The following is the compute I node logic number, the boot block Super block Two bitmaps then is (I node number/each piece has the number of I nodes) block
= 2 + sb->s_imap_blocks + sb->s_zmap_blocks +< c12/> (inode->i_num-1)/inodes_per_block;
Get the I node information from disk to
if (!) ( Bh=bread (Inode->i_dev,block))
panic ("Unable to read I-node block");
* (struct D_inode *) Inode =
((struct d_inode *) bh->b_data)
[(inode->i_num-1)%inodes_per_block];// This is from the hard disk on the I node to obtain data, update memory I node content
brelse (BH);
Unlock_inode (inode);
}
Write_inode ()6, the specified I node information to the disk, and the above Read_inode () function is just the opposite, the function is written to the use of the I node in memory on the hard disk used by the I node, the memory of the modified I node information to use the I node information on the hard disk;
//writes I node information to the buffer, the static void Write_inode (struct m_inode * inode)//parameter is the I-node structure used in memory {struct Super_block * SB
;
struct Buffer_head * BH;
int block;
Lock_inode (Inode);
if (!inode->i_dirt | |!inode->i_dev) {unlock_inode (inode);
Return } if (! (
Sb=get_super (Inode->i_dev)) Panic ("trying to write inode without device"); Block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks + (inode->i_num-1)/inodes_per_block;//Find the I node position on the disk logical blocks according to the I node number I F (!) (
Bh=bread (Inode->i_dev,block))//Read the I-node disk blocks to the buffer panic ("Unable to read I-node block"); ((struct D_inode *) bh->b_data)//Convert the buffer to disk using the I-node structure [(INODE->I_NUM-1)%inodes_per_block] =//According to the I-node number,
The remainder gets the first few positions on the disk for the I node * (struct D_inode *) inode;//from the Memory I node to the disk I node structure, because the disk I node structure and memory I node structure are the same as the first few bh->b_dirt=1;
inode->i_dirt=0;
Brelse (BH);
Unlock_inode (Inode); }
In fact, the above read-write I-node information, only in the subsequent conversion sequence is not the same. is a d_inode between the m_inode and the structural bodies, because the first 7 items in the two structures are the same, that is, the preceding 7 items can be shared, can be changed, and the M_INODE structure is not in the following D_inode structures (this is actually the uniqueness of the I node). , so there is no synchronization or not.
Read I node order is: * (struct D_inode *) Inode = ((struct D_inode *) bh->b_data) [(inode->i_num-1)%inodes_per_block]; Reading the I node information to the memory I node structure from the buffer of the hard disk map;
Write I node Order is: ((struct d_inode *) bh->b_data) [(inode->i_num-1)%inodes_per_block] =* (struct d_inode *) inode; The I-node structure is written from memory to the I-node structure used in the buffer of the hard disk map (in fact, the I node used on the hard disk);
Reprint please indicate the author and original source, original address: http://blog.csdn.net/yuzhihui_no1/article/details/43951153
If there is no correct place, I hope everyone corrected and study together. Thank you..