summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_vnops.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>1999-03-26 20:25:21 +0000
committeralc <alc@FreeBSD.org>1999-03-26 20:25:21 +0000
commit1e32f0021ea3509f5552d7a50ae07e37035fed6d (patch)
tree544a6fb4c84a5d003d1634a36cc2f0a1a6d1fc7d /sys/kern/vfs_vnops.c
parentbb2e8627df0b3ef08917543048f28eaf026fdc5a (diff)
downloadFreeBSD-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.c19
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);
}
OpenPOWER on IntegriCloud