VOP_RDWR(9)

명칭
VOP_READ, VOP_WRITE - 파일의 읽어들여 또는 기입해

서식
<sys/param.h> <sys/vnode.h> <sys/uio.h> int VOP_READ(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) int VOP_WRITE(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)

해설
이러한 엔트리 포인트는, 파일의 내용을 읽어들여 또는 기입합니다.

인수는 이하와 같습니다.

vp  파일의 vnode.

uio 읽어들여 또는 기입해 대상의 데이터의 위치.

ioflag
    여러가지 플래그.

cnp 호출측의 증명.

ioflag 인수는, 파일 시스템에 대한 인스트럭션 및 힌트를 주기 위해서(때문에) 사용됩니다. 읽기를 시도할 때에는, 상위의 16 비트는, 파일 시스템이 시도해야 할 예측의 힌트를 (파일 시스템 블록 단위로) 제공하기 위해서 사용됩니다. 하위의 16 비트는, 이하의 플래그를 포함할 수가 있는 비트 마스크입니다.

IO_UNIT
    불가분에 입출력을 행합니다.

IO_APPEND
    말미에 추가 기입을 행합니다.

IO_SYNC
    동기적으로 입출력을 행합니다.

IO_NODELOCKED
    하위층의 노드는 이미 락 되고 있습니다.

IO_NDELAY
    파일 테이블에 FNDELAY 플래그를 설정합니다.

IO_VMIO
    가상 메모리 입출력 (VMIO) area에 데이터가 이미 있습니다.

락
들어갈 때에, 파일은 락 되고 있어야 하는 것으로, 종료시까지 락 계속 됩니다.

반환값
성공시에는 0 이 돌려주어져 그렇지 않은 경우에는 에러 코드가 돌려주어집니다.

유사 코드

    int
    vop_read(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
    {
        struct buf *bp;
        off_t bytesinfile;
        daddr_t lbn, nextlbn;
        long size, xfersize, blkoffset;
        int error;
        size = block size of filesystem;
        for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) {
    	bytesinfile = size of file - uio->uio_offset;
    	if (bytesinfile <= 0)
    	    break;
    	lbn = uio->uio_offset / size;
    	blkoffset = uio->uio_offset - lbn * size;
    	xfersize = size - blkoffset;
    	if (uio->uio_resid < xfersize)
    	    xfersize = uio->uio_resid;
    	if (bytesinfile < xfersize)
    	    xfersize = bytesinfile;

    	error = bread(vp, lbn, size, NOCRED, &bp);
    	if (error) {
    	    brelse(bp);
    	    bp = NULL;
    	    break;
    	}
    	/*
    	 * 입출력 에러가 일어났을 때에는 0 이 아닌 b_resid 마셔
    	 * (을)를 얻습니다. 이것은 위에서 break 를 일으켜야 합니다.
    	 * 그렇지만, 짧은 읽기가 에러를 일으키지 않았다
    	 * 경우에는, 잘못한 또는 초기화되어 있지 않은 데이터의
    	 * uiomove 를 행하지 않는 것을 프로텍션하고 싶다.
    	 */
    	size -= bp->b_resid;
    	if (size < xfersize) {
    	    if (size == 0)
    		break;
    	    xfersize = size;
    	}

    	error = uiomove((char *) bp->b_data + blkoffset, (int) xfersize, uio);
    	if (error)
    	    break;
    	bqrelse(bp);
        }
        if (bp ! = NULL)
    	bqrelse(bp);
        return error;
    }
    int
    vop_write(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
    {
        struct buf *bp;
        off_t bytesinfile;
        daddr_t lbn, nextlbn;
        off_t osize;
        long size, resid, xfersize, blkoffset;
        int flags;
        int error;
        osize = size of file;
        size = block size of filesystem;
        resid = uio->uio_resid;
        if (ioflag & IO_SYNC)
    	flags = B_SYNC;
        else
    	flags = 0;
        for (error = 0; uio->uio_resid > 0;) {
    	lbn = uio->uio_offset / size;
    	blkoffset = uio->uio_offset - lbn * size;
    	xfersize = size - blkoffset;
    	if (uio->uio_resid < xfersize)
    	    xfersize = uio->uio_resid;

    	if (uio->uio_offset + xfersize > size of file)
    	    vnode_pager_setsize(vp, uio->uio_offset + xfersize);
    	if (size > xfersize)
    	    flags |= B_CLRBUF;
    	else
    	    flags &= ~B_CLRBUF;
    	error = find_block_in_file(vp, lbn, blkoffset + xfersize,
    				   cred, &bp, flags);
    	if (error)
    	    break;
    	if (uio->uio_offset + xfersize > size of file)
    	    set size of file to uio->uio_offset + xfersize;
    	error = uiomove((char *) bp->b_data + blkoffset, (int) xfersize, uio);
    	/* XXX ufs 는 여기서 에러 체크를 하고 있지 않습니다. 왜?  */
    	if (ioflag & IO_VMIO)
    	    bp->b_flags |= B_RELBUF; /* ??? */
    	if (ioflag & IO_SYNC)
    	    bwrite(bp);
    	else if (xfersize + blkoffset == size)
    	    bawrite(bp);
    	else
    	    bdwrite(bp);
    	if (error || xfersize == 0)
    	    break;
        }
        if (error) {
    	if (ioflag & IO_UNIT) {
    	    VOP_TRUNCATE(vp, osize, ioflag & IO_SYNC, cred, uio->uio_procp);
    	    uio->uio_offset -= resid - uio->uio_resid;
    	    uio->uio_resid = resid;
    	}
        } else if (resid > uio->uio_resid && (ioflag & IO_SYNC)) {
    	struct timeval tv;
    	error = VOP_UPDATE(vp, &tv, &tv, 1); /* XXX 이것은 무엇을 하고 있는 거야?  */
        }
        return error;
    }

에러

[EFBIG]
    프로세스의 파일 사이즈 제한 또는 최대 파일 사이즈를 넘는다 파일을 쓰기 이제(벌써)로 했습니다.

[ENOSPC]
    파일 시스템이 가득합니다.

[EPERM]
    추가만의 플래그가 파일로 설정되어 있습니다만, 호출측이 현재의 파일 종료 위치보다 전에 쓰기 이제(벌써)로 했습니다.

관련 항목
uiomove(9), vnode(9)

저자
이 메뉴얼 페이지는 Doug Rabson 하지만 썼습니다.