3 .\" Copyright (c) 1996 Doug Rabson
5 .\" All rights reserved.
7 .\" This program is free software.
9 .\" Redistribution and use in source and binary forms, with or without
10 .\" modification, are permitted provided that the following conditions
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.
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.
29 .\" $FreeBSD: src/share/man/man9/VOP_RDWR.9,v 1.9.2.2 2001/12/17 11:30:18 ru Exp $
30 .\" $DragonFly: src/share/man/man9/VOP_RDWR.9,v 1.3 2003/07/27 05:36:06 hmp Exp $
38 .Nd read or write a file
44 .Fn VOP_READ "struct vnode *vp" "struct uio *uio" "int ioflag" "struct ucred *cred"
46 .Fn VOP_WRITE "struct vnode *vp" "struct uio *uio" "int ioflag" "struct ucred *cred"
48 These entry points read or write the contents of a file
51 .Bl -tag -width ioflag
55 the location of the data to be read or written
59 the credentials of the caller
64 argument is used to give directives and hints to the filesystem.
65 When attempting a read, the high 16 bits are used to provide a
66 read-ahead hint (in units of filesystem blocks) that the filesystem
67 should attempt. The low 16 bits are a bit mask which can contain
69 .Bl -tag -width IO_NODELOCKED
77 underlying node already locked
80 flag set in file table
82 data already in VMIO space
85 The file should be locked on entry and will still be locked on exit.
87 Zero is returned on success, otherwise an error code is returned.
91 vop_read(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
96 long size, xfersize, blkoffset;
99 size = block size of filesystem;
101 for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) {
102 bytesinfile = size of file - uio->uio_offset;
103 if (bytesinfile <= 0)
106 lbn = uio->uio_offset / size;
107 blkoffset = uio->uio_offset - lbn * size;
109 xfersize = size - blkoffset;
110 if (uio->uio_resid < xfersize)
111 xfersize = uio->uio_resid;
112 if (bytesinfile < xfersize)
113 xfersize = bytesinfile;
115 error = bread(vp, lbn, size, NOCRED, &bp);
123 * We should only get non-zero b_resid when an I/O error
124 * has occurred, which should cause us to break above.
125 * However, if the short read did not cause an error,
126 * then we want to ensure that we do not uiomove bad
127 * or uninitialized data.
130 if (size < xfersize) {
136 error = uiomove((char *)bp->b_data + blkoffset, (int)xfersize, uio);
149 vop_write(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
153 daddr_t lbn, nextlbn;
155 long size, resid, xfersize, blkoffset;
159 osize = size of file;
160 size = block size of filesystem;
161 resid = uio->uio_resid;
162 if (ioflag & IO_SYNC)
167 for (error = 0; uio->uio_resid > 0;) {
168 lbn = uio->uio_offset / size;
169 blkoffset = uio->uio_offset - lbn * size;
171 xfersize = size - blkoffset;
172 if (uio->uio_resid < xfersize)
173 xfersize = uio->uio_resid;
175 if (uio->uio_offset + xfersize > size of file)
176 vnode_pager_setsize(vp, uio->uio_offset + xfersize);
183 error = find_block_in_file(vp, lbn, blkoffset + xfersize,
188 if (uio->uio_offset + xfersize > size of file)
189 set size of file to uio->uio_offset + xfersize;
191 error = uiomove((char *)bp->b_data + blkoffset, (int) xfersize, uio);
192 /* XXX ufs does not check the error here. Why? */
194 if (ioflag & IO_VMIO)
195 bp->b_flags |= B_RELBUF; /* ??? */
197 if (ioflag & IO_SYNC)
199 else if (xfersize + blkoffset == size)
204 if (error || xfersize == 0)
209 if (ioflag & IO_UNIT) {
210 VOP_TRUNCATE(vp, osize, ioflag & IO_SYNC, cred, uio->uio_procp);
211 uio->uio_offset -= resid - uio->uio_resid;
212 uio->uio_resid = resid;
214 } else if (resid > uio->uio_resid && (ioflag & IO_SYNC)) {
216 error = VOP_UPDATE(vp, &tv, &tv, 1); /* XXX what does this do? */
225 The filesystem is full.
231 This man page was written by