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.4 1997/03/07 03:32:27 mpp 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/param.h> 40.Fd #include <sys/vnode.h> 41.Fd #include <sys/uio.h> 42.Ft int 43.Fn VOP_READ "struct vnode *vp" "struct uio *uio" "int ioflag" "struct ucred *cred" 44.Ft int 45.Fn VOP_WRITE "struct vnode *vp" "struct uio *uio" "int ioflag" "struct ucred *cred" 46.Sh DESCRIPTION 47These entry points read or write the contents of a file 48.Pp 49The arguments are: 50.Bl -tag -width ioflag 51.It Ar vp 52the vnode of the file 53.It Ar uio 54the location of the data to be read or written 55.It Ar ioflag 56various flags 57.It Ar cnp 58the credentials of the caller 59.El 60.Pp 61The 62.Fa ioflag 63argument is a bit mask which can contain the following flags: 64.Bl -tag -width IO_NODELOCKED 65.It Dv IO_UNIT 66do I/O as atomic unit 67.It Dv IO_APPEND 68append write to end 69.It Dv IO_SYNC 70do I/O synchronously 71.It Dv IO_NODELOCKED 72underlying node already locked 73.It Dv IO_NDELAY 74.Dv FNDELAY 75flag set in file table 76.It Dv IO_VMIO 77data already in VMIO space 78.El 79.Sh LOCKS 80The file should be locked on entry and will still be locked on exit. 81.Sh RETURN VALUES 82Zero is returned on success, otherwise an error code is returned. 83.Sh PSEUDOCODE 84.Bd -literal 85int 86vop_read(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) 87{ 88 struct buf *bp; 89 off_t bytesinfile; 90 daddr_t lbn, nextlbn; 91 long size, xfersize, blkoffset; 92 int error; 93 94 size = block size of filesystem; 95 96 for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) { 97 bytesinfile = size of file - uio->uio_offset; 98 if (bytesinfile <= 0) 99 break; 100 101 lbn = uio->uio_offset / size; 102 blkoffset = uio->uio_offset - lbn * size; 103 104 xfersize = size - blkoffset; 105 if (uio->uio_resid < xfersize) 106 xfersize = uio->uio_resid; 107 if (bytesinfile < xfersize) 108 xfersize = bytesinfile; 109 110 error = bread(vp, lbn, size, NOCRED, &bp); 111 if (error) { 112 brelse(bp); 113 bp = NULL; 114 break; 115 } 116 117 /* 118 * We should only get non-zero b_resid when an I/O error 119 * has occurred, which should cause us to break above. 120 * However, if the short read did not cause an error, 121 * then we want to ensure that we do not uiomove bad 122 * or uninitialized data. 123 */ 124 size -= bp->b_resid; 125 if (size < xfersize) { 126 if (size == 0) 127 break; 128 xfersize = size; 129 } 130 131 error = uiomove((char *)bp->b_data + blkoffset, (int)xfersize, uio); 132 if (error) 133 break; 134 135 bqrelse(bp); 136 } 137 if (bp != NULL) 138 bqrelse(bp); 139 140 return error; 141} 142 143int 144vop_write(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) 145{ 146 struct buf *bp; 147 off_t bytesinfile; 148 daddr_t lbn, nextlbn; 149 off_t osize; 150 long size, resid, xfersize, blkoffset; 151 int flags; 152 int error; 153 154 osize = size of file; 155 size = block size of filesystem; 156 resid = uio->uio_resid; 157 if (ioflag & IO_SYNC) 158 flags = B_SYNC; 159 else 160 flags = 0; 161 162 for (error = 0; uio->uio_resid > 0;) { 163 lbn = uio->uio_offset / size; 164 blkoffset = uio->uio_offset - lbn * size; 165 166 xfersize = size - blkoffset; 167 if (uio->uio_resid < xfersize) 168 xfersize = uio->uio_resid; 169 170 if (uio->uio_offset + xfersize > size of file) 171 vnode_pager_setsize(vp, uio->uio_offset + xfersize); 172 173 if (size > xfersize) 174 flags |= B_CLRBUF; 175 else 176 flags &= ~B_CLRBUF; 177 178 error = find_block_in_file(vp, lbn, blkoffset + xfersize, 179 cred, &bp, flags); 180 if (error) 181 break; 182 183 if (uio->uio_offset + xfersize > size of file) 184 set size of file to uio->uio_offset + xfersize; 185 186 error = uiomove((char *)bp->b_data + blkoffset, (int) xfersize, uio); 187 /* XXX ufs does not check the error here. Why? */ 188 189 if (ioflag & IO_VMIO) 190 bp->b_flags |= B_RELBUF; /* ??? */ 191 192 if (ioflag & IO_SYNC) 193 bwrite(bp); 194 else if (xfersize + blkoffset == size) 195 bawrite(bp); 196 else 197 bdwrite(bp); 198 199 if (error || xfersize == 0) 200 break; 201 } 202 203 if (error) { 204 if (ioflag & IO_UNIT) { 205 VOP_TRUNCATE(vp, osize, ioflag & IO_SYNC, cred, uio->uio_procp); 206 uio->uio_offset -= resid - uio->uio_resid; 207 uio->uio_resid = resid; 208 } 209 } else if (resid > uio->uio_resid && (ioflag & IO_SYNC)) { 210 struct timeval tv; 211 error = VOP_UPDATE(vp, &tv, &tv, 1); /* XXX what does this do? */ 212 } 213 214 return error; 215} 216.Ed 217.Sh ERRORS 218.Bl -tag -width Er 219.It Bq Er ENOSPC 220The filesystem is full. 221.El 222.Sh SEE ALSO 223.Xr vnode 9 , 224.Xr uiomove 9 225.Sh AUTHORS 226This man page was written by Doug Rabson. 227 228