The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Интерактивная система просмотра системных руководств (man-ов)

 ТемаНаборКатегория 
 
 [Cписок руководств | Печать]

VOP_RDWR (9)
  • >> VOP_RDWR (9) ( FreeBSD man: Ядро )

  • BSD mandoc
     

    NAME

    VOP_READ
    
     
    VOP_WRITE
    
     - read or write a file
    
     
    

    SYNOPSIS

       #include <sys/param.h>
       #include <sys/vnode.h>
       #include <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);
     

    DESCRIPTION

    These entry points read or write the contents of a file

    The arguments are:

    Fa vp
    The vnode of the file.
    Fa uio
    The location of the data to be read or written.
    Fa ioflag
    Various flags.
    Fa cnp
    The credentials of the caller.

    The Fa ioflag argument is used to give directives and hints to the file system. When attempting a read, the high 16 bits are used to provide a read-ahead hint (in units of file system blocks) that the file system should attempt. The low 16 bits are a bit mask which can contain the following flags:

    IO_UNIT
    Do I/O as atomic unit.
    IO_APPEND
    Append write to end.
    IO_SYNC
    Do I/O synchronously.
    IO_NODELOCKED
    Underlying node already locked.
    IO_NDELAY
    FNDELAY flag set in file table.
    IO_VMIO
    Data already in VMIO space.

     

    LOCKS

    The file should be locked on entry and will still be locked on exit.  

    RETURN VALUES

    Zero is returned on success, otherwise an error code is returned.  

    PSEUDOCODE

    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 file system;
    
        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;
            }
    
            /*
             * We should only get non-zero b_resid when an I/O error
             * has occurred, which should cause us to break above.
             * However, if the short read did not cause an error,
             * then we want to ensure that we do not uiomove bad
             * or uninitialized data.
             */
            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 file system;
        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 does not check the error here.  Why? */
    
            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) {
                /* call private routine to truncate file. */
                your_truncate(vp, osize, ioflag & IO_SYNC, cred, uio->uio_td);
                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 what does this do? */
        }
    
        return (error);
    }
    
     

    ERRORS

    Bq Er EFBIG
    An attempt was made to write a file that exceeds the process's file size limit or the maximum file size.
    Bq Er ENOSPC
    The file system is full.
    Bq Er EPERM
    An append-only flag is set on the file, but the caller is attempting to write before the current end of file.

     

    SEE ALSO

    uiomove(9), vnode(9)  

    AUTHORS

    This manual page was written by An Doug Rabson .


     

    Index

    NAME
    SYNOPSIS
    DESCRIPTION
    LOCKS
    RETURN VALUES
    PSEUDOCODE
    ERRORS
    SEE ALSO
    AUTHORS


    Поиск по тексту MAN-ов: 




    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру