diff options
author | kib <kib@FreeBSD.org> | 2012-07-02 21:01:03 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2012-07-02 21:01:03 +0000 |
commit | 53224f018aac13056c11af9d1233317b1754149c (patch) | |
tree | 26c1ae1ac3dde3bf8b9b01fad04caad427a4ef48 /sys/ufs | |
parent | 293bf50336e246390039b341f229e30d00d97d27 (diff) | |
download | FreeBSD-src-53224f018aac13056c11af9d1233317b1754149c.zip FreeBSD-src-53224f018aac13056c11af9d1233317b1754149c.tar.gz |
Extend the KPI to lock and unlock f_offset member of struct file. It
now fully encapsulates all accesses to f_offset, and extends f_offset
locking to other consumers that need it, in particular, to lseek() and
variants of getdirentries().
Ensure that on 32bit architectures f_offset, which is 64bit quantity,
always read and written under the mtxpool protection. This fixes
apparently easy to trigger race when parallel lseek()s or lseek() and
read/write could destroy file offset.
The already broken ABI emulations, including iBCS and SysV, are not
converted (yet).
Tested by: pho
No objections from: jhb
MFC after: 3 weeks
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ffs/ffs_alloc.c | 7 |
1 files changed, 2 insertions, 5 deletions
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index 68ea172..2b3740d 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -2865,10 +2865,9 @@ buffered_write(fp, uio, active_cred, flags, td) if (ip->i_devvp != devvp) return (EINVAL); fs = ip->i_fs; + foffset_lock_uio(fp, uio, flags); vfslocked = VFS_LOCK_GIANT(ip->i_vnode->v_mount); vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); - if ((flags & FOF_OFFSET) == 0) - uio->uio_offset = fp->f_offset; #ifdef DEBUG if (fsckcmds) { printf("%s: buffered write for block %jd\n", @@ -2893,11 +2892,9 @@ buffered_write(fp, uio, active_cred, flags, td) goto out; } error = bwrite(bp); - if ((flags & FOF_OFFSET) == 0) - fp->f_offset = uio->uio_offset; - fp->f_nextoff = uio->uio_offset; out: VOP_UNLOCK(devvp, 0); VFS_UNLOCK_GIANT(vfslocked); + foffset_unlock_uio(fp, uio, flags | FOF_NEXTOFF); return (error); } |