Subject: Re: genfs_putpages with PGO_SYNCIO
To: None <enami@sm.sony.co.jp>
From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
List: tech-kern
Date: 01/14/2003 21:19:42
--NextPart-20030114211253-0037801
Content-Type: Text/Plain; charset=us-ascii

> > I think there was some interaction with NFS related to this.
> > I don't remember for sure, though.
> 
> Yes, with current nfs implementation, simply changing not to pass
> PGO_SYNCIO will makes nfs code not to use stable write.

i see, thanks.

then, how about attached patch?
- introduce B_STABLE so that nfs doesn't have to (ab)use B_ASYNC to determine
  if stable write is needed or not.
- always do async i/o for GOP_WRITE.

YAMAMOTO Takashi

--NextPart-20030114211253-0037801
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="genfs.syncio2.diff"

Index: sys/buf.h
===================================================================
RCS file: /cvs/NetBSD/src/sys/sys/buf.h,v
retrieving revision 1.55
diff -u -p -r1.55 buf.h
--- sys/buf.h	2002/10/06 17:05:56	1.55
+++ sys/buf.h	2003/01/14 12:12:45
@@ -217,6 +217,7 @@ struct buf {
 #define	B_WRITE		0x00000000	/* Write buffer (pseudo flag). */
 #define	B_XXX		0x02000000	/* Debugging flag. */
 #define	B_VFLUSH	0x04000000	/* Buffer is being synced. */
+#define	B_STABLE	0x08000000	/* Data should go to stable storage */
 
 /*
  * This structure describes a clustered I/O.  It is stored in the b_saveaddr
Index: miscfs/genfs/genfs_vnops.c
===================================================================
RCS file: /cvs/NetBSD/src/sys/miscfs/genfs/genfs_vnops.c,v
retrieving revision 1.68
diff -u -p -r1.68 genfs_vnops.c
--- miscfs/genfs/genfs_vnops.c	2002/11/15 14:01:57	1.68
+++ miscfs/genfs/genfs_vnops.c	2003/01/14 12:12:45
@@ -1359,7 +1359,6 @@ genfs_gop_write(struct vnode *vp, struct
 	struct vm_page *pg;
 	struct buf *mbp, *bp;
 	struct vnode *devvp;
-	boolean_t async = (flags & PGO_SYNCIO) == 0;
 	UVMHIST_FUNC("genfs_gop_write"); UVMHIST_CALLED(ubchist);
 
 	UVMHIST_LOG(ubchist, "vp %p pgs %p npages %d flags 0x%x",
@@ -1392,7 +1391,7 @@ genfs_gop_write(struct vnode *vp, struct
 	mbp->b_bufsize = npages << PAGE_SHIFT;
 	mbp->b_data = (void *)kva;
 	mbp->b_resid = mbp->b_bcount = bytes;
-	mbp->b_flags = B_BUSY|B_WRITE|B_AGE| (async ? (B_CALL|B_ASYNC) : 0);
+	mbp->b_flags = B_BUSY|B_WRITE|B_AGE|B_CALL|B_ASYNC;
 	mbp->b_iodone = uvm_aio_biodone;
 	mbp->b_vp = vp;
 	LIST_INIT(&mbp->b_dep);
@@ -1444,6 +1443,9 @@ genfs_gop_write(struct vnode *vp, struct
 		/* adjust physical blkno for partial blocks */
 		bp->b_blkno = blkno + ((offset - ((off_t)lbn << fs_bshift)) >>
 		    dev_bshift);
+		if (flags & PGO_SYNCIO) {
+			bp->b_flags |= B_STABLE;
+		}
 		UVMHIST_LOG(ubchist,
 		    "vp %p offset 0x%x bcount 0x%x blkno 0x%x",
 		    vp, offset, bp->b_bcount, bp->b_blkno);
@@ -1461,16 +1463,13 @@ genfs_gop_write(struct vnode *vp, struct
 			biodone(mbp);
 		}
 		splx(s);
-	}
-	if (async) {
-		UVMHIST_LOG(ubchist, "returning 0 (async)", 0,0,0,0);
-		return (0);
 	}
-	UVMHIST_LOG(ubchist, "waiting for mbp %p", mbp,0,0,0);
-	error = biowait(mbp);
-	uvm_aio_aiodone(mbp);
-	UVMHIST_LOG(ubchist, "returning, error %d", error,0,0,0);
-	return (error);
+	/*
+	 * We don't have to wait for I/O completions even for PGO_SYNCIO
+	 * because genfs_putpages will wait for us.
+	 */
+	UVMHIST_LOG(ubchist, "returning 0", 0,0,0,0);
+	return (0);
 }
 
 /*
Index: nfs/nfs_bio.c
===================================================================
RCS file: /cvs/NetBSD/src/sys/nfs/nfs_bio.c,v
retrieving revision 1.85
diff -u -p -r1.85 nfs_bio.c
--- nfs/nfs_bio.c	2002/10/29 10:15:16	1.85
+++ nfs/nfs_bio.c	2003/01/14 12:12:45
@@ -989,7 +989,7 @@ nfs_doio(bp, p)
 	    struct vm_page *pgs[npages];
 	    boolean_t needcommit = TRUE;
 
-	    if ((bp->b_flags & B_ASYNC) != 0 && NFS_ISV3(vp)) {
+	    if ((bp->b_flags & B_STABLE) == 0 && NFS_ISV3(vp)) {
 		    iomode = NFSV3WRITE_UNSTABLE;
 	    } else {
 		    iomode = NFSV3WRITE_FILESYNC;

--NextPart-20030114211253-0037801--