Source-Changes-HG archive

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

[src/netbsd-1-4]: src/sys/nfs Pull up revision 1.108 (via patch, requested by...



details:   https://anonhg.NetBSD.org/src/rev/8e00bcd962c9
branches:  netbsd-1-4
changeset: 469968:8e00bcd962c9
user:      he <he%NetBSD.org@localhost>
date:      Wed Jan 05 23:39:50 2000 +0000

description:
Pull up revision 1.108 (via patch, requested by fvdl):
  Insert an extra VOP_ACCESS check in nfs_lookup, preventing cached
  access mishaps for lookup and getattr.  Fixes PR#8884.

diffstat:

 sys/nfs/nfs_vnops.c |  51 +++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 43 insertions(+), 8 deletions(-)

diffs (103 lines):

diff -r 4d2b24abc2f6 -r 8e00bcd962c9 sys/nfs/nfs_vnops.c
--- a/sys/nfs/nfs_vnops.c       Wed Jan 05 23:39:14 2000 +0000
+++ b/sys/nfs/nfs_vnops.c       Wed Jan 05 23:39:50 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nfs_vnops.c,v 1.100.2.1 1999/06/22 17:10:39 perry Exp $        */
+/*     $NetBSD: nfs_vnops.c,v 1.100.2.2 2000/01/05 23:39:50 he Exp $   */
 
 /*
  * Copyright (c) 1989, 1993
@@ -298,10 +298,22 @@
        register caddr_t cp;
        register int32_t t1, t2;
        caddr_t bpos, dpos, cp2;
-       int error = 0, attrflag;
+       int error = 0, attrflag, cachevalid;
        struct mbuf *mreq, *mrep, *md, *mb, *mb2;
        u_int32_t mode, rmode;
        int v3 = NFS_ISV3(vp);
+       struct nfsnode *np = VTONFS(vp);
+
+       cachevalid = (np->n_accstamp != -1 &&
+           (time.tv_sec - np->n_accstamp) < NFS_ATTRTIMEO(np) &&
+           np->n_accuid == ap->a_cred->cr_uid);
+
+       /*
+        * Check access cache first. If this request has been made for this
+        * uid shortly before, use the cached result.
+        */
+       if (cachevalid && ((np->n_accmode & ap->a_mode) == ap->a_mode))
+               return np->n_accerror;
 
        /*
         * For nfs v3, do an access rpc, otherwise you are stuck emulating
@@ -347,8 +359,6 @@
                                error = EACCES;
                }
                nfsm_reqdone;
-               if (error)
-                       return (error);
        } else
                return (nfsspec_access(ap));
        /*
@@ -356,17 +366,35 @@
         * unless the file is a socket, fifo, or a block or character
         * device resident on the filesystem.
         */
-       if ((ap->a_mode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
+       if (!error && (ap->a_mode & VWRITE) &&
+           (vp->v_mount->mnt_flag & MNT_RDONLY)) {
                switch (vp->v_type) {
                case VREG:
                case VDIR:
                case VLNK:
-                       return (EROFS);
+                       error = EROFS;
                default:
                        break;
                }
        }
-       return (0);
+
+       if (!error || error == EACCES) {
+               /*
+                * If we got the same result as for a previous,
+                * different request, OR it in. Don't update
+                * the timestamp in that case.
+                */
+               if (cachevalid && error == np->n_accerror)
+                       np->n_accmode |= ap->a_mode;
+               else {
+                       np->n_accstamp = time.tv_sec;
+                       np->n_accuid = ap->a_cred->cr_uid;
+                       np->n_accmode = ap->a_mode;
+                       np->n_accerror = error;
+               }
+       }
+
+       return (error);
 }
 
 /*
@@ -743,13 +771,20 @@
                return (EROFS);
        if (dvp->v_type != VDIR)
                return (ENOTDIR);
+
        lockparent = flags & LOCKPARENT;
        wantparent = flags & (LOCKPARENT|WANTPARENT);
        nmp = VFSTONFS(dvp->v_mount);
        np = VTONFS(dvp);
        if ((error = cache_lookup(dvp, vpp, cnp)) != 0) {
                struct vattr vattr;
-               int vpid;
+               int vpid, err2;
+
+               err2 = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, cnp->cn_proc);
+               if (err2) {
+                       *vpp = NULLVP;
+                       return (err2);
+               }
 
                if (error == ENOENT) {
                        if (!VOP_GETATTR(dvp, &vattr, cnp->cn_cred,



Home | Main Index | Thread Index | Old Index