안녕하세요~ 호서대학교 석사(과정)이우영 입니다.


요즘 날씨가 너무 좋아서 어디론가 놀러가고 픈 마음이지만!


오늘도 공부 해봅시다.


/dev/null을 대부분의 사람들이 블랙홀이라 표현을 합니다.


모든 내용이 사라져 버립니다. 실제로는 내부에서 아무 처리도 안하고 리터해 버리기 때문입니다.


이것이 필요할까? 라는 생각이 들 수도 있지만 다 이유가 있기 때문에 있겠죠?


오늘은 null_fops 부분부터 시작해 보겠습니다.


 822static const struct file_operations null_fops = {
 823        .llseek         = null_lseek,
 824        .read           = read_null,
 825        .write          = write_null,
 826        .splice_write   = splice_write_null,
 827};

여기서는 llseek, read, write, splice_write 4가지를 정의 했습니다.

먼저 null_lseek 부분은 아래와 같이 정의 되어 있습니다.

 747/*
 748 * Special lseek() function for /dev/null and /dev/zero.  Most notably, you
 749 * can fopen() both devices with "a" now.  This was previously impossible.
 750 * -- SRB.
 751 */
 752
 753static loff_t null_lseek(struct file * file, loff_t offset, int orig)
 754{
 755        return file->f_pos = 0;
 756}

이 합수는 /dev/null, /dev/zero를 위해 특별히 사용되는 함수라고 쓰여 있습니다.

전에는 불가능 했지만 양쪽 디바이스에서 동시에 fopen() 할 수 있도록 만든거 같습니다.

하는 일은 file->f_pos를(파일에서 읽고 쓰는 위치를 나타내는 곳) 0으로 만들고


file의 주소를 리턴 합니다. (별다른 일을 안하죠 ㅎㅎ)



 678static ssize_t read_null(struct file * file, char __user * buf,
 679                         size_t count, loff_t *ppos)
 680{
 681        return 0;
 682}
 683
 684static ssize_t write_null(struct file * file, const char __user * buf,
 685                          size_t count, loff_t *ppos)
 686{
 687        return count;
 688}

read와 write 부분도 별 다른 작업을 안하고 바로 리턴 합니다


 696static ssize_t splice_write_null(struct pipe_inode_info *pipe,struct file *out,
 697                                 loff_t *ppos, size_t len, unsigned int flags)
 698{
 699        return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null);
 700}

splice_from_pipe 이라는 생소한 함수가 보이내요..

splice data from a pipe to a file 파일의 파이프에서 data를 잇는다?붙인다? 이런 뜻인듣 합니다.

linux/fs/splice.c를 보시면 함수가 있습니다.

 721ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out,
 722                         loff_t *ppos, size_t len, unsigned int flags,
 723                         splice_actor *actor)
 724{
 725        ssize_t ret;
 726        struct inode *inode = out->f_mapping->host;
 727        struct splice_desc sd = {
 728                .total_len = len,
 729                .flags = flags,
 730                .pos = *ppos,
 731                .u.file = out,
 732        };
 733
 734        /*
 735         * The actor worker might be calling ->write_begin and
 736         * ->write_end. Most of the time, these expect i_mutex to
 737         * be held. Since this may result in an ABBA deadlock with
 738         * pipe->inode, we have to order lock acquiry here.
 739         */
 740        inode_double_lock(inode, pipe->inode);
 741        ret = __splice_from_pipe(pipe, &sd, actor);
 742        inode_double_unlock(inode, pipe->inode);
 743
 744        return ret;
 745}

교착상태를 피하기위해 락을 해주고 __splice_from_pipe()를 작업을 하고 옵니다.


보시다 시피 /dev/null은 별다른 잡업이 없습니다.


오늘은 /dev/null에 대해서 간단하게 알아 보았습니다.

그럼 다음시간에 만나요~