1 .\" Copyright (c) 1996 Doug Rabson
3 .\" All rights reserved.
5 .\" This program is free software.
7 .\" Redistribution and use in source and binary forms, with or without
8 .\" modification, are permitted provided that the following conditions
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.
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.
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 $
36 .Nd read or write a file
42 .Fn VOP_READ "struct vnode *vp" "struct uio *uio" "int ioflag" "struct ucred *cred"
44 .Fn VOP_WRITE "struct vnode *vp" "struct uio *uio" "int ioflag" "struct ucred *cred"
46 These entry points read or write the contents of a file
49 .Bl -tag -width ioflag
53 the location of the data to be read or written
57 the credentials of the caller
62 argument is used to give directives and hints to the filesystem.
63 When attempting a read, the high 16 bits are used to provide a
64 read-ahead hint (in units of filesystem blocks) that the filesystem
65 should attempt. The low 16 bits are a bit mask which can contain
67 .Bl -tag -width ".Dv IO_NODELOCKED"
75 underlying node already locked
78 flag set in file table
80 data already in VMIO space
83 The file should be locked on entry and will still be locked on exit.
85 Zero is returned on success, otherwise an error code is returned.
89 vop_read(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
94 long size, xfersize, blkoffset;
97 size = block size of filesystem;
99 for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) {
100 bytesinfile = size of file - uio->uio_offset;
101 if (bytesinfile <= 0)
104 lbn = uio->uio_offset / size;
105 blkoffset = uio->uio_offset - lbn * size;
107 xfersize = size - blkoffset;
108 if (uio->uio_resid < xfersize)
109 xfersize = uio->uio_resid;
110 if (bytesinfile < xfersize)
111 xfersize = bytesinfile;
113 error = bread(vp, lbn, size, NOCRED, &bp);
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.
128 if (size < xfersize) {
134 error = uiomove((char *)bp->b_data + blkoffset, (int)xfersize, uio);
147 vop_write(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
151 daddr_t lbn, nextlbn;
153 long size, resid, xfersize, blkoffset;
157 osize = size of file;
158 size = block size of filesystem;
159 resid = uio->uio_resid;
160 if (ioflag & IO_SYNC)
165 for (error = 0; uio->uio_resid > 0;) {
166 lbn = uio->uio_offset / size;
167 blkoffset = uio->uio_offset - lbn * size;
169 xfersize = size - blkoffset;
170 if (uio->uio_resid < xfersize)
171 xfersize = uio->uio_resid;
173 if (uio->uio_offset + xfersize > size of file)
174 vnode_pager_setsize(vp, uio->uio_offset + xfersize);
181 error = find_block_in_file(vp, lbn, blkoffset + xfersize,
186 if (uio->uio_offset + xfersize > size of file)
187 set size of file to uio->uio_offset + xfersize;
189 error = uiomove((char *)bp->b_data + blkoffset, (int) xfersize, uio);
190 /* XXX ufs does not check the error here. Why? */
192 if (ioflag & IO_VMIO)
193 bp->b_flags |= B_RELBUF; /* ??? */
195 if (ioflag & IO_SYNC)
197 else if (xfersize + blkoffset == size)
202 if (error || xfersize == 0)
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;
212 } else if (resid > uio->uio_resid && (ioflag & IO_SYNC)) {
214 error = VOP_UPDATE(vp, &tv, &tv, 1); /* XXX what does this do? */
223 The filesystem is full.
229 This man page was written by