namei.c
1. Through nameI C continue to be familiar with the workflow and mode of file system inode dir_ Entry (file entry structure)
dir_ The entry structure has two elements
File name file inode number
2. By interpreting the actual process of the source code, we know the implementation method of directory operation, file operation and link operation
mkdir rmdir touch open read ln
3. Design method of code robustness
Operation permission of a file - inode node of the file - i_mode
dir_entry structure the entry structure of the file
We can think of it as a simplified i-node descriptor
One file corresponds to one inode node
Take another look at find_ What is the entry function
Function to find a file entry point in the current directory
Find dir of a file_ Enntry structure
Find the file entry point of the specified name parameter in the dir parameter directory, return the pointer entry point and return the cache, and find the cache of the name file.
add_entry
Add a file entry point with the specified name in the specified directory and use its res_dir returns the entry point and returns
static struct buffer_head * add_entry(struct m_inode * dir, const char * name, int namelen, struct dir_entry ** res_dir) { int block,i; struct buffer_head * bh; struct dir_entry * de; *res_dir = NULL; #ifdef NO_TRUNCATE if (namelen > NAME_LEN) return NULL; #else if (namelen > NAME_LEN) namelen = NAME_LEN; #endif //Name truncation if (!namelen) return NULL; //Logical block number of the storage directory file //What's in the file directory if (!(block = dir->i_zone[0])) return NULL; //Read the cache corresponding to BLOCK if (!(bh = bread(dir->i_dev,block))) return NULL; i = 0; //Dir is stored in the directory_ entry de = (struct dir_entry *) bh->b_data; while (1) { if ((char *)de >= BLOCK_SIZE+bh->b_data) { brelse(bh); bh = NULL; block = create_block(dir,i/DIR_ENTRIES_PER_BLOCK); if (!block) return NULL; if (!(bh = bread(dir->i_dev,block))) { i += DIR_ENTRIES_PER_BLOCK; continue; } de = (struct dir_entry *) bh->b_data; } if (i*sizeof(struct dir_entry) >= dir->i_size) { de->inode=0; dir->i_size = (i+1)*sizeof(struct dir_entry); dir->i_dirt = 1; dir->i_ctime = CURRENT_TIME; } if (!de->inode) { dir->i_mtime = CURRENT_TIME; for (i=0; i < NAME_LEN ; i++) de->name[i]=(i<namelen)?get_fs_byte(name+i):0; bh->b_dirt = 1; *res_dir = de; return bh; } de++; i++; } brelse(bh); return NULL; }
dir lookup for the specified directory
An empty file access point was found (the de - > inode of the dir_entry is 0)
The bh returned is the disk cache of the directory
static struct m_inode * get_dir(const char * pathname)
static struct m_inode * get_dir(const char * pathname) { char c; const char * thisname; struct m_inode * inode; struct buffer_head * bh; int namelen,inr,idev; struct dir_entry * de; //Current root file system in Beijing if (!current->root || !current->root->i_count) panic("No root inode"); //Working directory of the current process if (!current->pwd || !current->pwd->i_count) panic("No cwd inode"); if ((c=get_fs_byte(pathname))=='/') { inode = current->root; pathname++; } else if (c) inode = current->pwd; else return NULL; /* empty name is bad */ inode->i_count++; while (1) { thisname = pathname; if (!S_ISDIR(inode->i_mode) || !permission(inode,MAY_EXEC)) { iput(inode); return NULL; } for(namelen=0;(c=get_fs_byte(pathname++))&&(c!='/');namelen++) /* nothing */ ; if (!c) return inode; if (!(bh = find_entry(&inode,thisname,namelen,&de))) { iput(inode); return NULL; } inr = de->inode; idev = inode->i_dev; brelse(bh); iput(inode); if (!(inode = iget(idev,inr))) return NULL; } }
To manipulate a file, we first need to find its inode node
The inode node of the specified path can be found
For example, cd /work/work /, we need to find the inode node of the specified path first
static struct m_inode * dir_namei(const char * pathname,
int * namelen, const char ** name)
static struct m_inode * dir_namei(const char * pathname, int * namelen, const char ** name) { char c; const char * basename; struct m_inode * dir; if (!(dir = get_dir(pathname))) return NULL; basename = pathname; while (c=get_fs_byte(pathname++)) if (c=='/') basename=pathname; *namelen = pathname-basename-1; *name = basename; return dir; }
This is a supplement to the one above
Find the highest directory with the given path name, return its inode node, return the name length of the highest path, and return the name of the highest path
sys_unlink
sys_link rename the file
Create a linked file (hard link) for the file
When creating a linked file, explain what the linked file is
To link a file is to add a dir to an existing file_ entry
1. Find inode of existing file
2. Creates a new dir in the specified file path_ entry
3. Put the new dir_ The entry is mapped to the old inode.