1.\" -*- nroff -*- 2.\" 3.\" Copyright (c) 1996 Doug Rabson 4.\" 5.\" All rights reserved. 6.\" 7.\" This program is free software. 8.\" 9.\" Redistribution and use in source and binary forms, with or without 10.\" modification, are permitted provided that the following conditions 11.\" are met: 12.\" 1. Redistributions of source code must retain the above copyright 13.\" notice, this list of conditions and the following disclaimer. 14.\" 2. Redistributions in binary form must reproduce the above copyright 15.\" notice, this list of conditions and the following disclaimer in the 16.\" documentation and/or other materials provided with the distribution. 17.\" 18.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 19.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 22.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28.\" 29.\" $Id: VOP_RDWR.9,v 1.3 1997/03/04 10:02:18 dfr Exp $ 30.\" 31.Dd July 24, 1996 32.Os 33.Dt VOP_RDWR 9 34.Sh NAME 35.Nm VOP_READ , 36.Nm VOP_WRITE 37.Nd read or write a file 38.Sh SYNOPSIS 39.Fd #include <sys/vnode.h> 40.Fd #include <sys/uio.h> 41.Ft int 42.Fn VOP_READ "struct vnode *vp" "struct uio *uio" "int ioflag" "struct ucred *cred" 43.Ft int 44.Fn VOP_WRITE "struct vnode *vp" "struct uio *uio" "int ioflag" "struct ucred *cred" 45.Sh DESCRIPTION 46These entry points read or write the contents of a file 47.Pp 48The arguments are: 49.Bl -tag -width ioflag 50.It Ar vp 51the vnode of the file 52.It Ar uio 53the location of the data to be read or written 54.It Ar ioflag 55various flags 56.It Ar cnp 57the credentials of the caller 58.El 59.Pp 60The 61.Fa ioflag 62argument is a bit mask which can contain the following flags: 63.Bl -tag -width IO_NODELOCKED 64.It Dv IO_UNIT 65do I/O as atomic unit 66.It Dv IO_APPEND 67append write to end 68.It Dv IO_SYNC 69do I/O synchronously 70.It Dv IO_NODELOCKED 71underlying node already locked 72.It Dv IO_NDELAY 73.Dv FNDELAY 74flag set in file table 75.It Dv IO_VMIO 76data already in VMIO space 77.El 78.Sh LOCKS 79The file should be locked on entry and will still be locked on exit. 80.Sh RETURN VALUES 81Zero is returned on success, otherwise an error code is returned. 82.Sh PSEUDOCODE 83.Bd -literal 84int 85vop_read(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) 86{ 87 struct buf *bp; 88 off_t bytesinfile; 89 daddr_t lbn, nextlbn; 90 long size, xfersize, blkoffset; 91 int error; 92 93 size = block size of filesystem; 94 95 for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) { 96 bytesinfile = size of file - uio->uio_offset; 97 if (bytesinfile <= 0) 98 break; 99 100 lbn = uio->uio_offset / size; 101 blkoffset = uio->uio_offset - lbn * size; 102 103 xfersize = size - blkoffset; 104 if (uio->uio_resid < xfersize) 105 xfersize = uio->uio_resid; 106 if (bytesinfile < xfersize) 107 xfersize = bytesinfile; 108 109 error = bread(vp, lbn, size, NOCRED, &bp); 110 if (error) { 111 brelse(bp); 112 bp = NULL; 113 break; 114 } 115 116 /* 117 * We should only get non-zero b_resid when an I/O error 118 * has occurred, which should cause us to break above. 119 * However, if the short read did not cause an error, 120 * then we want to ensure that we do not uiomove bad 121 * or uninitialized data. 122 */ 123 size -= bp->b_resid; 124 if (size < xfersize) { 125 if (size == 0) 126 break; 127 xfersize = size; 128 } 129 130 error = uiomove((char *)bp->b_data + blkoffset, (int)xfersize, uio); 131 if (error) 132 break; 133 134 bqrelse(bp); 135 } 136 if (bp != NULL) 137 bqrelse(bp); 138 139 return error; 140} 141 142int 143vop_write(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) 144{ 145 struct buf *bp; 146 off_t bytesinfile; 147 daddr_t lbn, nextlbn; 148 off_t osize; 149 long size, resid, xfersize, blkoffset; 150 int flags; 151 int error; 152 153 osize = size of file; 154 size = block size of filesystem; 155 resid = uio->uio_resid; 156 if (ioflag & IO_SYNC) 157 flags = B_SYNC; 158 else 159 flags = 0; 160 161 for (error = 0; uio->uio_resid > 0;) { 162 lbn = uio->uio_offset / size; 163 blkoffset = uio->uio_offset - lbn * size; 164 165 xfersize = size - blkoffset; 166 if (uio->uio_resid < xfersize) 167 xfersize = uio->uio_resid; 168 169 if (uio->uio_offset + xfersize > size of file) 170 vnode_pager_setsize(vp, uio->uio_offset + xfersize); 171 172 if (size > xfersize) 173 flags |= B_CLRBUF; 174 else 175 flags &= ~B_CLRBUF; 176 177 error = find_block_in_file(vp, lbn, blkoffset + xfersize, 178 cred, &bp, flags); 179 if (error) 180 break; 181 182 if (uio->uio_offset + xfersize > size of file) 183 set size of file to uio->uio_offset + xfersize; 184 185 error = uiomove((char *)bp->b_data + blkoffset, (int) xfersize, uio); 186 /* XXX ufs does not check the error here. Why? */ 187 188 if (ioflag & IO_VMIO) 189 bp->b_flags |= B_RELBUF; /* ??? */ 190 191 if (ioflag & IO_SYNC) 192 bwrite(bp); 193 else if (xfersize + blkoffset == size) 194 bawrite(bp); 195 else 196 bdwrite(bp); 197 198 if (error || xfersize == 0) 199 break; 200 } 201 202 if (error) { 203 if (ioflag & IO_UNIT) { 204 VOP_TRUNCATE(vp, osize, ioflag & IO_SYNC, cred, uio->uio_procp); 205 uio->uio_offset -= resid - uio->uio_resid; 206 uio->uio_resid = resid; 207 } 208 } else if (resid > uio->uio_resid && (ioflag & IO_SYNC)) { 209 struct timeval tv; 210 error = VOP_UPDATE(vp, &tv, &tv, 1); /* XXX what does this do? */ 211 } 212 213 return error; 214} 215.Ed 216.Sh ERRORS 217.Bl -tag -width Er 218.It Bq Er ENOSPC 219The filesystem is full. 220.El 221.Sh SEE ALSO 222.Xr vnode 9 , 223.Xr uiomove 9 224.Sh AUTHORS 225This man page was written by Doug Rabson. 226 227