pipeバッファ
実装イメージ
#define PIPE_DEF_BUFFERS        16
truct pipe_inode_info {
       wait_queue_head_t wait;
       unsigned int nrbufs, curbuf, buffers;
       unsigned int readers;
       unsigned int writers;
       unsigned int waiting_writers;
       unsigned int r_counter;
       unsigned int w_counter;
       struct page *tmp_page;
       struct fasync_struct *fasync_readers;
       struct fasync_struct *fasync_writers;
       struct inode *inode;
       struct pipe_buffer *bufs;
};
struct pipe_buffer {
       struct page *page;
       unsigned int offset, len;
       const struct pipe_buf_operations *ops;
       unsigned int flags;
       unsigned long private;
};
struct pipe_inode_info * alloc_pipe_info(struct inode *inode)
{
       struct pipe_inode_info *pipe;
       pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
       if (pipe) {
               pipe->bufs = kzalloc(sizeof(struct pipe_buffer) * PIPE_DEF_BUFFERS, GFP_KERNEL);
               if (pipe->bufs) {
                       init_waitqueue_head(&pipe->wait);
                       pipe->r_counter = pipe->w_counter = 1;
                       pipe->inode = inode;
                       pipe->buffers = PIPE_DEF_BUFFERS;
                       return pipe;
               }
               kfree(pipe);
       }
       return NULL;
}
デフォルのパイプサイズはsizeof(struct pipe_buffer)のstruct pipe_bufferのpage*PIPE_DEF_BUFFERS
inode = new_inode_pseudo(pipe_mnt->mnt_sb);
struct pipe_inode_info pipe = alloc_pipe_info(inode)  { inode->i_pipe = pipe; }
pfile.dentry->d_inode = inode;
pfile.dentry->d_inode->i_pipe.buffers = PIPE_DEF_BUFFERS
pfile.dentry->d_inode->i_pipe.bufs    = sizeof(struct pipe_buffer)*PIPE_DEF_BUFFERS;
struct pipe_buffer *writing-pipe = pfile.dentry->d_inode->i_pipe.bufs + writing-position
strcpy(writing-pipe->page, data, strlen(data));
サンプル
[root@v.north]# cat pipe-write.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#define PAGE_SIZE              4096
#define PIPE_DEF_BUFFERS       16
int main(int argc, char *argv[])
{
    int pipefd[2];
    char	*wbuf, rbuf[10];
    int	cnt, wcnt, tcnt, pipe_size, write_size;
    wcnt = atoi(argv[1]);
    wbuf = "11111111111111111111111111111111111111111111111111";
    tcnt = 0;
    pipe2(pipefd, O_NONBLOCK);
    while(1) {
        cnt = write(pipefd[1], wbuf, wcnt);
        if(cnt <= 0) {
            break;
          }
        tcnt += cnt;
     }
    pipe_size  = PAGE_SIZE*PIPE_DEF_BUFFERS;
    write_size = tcnt;
    printf("pipe buff:%d  writed size:%d\n", pipe_size, write_size);
    printf("empty size by pipe buff :%d\n", pipe_size - write_size);
    printf("empty size by each  page:%d\n", (PAGE_SIZE % wcnt)*PIPE_DEF_BUFFERS);
    printf("\n");
}
[root@v.north]# ./pipe-write.out 1    <=2^0pipe buff:65536 writed size:65536
empty size by pipe buff :0
empty size by each page:0
[root@v.north]# ./pipe-write.out 2 <=2^1
pipe buff:65536 writed size:65536
empty size by pipe buff :0
empty size by each page:0
[root@v.north]# ./pipe-write.out 3
pipe buff:65536 writed size:65520
empty size by pipe buff :16
empty size by each page:16
[root@v.north]# ./pipe-write.out 4 <=2^2
pipe buff:65536 writed size:65536
empty size by pipe buff :0
empty size by each page:0
[root@v.north]# ./pipe-write.out 5
pipe buff:65536 writed size:65520
empty size by pipe buff :16
empty size by each page:16
[root@v.north]# ./pipe-write.out 6
pipe buff:65536 writed size:65472
empty size by pipe buff :64
empty size by each page:64
[root@v.north]# ./pipe-write.out 7
pipe buff:65536 writed size:65520
empty size by pipe buff :16
empty size by each page:16
[root@v.north]# ./pipe-write.out 8 <=2^3
pipe buff:65536 writed size:65536
empty size by pipe buff :0
empty size by each page:0
empty size by pipe buff>書き込みサイズで書き込みできないのは、empty size by pipe buffは、page単位の空サイズの合計
追記
書き込みをサイズ毎に行う場合、パイプの全バッファ有効利用のため、書き込みサイズは2のべき乗とすべき。通常ファイルオペレーションの書き込みは、generic_file_aio_writeによるファイルキャッシュへの書き込みとなるが、pipeは異るファイル間でのデータ共有とすべく、ファイルキャッシュでないpipe_writeによる上記実装となっている。
const struct file_operations write_pipefifo_fops = {
       .llseek         = no_llseek,
       .read           = bad_pipe_r,
       .write          = do_sync_write,
       .aio_write      = pipe_write,
       .poll           = pipe_poll,
       .unlocked_ioctl = pipe_ioctl,
       .open           = pipe_write_open,
       .release        = pipe_write_release,
       .fasync         = pipe_write_fasync,
};
    




