Linux Kernel Source Analysis-File system (V, inode.c) __linux

Source: Internet
Author: User


_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..


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.