Linux kernel Source-code scenario Analysis-System call Mknod

Source: Internet
Author: User
Tags goto

Ordinary files can be created with open or create, FIFO files can be created with pipe, Mknod is mainly used for the creation of device files.

In the kernel, Mknod is implemented by Sys_mknod, with the following code:

Asmlinkage Long Sys_mknod (const char * filename, int mode, dev_t dev)//For example filename for/tmp/server_socket,dev is the device number {int error = 0;char * tmp;struct dentry * dentry;struct nameidata nd;if (s_isdir (mode)) Return-eperm;tmp = getname (filename); if (Is_err (TMP)) return Ptr_err (TMP), if (Path_init (TMP, lookup_parent, &nd)//Find parent node, here is/tmp node error = Path_walk (tmp, &ND); if ( Error) Goto Out;dentry = lookup_create (&nd, 0);//Find/tmp/server_socket node, return the dentry structure of the node, but Dentry->d_ Inode = Nullerror = Ptr_err (Dentry), if (!is_err (dentry)) {switch (mode & s_ifmt) {case 0:case s_ifreg://plain File error = VFS _create (Nd.dentry->d_inode,dentry,mode); break;case s_ifchr:case s_ifblk:case s_ififo:case s_ifsock://character device, block device, Pipeline, Socket File error = Vfs_mknod (Nd.dentry->d_inode,mode,dev);//create inode structure of/tmp/server_socket node and associate to break in file system; Case S_ifdir:error =-eperm;break;default:error =-einval;} Dput (dentry);} Up (&nd.dentry->d_inode->i_sem);p ath_release (&nd); Out:putname (TMP); return error;}

Lookup_create, look for the/tmp/server_socket node, the code is as follows:

