Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-7]: src/sys/fs/puffs Pull up following revision(s) (requested by ...



details:   https://anonhg.NetBSD.org/src/rev/004642542ae1
branches:  netbsd-7
changeset: 798510:004642542ae1
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Sun Nov 09 10:07:31 2014 +0000

description:
Pull up following revision(s) (requested by manu in ticket #193):
        sys/fs/puffs/puffs_vnops.c: revision 1.198
PUFFS direct I/O cache fix
There are a few situations where we must take care of the cache if
direct
I/O was enabled:
- if we do direct I/O for write but not for read, then any write must
  invalidate the cache so that a reader gets the written data and not
  the not-updated cache.
- if we used a vnode without direct I/O and it is enabled for writing,
  we must flush the cache before compeling the open operation, so that
  the cachec write are not lost.
And at inactive time, we wipe direct I/O flags so that a new open
without
direct I/O does not inherit direct I/O.

diffstat:

 sys/fs/puffs/puffs_vnops.c |  48 ++++++++++++++++++++++++++++++++++++---------
 1 files changed, 38 insertions(+), 10 deletions(-)

diffs (95 lines):

diff -r b48d714f4227 -r 004642542ae1 sys/fs/puffs/puffs_vnops.c
--- a/sys/fs/puffs/puffs_vnops.c        Sun Nov 09 10:06:34 2014 +0000
+++ b/sys/fs/puffs/puffs_vnops.c        Sun Nov 09 10:07:31 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: puffs_vnops.c,v 1.182.2.9 2014/11/05 18:16:17 snj Exp $        */
+/*     $NetBSD: puffs_vnops.c,v 1.182.2.10 2014/11/09 10:07:31 msaitoh Exp $   */
 
 /*
  * Copyright (c) 2005, 2006, 2007  Antti Kantee.  All Rights Reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.182.2.9 2014/11/05 18:16:17 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.182.2.10 2014/11/09 10:07:31 msaitoh Exp $");
 
 #include <sys/param.h>
 #include <sys/buf.h>
@@ -908,6 +908,12 @@
        error = checkerr(pmp, error, __func__);
 
        if (open_msg->pvnr_oflags & PUFFS_OPEN_IO_DIRECT) {
+               /*
+                * Flush cache:
+                * - we do not want to discard cached write by direct write
+                * - read cache is now useless and should be freed
+                */
+               flushvncache(vp, 0, 0, true);
                if (mode & FREAD)
                        pn->pn_stat |= PNODE_RDIRECT;
                if (mode & FWRITE)
@@ -1404,6 +1410,11 @@
                }
        }
 
+       /*
+        * Wipe direct I/O flags
+        */
+       pnode->pn_stat &= ~(PNODE_RDIRECT|PNODE_WDIRECT);
+
        *ap->a_recycle = recycle;
 
        mutex_exit(&pnode->pn_sizemtx);
@@ -2369,19 +2380,20 @@
 
        mutex_enter(&pn->pn_sizemtx);
 
+       /*
+        * userspace *should* be allowed to control this,
+        * but with UBC it's a bit unclear how to handle it
+        */
+       if (ap->a_ioflag & IO_APPEND)
+               uio->uio_offset = vp->v_size;
+
+       origoff = uio->uio_offset;
+
        if (vp->v_type == VREG && 
            PUFFS_USE_PAGECACHE(pmp) &&
            !(pn->pn_stat & PNODE_WDIRECT)) {
                ubcflags = UBC_WRITE | UBC_PARTIALOK | UBC_UNMAP_FLAG(vp);
 
-               /*
-                * userspace *should* be allowed to control this,
-                * but with UBC it's a bit unclear how to handle it
-                */
-               if (ap->a_ioflag & IO_APPEND)
-                       uio->uio_offset = vp->v_size;
-
-               origoff = uio->uio_offset;
                while (uio->uio_resid > 0) {
                        oldoff = uio->uio_offset;
                        bytelen = uio->uio_resid;
@@ -2488,6 +2500,22 @@
                        }
                }
                puffs_msgmem_release(park_write);
+
+               /*
+                * Direct I/O on write but not on read: we must
+                * invlidate the written pages so that we read
+                * the written data and not the stalled cache.
+                */
+               if ((error == 0) && 
+                   (vp->v_type == VREG) && PUFFS_USE_PAGECACHE(pmp) &&
+                   (pn->pn_stat & PNODE_WDIRECT) &&
+                   !(pn->pn_stat & PNODE_RDIRECT)) {
+                       voff_t off_lo = trunc_page(origoff);
+                       voff_t off_hi = round_page(uio->uio_offset);
+
+                       mutex_enter(vp->v_uobj.vmobjlock);
+                       error = VOP_PUTPAGES(vp, off_lo, off_hi, PGO_FREE);
+               }
        }
 
        if (vp->v_mount->mnt_flag & MNT_RELATIME)



Home | Main Index | Thread Index | Old Index