In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article introduces the relevant knowledge of "what is the principle of open based on linux". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
We all need to open before we manipulate a file. Let's take a look at how open performs roughly in a virtual file system. The specific process will not be analyzed. This paper mainly analyzes the implementation principle of virtual file system.
Asmlinkage int sys_open (const char * filename,int flags,int mode)
{
Char * tmp
Int error
Error = getname (filename, & tmp)
If (error)
Return error
Error = do_open (tmp,flags,mode)
Putname (tmp)
Return error
}
Here is the code for do_open.
/ / Open a file
Int do_open (const char * filename,int flags,int mode)
{
Struct inode * inode
Struct file * f
Int flag,error,fd
/ / find an available file descriptor
For (fd=0; fdfiles- > fd [fd])
Break
/ / No available one was found
If (fd > = NR_OPEN | | fd > = current- > rlimm [RLIMIT _ NOFILE] .rlim _ cur)
Return-EMFILE
/ / clear the close_on_exec tag bit
FD_CLR (fd,¤t- > files- > close_on_exec)
/ / get an available file structure
F = get_empty_filp ()
If (! F)
Return-ENFILE
/ / establish the mapping from fd to file structure
Current- > files- > fd [fd] = f
F-> f_flags = flag = flags
F-> f_mode = (flag+1) & O_ACCMODE
If (f-> f_mode)
Flag++
If (flag & (O_TRUNC | O_CREAT))
Flag | = 2
/ / find the inode node corresponding to the file and put it in the inode variable
Error = open_namei (filename,flag,mode,&inode,NULL)
If (! error & & (f-> f_mode & 2)) {
Error = get_write_access (inode)
If (error)
Iput (inode)
}
If (error) {
Current- > files- > fd [fd] = NULL
F.frankcountmuri-
Return error
}
/ / establish the mapping relationship between file structure and inode
F-> f_inode = inode
/ / initialize file offset
F-> f_pos = 0
F-> f_reada = 0
F-> f_op = NULL
/ / the function set of the file structure of the assignment operation
If (inode- > i_op)
F-> f_op = inode- > iComop-> default_file_ops
If (f-> f_op & & f-> flip-> open) {
/ / call the open function of the underlying file system
Error = f-> fopp-> open (inode,f)
If (error) {
If (f-> f_mode & 2) put_write_access (inode)
Iput (inode)
F.frankcountmuri-
Current- > files- > fd [fd] = NULL
Return error
}
}
F-> f_flags & = ~ (O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC)
Return (fd)
}
The main job is to find the inode node corresponding to the file through open_namei, and then execute the underlying open. Finally, the relationship from fd to file to inode is established. In the virtual file system, super block, inode, directory and file are all abstract concepts, and the specific operation functions are implemented by each file system. So we first find a structure, and then call the operation function of the specific file system according to the actual operation value.
So let's first look at open_namei, and then look at the specific open function.
The following is the core code of open_namei.
/ / find out the inode of the last level directory
Error = dir_namei (pathname,&namelen,&basename,base,&dir)
/ / find the inode corresponding to a file in the last level directory
Error = lookup (dir,basename,namelen,&inode)
The general idea is to find the inode of the last level directory first, and then look for a file in the last level directory. Let's see how to find the inode corresponding to the last level of directory.
/ / find out the inode corresponding to the last level directory in pathname
Static int dir_namei (const char * pathname, int * namelen, const char * name
Struct inode * base, struct inode * * res_inode)
{
Char c
Const char * thisname
Int len,error
Struct inode * inode
* res_inode = NULL
/ / if no base is passed, the search starts from the current working directory of the process
If (! base) {
Base = current- > fs- > pwd
Base- > iSuppli countdown +
}
/ / absolute path, start from the root directory
If ((c = * pathname) = ='/') {
Iput (base)
Base = current- > fs- > root
Pathname++
Base- > iSuppli countdown +
}
/ / find out the inode node corresponding to the last level directory of pathname
While (1) {
Thisname = pathname
/ / split the part of the path with /. If you encounter /, you will get a certain level of path name. Thisname points to the first address of the current path, and len represents the corresponding length of this part of the path.
For (len=0; (c = * (pathname++)) & & (c! ='/'); len++)
/ * nothing * /
/ / c is empty to indicate that the last character, that is, the end of the path, is not looking for the last file or directory.
If (! C)
Break
Base- > iSuppli countdown +
/ / find a file in the base directory
Error = lookup (base,thisname,len,&inode)
If (error) {
Iput (base)
Return error
}
/ / set base to inode, and keep looking
Error = follow_link (base,inode,0,0,&base)
If (error)
Return error
}
If (! base- > i_op | |! base- > iPrep-> lookup) {
Iput (base)
Return-ENOTDIR
}
* name = thisname
* namelen = len
* res_inode = base
Return 0
}
It is by splitting the string with /, under the starting directory, that is, the root directory or the given directory. Find the inode of the next level directory and iterate over and over again to find the inode of the last level directory. We found that the lookup function is used to find the inode of the last level directory and the inode of a file in a certain directory. Let's take a look at his realization. Core code.
Return dir- > iPop-> lookup (dir,name,len,result)
Take the ext file system as an example. Look at the implementation of lookup.
Int ext_lookup (struct inode * dir,const char * name, int len)
Struct inode * * result)
{
Int ino
Struct ext_dir_entry * de
Struct buffer_head * bh
* result = NULL
If (! dir)
Return-ENOENT
If (! S_ISDIR (dir- > i_mode)) {
Iput (dir)
Return-ENOENT
}
If (! (bh = ext_find_entry (dir,name,len,&de,NULL,NULL) {
Iput (dir)
Return-ENOENT
}
Ino = de- > inode
Brelse (bh)
If (! (* result = iget (dir- > iSupplsbPhonino)) {
Iput (dir)
Return-EACCES
}
Iput (dir)
Return 0
}
Static struct buffer_head * ext_find_entry (struct inode * dir
Const char * name, int namelen, struct ext_dir_entry * * res_dir
Struct ext_dir_entry * * prev_dir, struct ext_dir_entry * * next_dir)
{
Long offset
Struct buffer_head * bh
Struct ext_dir_entry * de
* res_dir = NULL
If (! dir)
Return NULL
# ifdef NO_TRUNCATE
If (namelen > EXT_NAME_LEN)
Return NULL
# else
If (namelen > EXT_NAME_LEN)
Namelen = EXT_NAME_LEN
# endif
/ / read the file contents of the directory, and then compare
Bh = ext_bread (dir,0,0)
If (! bh)
Return NULL
If (prev_dir)
* prev_dir = NULL
If (next_dir)
* next_dir = NULL
Offset = 0
De = (struct ext_dir_entry *) bh- > b_data
While (offset
< dir->I_size) {
If ((char *) de > = BLOCK_SIZE+bh- > b_data) {
Brelse (bh)
Bh = NULL
Bh = ext_bread (dir,offset > > BLOCK_SIZE_BITS,0)
If (! bh)
Continue
De = (struct ext_dir_entry *) bh- > b_data
If (prev_dir)
* prev_dir = NULL
}
If (de- > rec_len)
< 8 || de->Rec_len% 8! = 0 | |
De- > rec_len
< de->Name_len + 8 | |
(char *) de) + de- > rec_len-1 > = BLOCK_SIZE+bh- > b_data) {
Printk ("ext_find_entry: bad dir entry\ n")
Printk ("dev=%d, dir=%ld, offset=%ld, rec_len=%d, name_len=%d\ n"
Dir- > i_dev, dir- > i_ino, offset, de- > rec_len, de- > name_len)
De = (struct ext_dir_entry *) (bh- > b_data+BLOCK_SIZE)
Offset = (offset / BLOCK_SIZE) + 1) * BLOCK_SIZE
Continue
/ * brelse (bh)
Return NULL; * /
}
/ / whether the desired file has been found
If (ext_match (namelen,name,de)) {
* res_dir = de
If (next_dir)
If (offset + de- > rec_len)
< dir->I_size & &
((char *) de) + de- > rec_len
< BLOCK_SIZE+bh->B_data)
* next_dir = (struct ext_dir_entry *)
((char *) de + de- > rec_len)
Else
* next_dir = NULL
Return bh
}
Offset + = de- > rec_len
If (prev_dir)
* prev_dir = de
De = (struct ext_dir_entry *) ((char *) de + de- > rec_len)
}
Brelse (bh)
Return NULL
}
More code, you don't need to study, mainly to read the contents of the directory from the hard disk, and then traverse whether each file name is consistent with what you are looking for.
Through the above analysis, we have found a file corresponding to the inode node. The general file system does not implement the open function. So just return inode and establish a relationship from fd to file to inode. The subsequent operation on the file is also done through the set of operation functions of the inode node.
This is the end of the content of "what is the principle of open based on linux". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.