Establish a named pipe, Mknod mypipe p. The named pipe exists on the hard disk, and the pipeline is not.
Open this named pipe through open, implemented through Sys_open () in the kernel, and filename is "***/mypipe ".
For the relevant section, refer to the Linux kernel source scenario analysis-File open.
Sys_open enters Filp_open, then calls a function Path_walk () in Open_namei, and finds the inode representing the file in the file system based on the path name of the file. When the inode on the disk is read into memory, the I_OP and I_fop pointers in the inode are set to point to the corresponding inode_operations data structures and file_ based on the type of the file (the S_IFIFO flag bit of the FIFO file is 1). Operations data structures, but for special files such as FIFO, call Init_special_inode () to initialize them. This code is in Ext2_read_inode (), as follows:
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)) {inode->i_op = &ext2_ File_inode_operations;inode->i_fop = &ext2_file_operations;inode->i_mapping->a_ops = &ext2_aops;} else if (S_isdir (Inode->i_mode)) {inode->i_op = &ext2_dir_inode_operations;inode->i_fop = &ext2_dir_ Operations;} else if (S_islnk (Inode->i_mode)) {if (!inode->i_blocks) Inode->i_op = &ext2_fast_symlink_inode_ operations;else {inode->i_op = &page_symlink_inode_operations;inode->i_mapping->a_ops = &ext2_aops ;}} else Init_special_inode (Inode, Inode->i_mode, le32_to_cpu (raw_inode->i_block[0]));
As long as the file type is not an ACL index live data, not a normal file, not a directory, not a symbolic connection, belongs to a special file, it is necessary to initialize its inode structure by Init_special_inode ():
Sys_open () >filp_open () >open_namei () >path_walk () >real_lookup () >ext2_lookup () >iget () >get_ New_inode () >ext2_read_inode () >init_special_inode ()
void Init_special_inode (struct inode *inode, umode_t mode, int rdev) {Inode->i_mode = Mode;if (S_ISCHR (mode)) {INODE-&G T;i_fop = &def_chr_fops;inode->i_rdev = to_kdev_t (Rdev);} else if (s_isblk (mode)) {Inode->i_fop = &def_blk_fops;inode->i_rdev = to_kdev_t (Rdev); Inode->i_bdev = Bdget (Rdev);} else if (S_isfifo (mode)) Inode->i_fop = &def_fifo_fops;else if (s_issock (mode)) Inode->i_fop = &bad_sock_ FOPS;ELSEPRINTK (kern_debug "Init_special_inode:bogus imode (%o) \ n", mode);}
Obviously, for a FIFO file, the inode_operations structure pointer in its inode structure is i_op to 0, and the file_operations structure pointer i_fop points to def_fifo_fops, as defined below:
struct File_operations def_fifo_fops = {open:fifo_open,/* would set read or write Pipe_fops */};
Compared with the inode structure of piping pipe file, it can be seen that the inode structure in pipe file has not gone through such a process, and init_special_inode () is not related. This is because the inode structure of the pipe file is not read from disk by Ext2_read_inode (), but is generated temporarily (and thus nameless, invisible).
The file_operations structure pointer in the inode structure is then copied to the file data structure in Dentry_open. Thus, for a named pipe, when the file is opened through the data structure def_fifo_fops, you can get the function pointer Fifo_open, thus entering the function Fifo_open (), the code is as follows:
F->f_op = Fops_get (INODE->I_FOP);//f->f_op is assigned Inode_i_fop if (INODE->I_SB) file_move (F, & Inode->i_sb->s_files),//The file structure queue S_files if (f->f_op && f) in the super_block structure of the device to which it is being removed from the intermediate queue >f_op->open) { error = F->f_op->open (inode,f); if (error) goto Cleanup_all;
F->f_op->open (inode,f) corresponds to Fifo_open, the code is as follows:
static int Fifo_open (struct inode *inode, struct file *filp) {int ret;ret =-erestartsys;lock_kernel (); if (Down_interrupti BLE (Pipe_sem (*inode))) Goto Err_nolock_nocleanup;if (!inode->i_pipe) {ret =-enomem;if (!pipe_new (inode))// When the process of opening this FIFO file first comes to Fifo_open, the buffer page of the pipeline has not been allocated, so the required pipe_inode_info data structures and buffer pages are allocated through Pipe_new, The process of opening the same FIFO file later skips this section of Goto Err_nocleanup;} Filp->f_version = 0;switch (filp->f_mode) {case 1://read/* * o_rdonly * posix.1 says that o_nonblock means return WI Th the FIFO * opened, even when there is no process writing the FIFO. */filp->f_op = &read_fifo_fops;//and write end are different pipe_rcounter (*inode) ++;//(inode). I_pipe->r_counter++if (PIPE_ READERS (*inode) + = = 0)//(Inode). I_pipe->readers++wake_up_partner (inode);//If the write end is open, the opening of the read end completes the process of establishing the named pipe. In this case the write-side process, which is the "producer" process, is generally sleeping, waiting for the naming pipeline to be completed, so wake it up if (!). Pipe_writers (*inode)) {//(Inode). I_pipe->writerif ((Filp->f_flags & O_nonblock)) {/* suppress pollhup until We have * seen a writer */filp->f_version = Pipe_wcoUNTER (*inode);} else {Wait_for_partner (inode, &pipe_wcounter (*inode));//If the write end of the named pipe is not already open, the read-side opening is only half the process of naming the pipe, so the "consumer" process is going through wait _for_partner () goes to sleep, waits for a "producer" process to open the write end of the named pipe to complete its build process if (signal_pending (current)) goto ERR_RD;} Break;case 2://Write End/* * o_wronly * posix.1 says that o_nonblock means return-1 with * Errno=enxio when there is no proce SS Reading the FIFO. */ret =-enxio;if (Filp->f_flags & o_nonblock) &&! Pipe_readers (*inode)) goto ERR;FILP->F_OP = &write_fifo_fops;//and read at different pipe_wcounter (*inode) ++;//(inode). I_ Pipe->w_counter++if (! Pipe_writers (*inode) +/(inode). I_pipe->writer++wake_up_partner (inode);//If the read end is already open, then the write end is opened to complete the process of establishing the named pipe. In this case, the read-side process, the "consumer" process, is generally sleeping, waiting for the naming pipeline to be completed, so wake it up if (!). Pipe_readers (*inode)) {//(Inode). I_pipe->readerwait_for_partner (Inode, &pipe_rcounter (*inode));// If the read end of the named pipe is not already open, the write end is only half as complete as the named pipe is built, so the "producer" process goes to sleep through Wait_for_partner (), waits for a "consumer" process to open the read end of the named pipe to complete its build process if (Signal_ Pending (current) goto ERR_WR;} Break;case 3:/* * O_RDWR* Posix.1 leaves the "undefined" when O_nonblock is set. * This implementation would never block on a o_rdwr open, since * the process can at least talk to itself. */filp->f_op = &rdwr_fifo_fops; Pipe_readers (*inode) + +; Pipe_writers (*inode) + +; Pipe_rcounter (*inode) + +; Pipe_wcounter (*inode) ++;if (pipe_readers (*inode) = = 1 | | Pipe_writers (*inode) = = 1) wake_up_partner (inode); break;default:ret =-einval;goto err;} /* ok! */up (Pipe_sem (*inode)); Unlock_kernel (); return 0;err_rd:if (!--pipe_readers (*inode)) wake_up_interruptible (PIPE_ WAIT (*inode)); ret =-erestartsys;goto err;err_wr:if (!--pipe_writers (*inode)) wake_up_interruptible (PIPE_WAIT (* Inode)); ret =-erestartsys;goto err;err:if (! Pipe_readers (*inode) &&! Pipe_writers (*inode)) {struct Pipe_inode_info *info = Inode->i_pipe;inode->i_pipe = Null;free_page ((unsigned Long) info->base); Kfree (info);} Err_nocleanup:up (Pipe_sem (*inode)); Err_nolock_nocleanup:unlock_kernel (); return ret;}
Linux kernel source Scenario analysis-interprocess communication-Named pipes