Skip to the content.

pipe

先把基本理念搞清楚了

系统调用

pipe

vmsplice splice tee pipe

fs/splice.c 提供了三个系统调用

有趣的东西

https://mazzo.li/posts/fast-pipes.html

https://news.ycombinator.com/item?id=41348844 不知道为什么一天到晚都在分析 pipe

splice

splice() moves data between two file descriptors without copying between kernel address space and user address space. It transfers up to len bytes of data from the file descriptor fd_in to the file descriptor fd_out, where one of the file descriptors must refer to a pipe.

without splice, we can copy file by coping file to user space and coping data in userspace to kernel space. splice can copy file directly in kernel with pipe.

Because splice connect two fd (one of is pipe fd), so splice also works with tee. Tee can copy files without consuming it, in the second stage, we can splice the data to files.

pipe

If we get fd, then find inode, then standard path to pipefifo_fops::pipe_read

为什么 pipe 还需要一个 fs 啊

const struct file_operations pipefifo_fops = {
	.open		= fifo_open,
	.llseek		= no_llseek,
	.read_iter	= pipe_read,
	.write_iter	= pipe_write,
	.poll		= pipe_poll,
	.unlocked_ioctl	= pipe_ioctl,
	.release	= pipe_release,
	.fasync		= pipe_fasync,
};

为什么需要文件系统,因为 pipe2 会产生两个 fd ,这两个 fd 是可以 close / read / write ,所以必须重载 对应的各种行为,所以需要有 pipefifo_fops 。同时他们的 fd 也是需要关联 inode ,有 inode 就需要 fs 来管理这些 inode .

在 inode 中, struct pipe_inode_info::pipe_buffer points an array of pipe_buffer, every pipe_buffer manages one page frame.

有趣的 dentry_operations::d_dname

使用 fs/pipe2.c 下:

@[
    pipefs_dname+5
    proc_pid_readlink+218
    vfs_readlink+255
    do_readlinkat+270
    __x64_sys_readlink+30
    do_syscall_64+188
    entry_SYSCALL_64_after_hwframe+119
]: 8
🧀  ls -la fd
lrwx------ - martins3 24 Jan 22:48  0 -> /dev/pts/12
lrwx------ - martins3 24 Jan 22:48  1 -> /dev/pts/12
lrwx------ - martins3 24 Jan 22:48  2 -> /dev/pts/12
lr-x------ - martins3 24 Jan 22:48  3 -> pipe:[1443562]
l-wx------ - martins3 24 Jan 22:48  4 -> pipe:[1443562]
/*
 * pipefs_dname() is called from d_path().
 */
static char *pipefs_dname(struct dentry *dentry, char *buffer, int buflen)
{
	return dynamic_dname(buffer, buflen, "pipe:[%lu]",
				d_inode(dentry)->i_ino);
}

static const struct dentry_operations pipefs_dentry_operations = {
	.d_dname	= pipefs_dname,
};

除了展示,应该还有其他的作用吧

[ ] pipe_buf_operations

buffer ops: because some optimization, e.g., steal page to avoid coping, we can do some magic about buffer page.

如何理解 file_operations 中的

有趣的阅读

https://www.moritz.systems/blog/mastering-unix-pipes-part-1/

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。