Linux kernel source scenario analysis-Access after file system installation

Source: Internet
Author: User
Tags goto

In the Linux kernel source scenario analysis-File system installation, in the article, sudo mount-t ext2/dev/sdb1/mnt/sdb has been called, and the file system is mounted on the/MNT/SDB node, then we then visit/mnt/sdb/ The HELLO.C node. Let's see what's the difference between Path_walk's execution?

int Path_walk (const char * name, struct nameidata *nd) {struct dentry *dentry;struct inode *inode;int err;unsigned int look Up_flags = Nd->flags;while (*name== '/') name++;if (!*name) goto Return_base;inode = Nd->dentry->d_inode;if ( Current->link_count) Lookup_flags = lookup_follow;/* at the "We know we have a real path component. */for (;;) {unsigned long hash;struct qstr this;unsigned int c;err = permission (inode, may_exec);d entry = Err_ptr (err); if (err) break ; this.name = name;c = * (const unsigned char *) Name;hash = Init_name_hash ();d o {name++;hash = Partial_name_hash (c, hash); c = * (const unsigned char *) name;} while (c && (c! = '/')); This.len = name-(const char *) This.name;this.hash = End_name_hash (hash);/* Remove Trail ing slashes? */if (!c) goto last_component;while (*++name = = '/'); if (!*name) goto last_with_slashes;/* * "." and ":" Is special-". Especially so because it have * to is able to know is about the current root directory and * parent relationships. */if (this.name[0] = = '. ') switch (this.len) {default:break;case 2:if (this.name[1]! = '. ') Break;follow_dotdot (nd); inode = nd->dentry->d_inode;/* fallthrough */case 1:continue;} /* * See if the low-level filesystem might want * to use its own hash. */if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {err = Nd->dentry->d_op->d_hash ( Nd->dentry, &this); if (Err < 0) break;} /* This does the actual lookups. */dentry = Cached_lookup (Nd->dentry, &this, lookup_continue); if (!dentry) {dentry = Real_lookup (Nd->dentry, & Amp;this, lookup_continue); err = Ptr_err (dentry); if (Is_err (dentry)) break;} /* Check mountpoints. */while (D_mountpoint (dentry) && __follow_down (&nd->mnt, &dentry)); err =-enoent;inode = dentry- >d_inode;if (!inode) goto out_dput;err =-enotdir; if (!inode->i_op) goto out_dput;if (inode->i_op->follow_link) {err = Do_follow_link (dentry, ND);dp ut (dentry); if (err) goto Return_err;err =-enoent;inode= Nd->dentry->d_inode;if (!inode) break;err =-enotdir; if (!inode->i_op) break;} else {dput (nd->dentry); nd->dentry = Dentry;} err =-enotdir; if (!inode->i_op->lookup) break;continue;/* here ends the main loop */last_with_slashes:lookup_flags |= LOOKUP_ Follow | Lookup_directory;last_component:if (Lookup_flags & lookup_parent) goto lookup_parent;if (this.name[0] = = '. ') Switch (this.len) {default:break;case 2:if (this.name[1]! = '. ') Break;follow_dotdot (nd); inode = nd->dentry->d_inode;/* Fallthrough */case 1:goto return_base;} if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {err = Nd->dentry->d_op->d_hash ( Nd->dentry, &this); if (Err < 0) break;}  Dentry = Cached_lookup (nd->dentry, &this, 0); if (!dentry) {dentry = Real_lookup (nd->dentry, &this, 0); err = Ptr_err (Dentry); if (Is_err (dentry)) break;} while (D_mountpoint (dentry) && __follow_down (&nd->mnt, &dentry))//After finding the/MNT/SDB node, will be executed here, is also different ; inOde = Dentry->d_inode;if ((lookup_flags & Lookup_follow) && inode && inode->i_op && I Node->i_op->follow_link) {err = Do_follow_link (dentry, ND);dp ut (dentry); if (err) goto Return_err;inode = nd-> Dentry->d_inode;} else {dput (nd->dentry); nd->dentry = Dentry;} Err =-enoent;if (!inode) goto no_inode;if (Lookup_flags & lookup_directory) {err =-enotdir; if (!inode->i_op | |!i node->i_op->lookup) break;} Goto Return_base;no_inode:err =-enoent;if (Lookup_flags & (lookup_positive| lookup_directory)) Break;goto return_base;lookup_parent:nd->last = This;nd->last_type = LAST_NORM;if (this.name [0]! = '. ') Goto return_base;if (This.len = = 1) Nd->last_type = Last_dot;else if (This.len = = 2 && this.name[1] = = '. ') Nd->last_type = Last_dotdot;return_base:return 0;out_dput:dput (dentry); Path_release (ND); Return_err:return err;}

D_mountpoint to see if it is a mount point.

static __inline__ int d_mountpoint (struct dentry *dentry) {return!list_empty (&DENTRY->D_VFSMNT);}
Remember in the Linux kernel source code scenario analysis-File system installation, in the article, the last add_vfsmnt.

List_add (&mnt->mnt_clash, &nd->dentry->d_vfsmnt);
So here is not NULL, return True, then execute __follow_down, the code is as follows:

static inline int __follow_down (struct vfsmount **mnt, struct dentry **dentry) {struct List_head *p;spin_lock (&dcache _lock);p = (*dentry)->d_vfsmnt.next;while (P! = & (*dentry)->d_vfsmnt) {//reference file system installation Add_vfsmntstruct Vfsmount *tmp;tmp = List_entry (p, struct vfsmount, mnt_clash); if (tmp->mnt_parent = = *mnt) {//reference file system installation Add_vfsmnt*mn t = mntget (TMP);//nd->mnt is the vfsmount structure of the installed device Spin_unlock (&dcache_lock); Mntput (tmp->mnt_parent);/* TMP holds The Mountpoint, so ... */dput (*dentry); *dentry = Dget (tmp->mnt_root);//dentry the dentry structure of the root node of the installed device return 1;} p = p->next;} Spin_unlock (&dcache_lock); return 0;}

There is also a knowledge point, that is, the middle node is dot or dotdot processing.

if (this.name[0] = = '. ') switch (this.len) {default:break;case 2:if (this.name[1]! = '. ') Break;follow_dotdot (nd); inode = nd->dentry->d_inode;/* Fallthrough */case 1:continue;
If it is dot, then continue to the next cycle. If it is Dotdot, it will call Follow_dotdot, the code is as follows:

static inline void Follow_dotdot (struct nameidata *nd) {while (1) {struct Vfsmount *parent;struct dentry *dentry;read_lock (&current->fs->lock); if (nd->dentry = = Current->fs->root && nd->mnt = = current->fs-& GT;ROOTMNT) {//The nd->dentry reached is the root node of this process and can no longer run up, so keep the Nd->dentry constant Read_unlock (&current->fs->lock ); break;} Read_unlock (&current->fs->lock); Spin_lock (&dcache_lock); if (nd->dentry! = Nd->mnt->mnt_ Root) {//reached nd->dentry dentry structure dentry = Dget (nd->dentry->d_parent); Spin_unlock (&dcache_lock); Dput (nd->dentry); nd->dentry = Dentry;//dentry structure goes up, the MNT structure is not changed;} parent=nd->mnt->mnt_parent;//Walk Here, it shows that Nd->dentry is already the dentry structure of the root node, can only run to another device, read the parent device's VFSMOUNT structure if (parent = = ND-&GT;MNT) {//If the VFSMOUNT structure of the parent device is the same as the vmfmount structure of this device, then no more spin_unlock (&dcache_lock) can be run on the parent device; Mntget (parent);//If the VFSMOUNT structure of the parent device is not the same as the vmfmount structure of the device dentry=dget (nd->mnt->mnt_mountpoint); Dentry is the dentry structure of the Mount node for the current device Spin_unlock (&AMp;dcache_lock);dp ut (nd->dentry), nd->dentry = Dentry;mntput (nd->mnt); nd->mnt = parent;//nd-> MNT is also assigned the VFSMOUNT structure of the Parent device}}

Linux kernel source scenario analysis-Access after file system installation

Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

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.