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