Source-Changes-HG archive

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

[src/trunk]: src/sys/nfs make sure that if NMODIFIED is clear, all pages atta...



details:   https://anonhg.NetBSD.org/src/rev/31184438da39
branches:  trunk
changeset: 523832:31184438da39
user:      chs <chs%NetBSD.org@localhost>
date:      Sat Mar 16 23:05:25 2002 +0000

description:
make sure that if NMODIFIED is clear, all pages attached to the vnode are
clean and without writable mappings.  if we try to flush dirty pages past
EOF to the server when NMODIFIED is clear, we'll update the attrcache before
doing the write, which will try to free the pages past EOF and deadlock.
to deal with this, we write-protect pages before we send them to the server,
and restrict ourselves to creating read-only mappings if NMODIFIED isn't set.
score another one for enami.

diffstat:

 sys/nfs/nfs_bio.c  |  47 +++++++++++++++++++++++++++++++++++++++--------
 sys/nfs/nfs_node.c |  18 +++++++++++++++---
 2 files changed, 54 insertions(+), 11 deletions(-)

diffs (131 lines):

diff -r 232a89fab8c7 -r 31184438da39 sys/nfs/nfs_bio.c
--- a/sys/nfs/nfs_bio.c Sat Mar 16 22:44:41 2002 +0000
+++ b/sys/nfs/nfs_bio.c Sat Mar 16 23:05:25 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nfs_bio.c,v 1.75 2002/01/31 05:56:57 chs Exp $ */
+/*     $NetBSD: nfs_bio.c,v 1.76 2002/03/16 23:05:25 chs Exp $ */
 
 /*
  * Copyright (c) 1989, 1993
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_bio.c,v 1.75 2002/01/31 05:56:57 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_bio.c,v 1.76 2002/03/16 23:05:25 chs Exp $");
 
 #include "opt_nfs.h"
 #include "opt_ddb.h"
@@ -1132,7 +1132,34 @@
 
        npages = *ap->a_count;
        error = genfs_getpages(v);
-       if (error || !write || !v3) {
+       if (error) {
+               return error;
+       }
+
+       /*
+        * for read faults where the nfs node is not yet marked NMODIFIED,
+        * set PG_RDONLY on the pages so that we come back here if someone
+        * tries to modify later via the mapping that will be entered for
+        * this fault.
+        */
+
+       pgs = ap->a_m;
+       if (!write && (np->n_flag & NMODIFIED) == 0 && pgs != NULL) {
+               if (!locked) {
+                       simple_lock(&uobj->vmobjlock);
+               }
+               for (i = 0; i < npages; i++) {
+                       pg = pgs[i];
+                       if (pg == NULL || pg == PGO_DONTCARE) {
+                               continue;
+                       }
+                       pg->flags |= PG_RDONLY;
+               }
+               if (!locked) {
+                       simple_unlock(&uobj->vmobjlock);
+               }
+       }
+       if (!write) {
                return error;
        }
 
@@ -1140,13 +1167,15 @@
         * this is a write fault, update the commit info.
         */
 
-       pgs = ap->a_m;
        origoffset = ap->a_offset;
        len = npages << PAGE_SHIFT;
 
-       lockmgr(&np->n_commitlock, LK_EXCLUSIVE, NULL);
-       nfs_del_committed_range(vp, origoffset, len);
-       nfs_del_tobecommitted_range(vp, origoffset, len);
+       np->n_flag |= NMODIFIED;
+       if (v3) {
+               lockmgr(&np->n_commitlock, LK_EXCLUSIVE, NULL);
+               nfs_del_committed_range(vp, origoffset, len);
+               nfs_del_tobecommitted_range(vp, origoffset, len);
+       }
        if (!locked) {
                simple_lock(&uobj->vmobjlock);
        }
@@ -1160,6 +1189,8 @@
        if (!locked) {
                simple_unlock(&uobj->vmobjlock);
        }
-       lockmgr(&np->n_commitlock, LK_RELEASE, NULL);
+       if (v3) {
+               lockmgr(&np->n_commitlock, LK_RELEASE, NULL);
+       }
        return 0;
 }
diff -r 232a89fab8c7 -r 31184438da39 sys/nfs/nfs_node.c
--- a/sys/nfs/nfs_node.c        Sat Mar 16 22:44:41 2002 +0000
+++ b/sys/nfs/nfs_node.c        Sat Mar 16 23:05:25 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nfs_node.c,v 1.52 2002/03/08 20:48:45 thorpej Exp $    */
+/*     $NetBSD: nfs_node.c,v 1.53 2002/03/16 23:05:25 chs Exp $        */
 
 /*
  * Copyright (c) 1989, 1993
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_node.c,v 1.52 2002/03/08 20:48:45 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_node.c,v 1.53 2002/03/16 23:05:25 chs Exp $");
 
 #include "opt_nfs.h"
 
@@ -79,11 +79,12 @@
 
 void nfs_gop_size(struct vnode *, off_t, off_t *);
 int nfs_gop_alloc(struct vnode *, off_t, off_t, int, struct ucred *);
+int nfs_gop_write(struct vnode *, struct vm_page **, int, int);
 
 struct genfs_ops nfs_genfsops = {
        nfs_gop_size,
        nfs_gop_alloc,
-       genfs_gop_write,
+       nfs_gop_write,
 };
 
 /*
@@ -323,3 +324,14 @@
 {
        return 0;
 }
+
+int
+nfs_gop_write(struct vnode *vp, struct vm_page **pgs, int npages, int flags)
+{
+       int i;
+
+       for (i = 0; i < npages; i++) {
+               pmap_page_protect(pgs[i], VM_PROT_READ);
+       }
+       return genfs_gop_write(vp, pgs, npages, flags);
+}



Home | Main Index | Thread Index | Old Index