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