diff options
author | alc <alc@FreeBSD.org> | 1999-03-26 20:25:21 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 1999-03-26 20:25:21 +0000 |
commit | 1e32f0021ea3509f5552d7a50ae07e37035fed6d (patch) | |
tree | 544a6fb4c84a5d003d1634a36cc2f0a1a6d1fc7d /sys/kern/vfs_vnops.c | |
parent | bb2e8627df0b3ef08917543048f28eaf026fdc5a (diff) | |
download | FreeBSD-src-1e32f0021ea3509f5552d7a50ae07e37035fed6d.zip FreeBSD-src-1e32f0021ea3509f5552d7a50ae07e37035fed6d.tar.gz |
Changed vn_read/write such that fp->f_offset isn't touched
if uio->uio_offset != -1. This fixes a problem with aio_read/write
and permits a straightforward implementation of pread/pwrite.
PR: kern/8669
Submitted by: John Plevyak <jplevyak@inktomi.com>
Reviewed by: Matthew Dillon <dillon@apollo.backplane.com>
Diffstat (limited to 'sys/kern/vfs_vnops.c')
-rw-r--r-- | sys/kern/vfs_vnops.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index b9242b3..708c388d 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94 - * $Id: vfs_vnops.c,v 1.62 1999/01/20 14:49:11 eivind Exp $ + * $Id: vfs_vnops.c,v 1.63 1999/01/30 12:21:49 phk Exp $ */ #include <sys/param.h> @@ -284,13 +284,18 @@ vn_read(fp, uio, cred) VOP_LEASE(vp, p, cred, LEASE_READ); vn_lock(vp, LK_SHARED | LK_NOPAUSE | LK_RETRY, p); - if (uio->uio_offset == -1) - uio->uio_offset = fp->f_offset; - count = uio->uio_resid; + flag = 0; if (fp->f_flag & FNONBLOCK) flag |= IO_NDELAY; + if (uio->uio_offset != -1) { + error = VOP_READ(vp, uio, flag, cred); + goto out; + } + uio->uio_offset = fp->f_offset; + count = uio->uio_resid; + /* * Sequential read heuristic. * If we have been doing sequential input, @@ -321,6 +326,7 @@ vn_read(fp, uio, cred) error = VOP_READ(vp, uio, flag, cred); fp->f_offset += count - uio->uio_resid; fp->f_nextread = fp->f_offset; +out: VOP_UNLOCK(vp, 0, p); return (error); } @@ -347,6 +353,10 @@ vn_write(fp, uio, cred) ioflag |= IO_SYNC; VOP_LEASE(vp, p, cred, LEASE_WRITE); vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + if (uio->uio_offset != -1) { + error = VOP_WRITE(vp, uio, ioflag, cred); + goto out; + } uio->uio_offset = fp->f_offset; count = uio->uio_resid; error = VOP_WRITE(vp, uio, ioflag, cred); @@ -354,6 +364,7 @@ vn_write(fp, uio, cred) fp->f_offset = uio->uio_offset; else fp->f_offset += count - uio->uio_resid; +out: VOP_UNLOCK(vp, 0, p); return (error); } |