Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs Disentangle buffer-cached I/O from page-cached I/O i...
details: https://anonhg.NetBSD.org/src/rev/5eaca9eb781a
branches: trunk
changeset: 336927:5eaca9eb781a
user: riastradh <riastradh%NetBSD.org@localhost>
date: Fri Mar 27 17:27:55 2015 +0000
description:
Disentangle buffer-cached I/O from page-cached I/O in UFS.
Page-cached I/O is used for regular files, and is initiated by VFS
users such as userland and NFS.
Buffer-cached I/O is used for directories and symlinks, and is issued
only internally by UFS.
New UFS routine ufs_bufio replaces vn_rdwr for internal use.
ufs_bufio is implemented by new UFS operations uo_bufrd/uo_bufwr,
which sit in ufs_readwrite.c alongside the VOP_READ/VOP_WRITE
implementations.
I preserved the code as much as possible and will leave further
simplification for future commits. I kept the ulfs_readwrite.c
copypasta close to ufs_readwrite.c in case we ever want to merge them
back; likewise ext2fs_readwrite.c.
No externally visible semantic change. All atf fs tests still pass.
diffstat:
sys/ufs/chfs/chfs_vnops.c | 9 +-
sys/ufs/ext2fs/ext2fs_extern.h | 4 +-
sys/ufs/ext2fs/ext2fs_lookup.c | 10 +-
sys/ufs/ext2fs/ext2fs_readwrite.c | 257 ++++++++++++++++++++++++++-----------
sys/ufs/ext2fs/ext2fs_rename.c | 16 +-
sys/ufs/ext2fs/ext2fs_vfsops.c | 6 +-
sys/ufs/ext2fs/ext2fs_vnops.c | 17 +-
sys/ufs/ffs/ffs_extern.h | 6 +-
sys/ufs/ffs/ffs_vfsops.c | 6 +-
sys/ufs/lfs/lfs_extern.h | 5 +-
sys/ufs/lfs/lfs_rename.c | 8 +-
sys/ufs/lfs/lfs_vnops.c | 10 +-
sys/ufs/lfs/ulfs_extern.h | 4 +-
sys/ufs/lfs/ulfs_lookup.c | 8 +-
sys/ufs/lfs/ulfs_readwrite.c | 250 +++++++++++++++++++++++++++--------
sys/ufs/lfs/ulfs_vnops.c | 52 +++++++-
sys/ufs/ufs/ufs_extern.h | 4 +-
sys/ufs/ufs/ufs_lookup.c | 8 +-
sys/ufs/ufs/ufs_readwrite.c | 258 +++++++++++++++++++++++++++++--------
sys/ufs/ufs/ufs_rename.c | 8 +-
sys/ufs/ufs/ufs_vnops.c | 60 +++++++-
sys/ufs/ufs/ufsmount.h | 8 +-
22 files changed, 749 insertions(+), 265 deletions(-)
diffs (truncated from 1808 to 300 lines):
diff -r 51ef6af9df11 -r 5eaca9eb781a sys/ufs/chfs/chfs_vnops.c
--- a/sys/ufs/chfs/chfs_vnops.c Fri Mar 27 12:46:51 2015 +0000
+++ b/sys/ufs/chfs/chfs_vnops.c Fri Mar 27 17:27:55 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: chfs_vnops.c,v 1.24 2015/01/11 17:29:57 hannken Exp $ */
+/* $NetBSD: chfs_vnops.c,v 1.25 2015/03/27 17:27:55 riastradh Exp $ */
/*-
* Copyright (c) 2010 Department of Software Engineering,
@@ -1310,9 +1310,8 @@
uvm_vnp_setsize(vp, len);
} else {
- err = vn_rdwr(UIO_WRITE, vp, target, len, (off_t)0,
- UIO_SYSSPACE, IO_NODELOCKED, cnp->cn_cred,
- (size_t *)0, NULL);
+ err = ufs_bufio(UIO_WRITE, vp, target, len, (off_t)0,
+ IO_NODELOCKED, cnp->cn_cred, (size_t *)0, NULL);
}
out:
@@ -1454,7 +1453,7 @@
return (0);
}
- return (VOP_READ(vp, uio, 0, cred));
+ return (UFS_BUFRD(vp, uio, 0, cred));
}
/* --------------------------------------------------------------------- */
diff -r 51ef6af9df11 -r 5eaca9eb781a sys/ufs/ext2fs/ext2fs_extern.h
--- a/sys/ufs/ext2fs/ext2fs_extern.h Fri Mar 27 12:46:51 2015 +0000
+++ b/sys/ufs/ext2fs/ext2fs_extern.h Fri Mar 27 17:27:55 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ext2fs_extern.h,v 1.47 2014/05/25 14:07:19 hannken Exp $ */
+/* $NetBSD: ext2fs_extern.h,v 1.48 2015/03/27 17:27:56 riastradh Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@@ -147,6 +147,8 @@
/* ext2fs_readwrite.c */
int ext2fs_read(void *);
int ext2fs_write(void *);
+int ext2fs_bufrd(struct vnode *, struct uio *, int, kauth_cred_t);
+int ext2fs_bufwr(struct vnode *, struct uio *, int, kauth_cred_t);
/* ext2fs_vnops.c */
int ext2fs_create(void *);
diff -r 51ef6af9df11 -r 5eaca9eb781a sys/ufs/ext2fs/ext2fs_lookup.c
--- a/sys/ufs/ext2fs/ext2fs_lookup.c Fri Mar 27 12:46:51 2015 +0000
+++ b/sys/ufs/ext2fs/ext2fs_lookup.c Fri Mar 27 17:27:55 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ext2fs_lookup.c,v 1.77 2014/06/03 19:30:29 joerg Exp $ */
+/* $NetBSD: ext2fs_lookup.c,v 1.78 2015/03/27 17:27:56 riastradh Exp $ */
/*
* Modified for NetBSD 1.2E
@@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_lookup.c,v 1.77 2014/06/03 19:30:29 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_lookup.c,v 1.78 2015/03/27 17:27:56 riastradh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -180,7 +180,7 @@
}
aiov.iov_base = dirbuf;
- error = VOP_READ(ap->a_vp, &auio, 0, ap->a_cred);
+ error = UFS_BUFRD(ap->a_vp, &auio, 0, ap->a_cred);
if (error == 0) {
readcnt = e2fs_count - auio.uio_resid;
for (dp = (struct ext2fs_direct *)dirbuf;
@@ -952,8 +952,8 @@
#define MINDIRSIZ (sizeof (struct ext2fs_dirtemplate) / 2)
for (off = 0; off < ext2fs_size(ip); off += fs2h16(dp->e2d_reclen)) {
- error = vn_rdwr(UIO_READ, ITOV(ip), (void *)dp, MINDIRSIZ, off,
- UIO_SYSSPACE, IO_NODELOCKED, cred, &count, NULL);
+ error = ufs_bufio(UIO_READ, ITOV(ip), (void *)dp, MINDIRSIZ,
+ off, IO_NODELOCKED, cred, &count, NULL);
/*
* Since we read MINDIRSIZ, residual must
* be 0 unless we're at end of file.
diff -r 51ef6af9df11 -r 5eaca9eb781a sys/ufs/ext2fs/ext2fs_readwrite.c
--- a/sys/ufs/ext2fs/ext2fs_readwrite.c Fri Mar 27 12:46:51 2015 +0000
+++ b/sys/ufs/ext2fs/ext2fs_readwrite.c Fri Mar 27 17:27:55 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ext2fs_readwrite.c,v 1.66 2014/11/09 18:23:28 maxv Exp $ */
+/* $NetBSD: ext2fs_readwrite.c,v 1.67 2015/03/27 17:27:56 riastradh Exp $ */
/*-
* Copyright (c) 1993
@@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_readwrite.c,v 1.66 2014/11/09 18:23:28 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_readwrite.c,v 1.67 2015/03/27 17:27:56 riastradh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -97,13 +97,9 @@
struct vnode *vp;
struct inode *ip;
struct uio *uio;
- struct m_ext2fs *fs;
- struct buf *bp;
struct ufsmount *ump;
vsize_t bytelen;
- daddr_t lbn, nextlbn;
- off_t bytesinfile;
- long size, xfersize, blkoffset;
+ int advice;
int error;
vp = ap->a_vp;
@@ -123,7 +119,10 @@
} else if (vp->v_type != VREG && vp->v_type != VDIR)
panic("%s: type %d", "ext2fs_read", vp->v_type);
#endif
- fs = ip->i_e2fs;
+ /* XXX Eliminate me by refusing directory reads from userland. */
+ if (vp->v_type == VDIR)
+ return ext2fs_bufrd(vp, uio, ap->a_ioflag, ap->a_cred);
+
if ((uint64_t)uio->uio_offset > ump->um_maxfilesize)
return (EFBIG);
if (uio->uio_resid == 0)
@@ -131,22 +130,64 @@
if (uio->uio_offset >= ext2fs_size(ip))
goto out;
- if (vp->v_type == VREG) {
- const int advice = IO_ADV_DECODE(ap->a_ioflag);
-
- while (uio->uio_resid > 0) {
- bytelen = MIN(ext2fs_size(ip) - uio->uio_offset,
+ KASSERT(vp->v_type == VREG);
+ advice = IO_ADV_DECODE(ap->a_ioflag);
+ while (uio->uio_resid > 0) {
+ bytelen = MIN(ext2fs_size(ip) - uio->uio_offset,
uio->uio_resid);
- if (bytelen == 0)
- break;
+ if (bytelen == 0)
+ break;
+
+ error = ubc_uiomove(&vp->v_uobj, uio, bytelen, advice,
+ UBC_READ | UBC_PARTIALOK | UBC_UNMAP_FLAG(vp));
+ if (error)
+ break;
+ }
+
+out:
+ if (!(vp->v_mount->mnt_flag & MNT_NOATIME)) {
+ ip->i_flag |= IN_ACCESS;
+ if ((ap->a_ioflag & IO_SYNC) == IO_SYNC)
+ error = ext2fs_update(vp, NULL, NULL, UPDATE_WAIT);
+ }
+ return (error);
+}
- error = ubc_uiomove(&vp->v_uobj, uio, bytelen, advice,
- UBC_READ | UBC_PARTIALOK | UBC_UNMAP_FLAG(vp));
- if (error)
- break;
- }
+/*
+ * UFS op for reading via the buffer cache
+ */
+int
+ext2fs_bufrd(struct vnode *vp, struct uio *uio, int ioflag, kauth_cred_t cred)
+{
+ struct inode *ip;
+ struct ufsmount *ump;
+ struct m_ext2fs *fs;
+ struct buf *bp;
+ off_t bytesinfile;
+ daddr_t lbn, nextlbn;
+ long size, xfersize, blkoffset;
+ int error;
+
+ KASSERT(uio->uio_rw == UIO_READ);
+ KASSERT(VOP_ISLOCKED(vp));
+ KASSERT(vp->v_type == VDIR || vp->v_type == VLNK);
+
+ ip = VTOI(vp);
+ ump = ip->i_ump;
+ fs = ip->i_e2fs;
+ error = 0;
+
+ KASSERT(vp->v_type != VLNK ||
+ ext2fs_size(ip) >= ump->um_maxsymlinklen);
+ KASSERT(vp->v_type != VLNK || ump->um_maxsymlinklen != 0 ||
+ ext2fs_nblock(ip) != 0);
+
+ if (uio->uio_offset > ump->um_maxfilesize)
+ return EFBIG;
+ if (uio->uio_resid == 0)
+ return 0;
+ if (uio->uio_offset >= ext2fs_size(ip))
goto out;
- }
for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) {
bytesinfile = ext2fs_size(ip) - uio->uio_offset;
@@ -196,7 +237,7 @@
out:
if (!(vp->v_mount->mnt_flag & MNT_NOATIME)) {
ip->i_flag |= IN_ACCESS;
- if ((ap->a_ioflag & IO_SYNC) == IO_SYNC)
+ if ((ioflag & IO_SYNC) == IO_SYNC)
error = ext2fs_update(vp, NULL, NULL, UPDATE_WAIT);
}
return (error);
@@ -218,11 +259,9 @@
struct uio *uio;
struct inode *ip;
struct m_ext2fs *fs;
- struct buf *bp;
struct ufsmount *ump;
- daddr_t lbn;
off_t osize;
- int blkoffset, error, flags, ioflag, resid, xfersize;
+ int blkoffset, error, ioflag, resid;
vsize_t bytelen;
off_t oldoff = 0; /* XXX */
bool async;
@@ -271,58 +310,124 @@
resid = uio->uio_resid;
osize = ext2fs_size(ip);
- if (vp->v_type == VREG) {
- while (uio->uio_resid > 0) {
- oldoff = uio->uio_offset;
- blkoffset = ext2_blkoff(fs, uio->uio_offset);
- bytelen = MIN(fs->e2fs_bsize - blkoffset,
- uio->uio_resid);
-
- if (vp->v_size < oldoff + bytelen) {
- uvm_vnp_setwritesize(vp, oldoff + bytelen);
- }
- error = ufs_balloc_range(vp, uio->uio_offset,
- bytelen, ap->a_cred, 0);
- if (error)
- break;
- error = ubc_uiomove(&vp->v_uobj, uio, bytelen, advice,
- UBC_WRITE | UBC_UNMAP_FLAG(vp));
- if (error)
- break;
+ KASSERT(vp->v_type == VREG);
+ while (uio->uio_resid > 0) {
+ oldoff = uio->uio_offset;
+ blkoffset = ext2_blkoff(fs, uio->uio_offset);
+ bytelen = MIN(fs->e2fs_bsize - blkoffset, uio->uio_resid);
- /*
- * update UVM's notion of the size now that we've
- * copied the data into the vnode's pages.
- */
-
- if (vp->v_size < uio->uio_offset) {
- uvm_vnp_setsize(vp, uio->uio_offset);
- extended = 1;
- }
+ if (vp->v_size < oldoff + bytelen) {
+ uvm_vnp_setwritesize(vp, oldoff + bytelen);
+ }
+ error = ufs_balloc_range(vp, uio->uio_offset, bytelen,
+ ap->a_cred, 0);
+ if (error)
+ break;
+ error = ubc_uiomove(&vp->v_uobj, uio, bytelen, advice,
+ UBC_WRITE | UBC_UNMAP_FLAG(vp));
+ if (error)
+ break;
- /*
- * flush what we just wrote if necessary.
- * XXXUBC simplistic async flushing.
- */
+ /*
+ * update UVM's notion of the size now that we've
+ * copied the data into the vnode's pages.
+ */
- if (!async && oldoff >> 16 != uio->uio_offset >> 16) {
- mutex_enter(vp->v_interlock);
- error = VOP_PUTPAGES(vp, (oldoff >> 16) << 16,
- (uio->uio_offset >> 16) << 16,
- PGO_CLEANIT | PGO_LAZY);
- }
- }
- if (error == 0 && ioflag & IO_SYNC) {
- mutex_enter(vp->v_interlock);
- error = VOP_PUTPAGES(vp, trunc_page(oldoff),
- round_page(ext2_blkroundup(fs, uio->uio_offset)),
Home |
Main Index |
Thread Index |
Old Index