static struct Dentry *lookup_create (struct nameidata *nd, int is_dir) {struct Dentry *dentry;down (&nd->dentry- >D_INODE->I_SEM);d entry = Err_ptr (-eexist), if (nd->last_type! = last_norm) Goto Fail;dentry = Lookup_hash ( &nd->last, nd->dentry);//nd->last is Server_socketif (Is_err (dentry)) goto fail;if (!is_dir && nd- >last.name[nd->last.len] &&!dentry->d_inode) goto Enoent;return dentry;enoent:dput (dentry);d entry = Err_ptr (-enoent); Fail:return Dentry;}
struct dentry * Lookup_hash (struct qstr *name, struct dentry * base)//name for Server_socket,base as parent node/tmp dentry struct {struct dentry * dentry; struct Inode *inode;int err;inode = base->d_inode;//parent node/tmp i node err = permission (inode, may_exec);d entry = Err_ptr (err ); if (err) goto out;/* * See if the low-level filesystem might want * to use its own hash. */if (base->d_op && base->d_op->d_hash) {err = Base->d_op->d_hash (base, name);d entry = Err_ptr ( ERR); if (Err < 0) goto out;} Dentry = Cached_lookup (base, name, 0), if (!dentry) {struct Dentry *new = D_alloc (base, name);//den Creating/tmp/server_socket Node Try structure dentry = err_ptr (-enomem), if (!new) goto Out;lock_kernel ();d entry = Inode->i_op->lookup (Inode, new);// Dentry is Nullunlock_kernel (); if (!dentry) Dentry = new;//The new assignment you just created is assigned to Dentry, but Dentry->d_inode is nullelsedput (new);} Out:return Dentry;} 
Vfs_mknod, create the inode structure of the/tmp/server_socket node and associate it with the file system with the following code:

int Vfs_mknod (struct inode *dir, struct dentry *dentry, int mode, dev_t Dev)//dir is the inode structure of the/TMP parent node, Dentry is/tmp/server_ The dentry structure of the socket node {int error =-eperm;mode &= ~current->fs->umask;down (&dir->i_zombie); if (S_ISCHR ( mode) | | S_ISBLK (mode)) &&!capable (Cap_mknod))//Verify that the current process allows the creation of a device node, which is only used when the node to be created is the device node, goto exit_lock;error = May_ Create (dir, dentry), if (error) Goto Exit_lock;error =-eperm;if (!dir->i_op | |!dir->i_op->mknod) GOTO EXIT_LOCK ;D Quot_init (dir); Lock_kernel (); error = Dir->i_op->mknod (dir, dentry, mode, dev);//For EXT2, this function is ext2_ Mknodunlock_kernel (); Exit_lock:up (&dir->i_zombie); if (!error) inode_dir_notify (dir, dn_create); return error ;}

May_create, check whether the inode structure of the target node exists.

static inline int may_create (struct inode *dir, struct dentry *child) {if (Child->d_inode)//check D_inode for Nullreturn -eexist;if (Is_deaddir (dir)) Return-enoent;return Permission (Dir,may_write | MAY_EXEC);}

For Ext2,dir->i_op->mknod is Ext2_mknod, the code is as follows:

static int Ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev) {struct Inode * inode = Ext2_new_inode (dir, mod e);//assigned an inode struct int err = Ptr_err (inode); if (Is_err (inode)) return err;inode->i_uid = Current->fsuid;init_ Special_inode (inode, mode, rdev); err = Ext2_add_entry (dir, Dentry->d_name.name, Dentry->d_name.len, inode);//i node is associated to the file system, that is, through the parent inode structure, to find the inode structure of the newly created child node if (err) goto Out_no_entry;mark_inode_dirty (inode);// The newly created INODE structure is set to "dirty" d_instantiate (Dentry, inode);//The newly created INODE structure is associated with the dentry structure return 0;out_no_entry:inode->i_ Nlink--;mark_inode_dirty (inode); Iput (inode); return err;} 
void Init_special_inode (struct inode *inode, umode_t mode, int rdev) {Inode->i_mode = Mode;if (S_ISCHR (mode)) {//character device in Ode->i_fop = &def_chr_fops;inode->i_rdev = to_kdev_t (Rdev);} else if (s_isblk (mode)) {//block device Inode->i_fop = &def_blk_fops;inode->i_rdev = to_kdev_t (Rdev); Inode->i_bdev = Bdget (Rdev);} else if (S_isfifo (mode))//fifo device Inode->i_fop = &def_fifo_fops;else if (s_issock (mode))//socket device Inode->i_ FOP = &BAD_SOCK_FOPS;ELSEPRINTK (kern_debug "Init_special_inode:bogus imode (%o) \ n", mode);}
Since the newly created INODE structure is set to "dirty", the kernel writes the contents of the INODE structure to the index node allocated to the file on disk, the Ext2_inode data structure, in "synchronizing" the inode structure in memory with the index node on disk. Because there is no such ingredient in the ext2_inode structure, and the device file does not need to use the i_block[] array, the I_rdev is misappropriated to save the device number. To understand this, look primarily at a fragment in the Ext2_update_inode code:

if (S_ISCHR (inode->i_mode) | | S_ISBLK (inode->i_mode))//FIFO device and socket device no device number raw_inode->i_block[0] = cpu_to_le32 (KDEV_T_TO_NR (inode->i_ Rdev)); else for (block = 0; block < ext2_n_blocks; block++) Raw_inode->i_block[block] = inode->u.ext2_i.i_data[ Block];


Conversely, when an index node is read from disk through Ext2_read_inode and the corresponding inode structure is created in memory, the i_block[] array is copied all to the i_data[] array. If the device file is called Init_special_inode the contents of i_block[0] are filled into the i_rdev of the inode structure. Here are the fragments:

for (block = 0; block < ext2_n_blocks; block++) Inode->u.ext2_i.i_data[block] = raw_inode->i_block[block];if ( Inode->i_ino = = Ext2_acl_idx_ino | |    Inode->i_ino = = Ext2_acl_data_ino)/* Nothing to do * *, else if (S_isreg (Inode->i_mode)) {} else if (S_isdir (INODE-&G T;i_mode)) {} else if (S_islnk (Inode->i_mode)) {} else Init_special_inode (Inode, Inode->i_mode,   le32_to_cpu ( Raw_inode->i_block[0]));

We go back to think, in the Linux kernel source code scenario analysis-File system installation,/DEV/SDB1, is established through the Mknod.

Also in the Linux kernel source code scenario analysis-socket-based interprocess communication,/tmp/server_socket, is also created through Vfs_mknod.

Linux kernel Source-code scenario Analysis-System call Mknod

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.