Author: rmacklem
Date: Mon Jan  3 00:33:32 2011
New Revision: 216897
URL: http://svn.freebsd.org/changeset/base/216897

Log:
  Modify the experimental NFSv4 server so that the lookup
  ops return a locked vnode. This ensures that the associated mount
  point will always be valid for the code that follows the operation.
  Also add a couple of additional checks
  for non-error to the other functions that create file objects.
  
  MFC after:    2 weeks

Modified:
  head/sys/fs/nfsserver/nfs_nfsdserv.c
  head/sys/fs/nfsserver/nfs_nfsdsocket.c

Modified: head/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdserv.c        Mon Jan  3 00:11:10 2011        
(r216896)
+++ head/sys/fs/nfsserver/nfs_nfsdserv.c        Mon Jan  3 00:33:32 2011        
(r216897)
@@ -470,12 +470,10 @@ nfsrvd_lookup(struct nfsrv_descript *nd,
        nd->nd_repstat = nfsvno_getfh(vp, fhp, p);
        if (!(nd->nd_flag & ND_NFSV4) && !nd->nd_repstat)
                nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p, 1);
-       if (vpp) {
-               NFSVOPUNLOCK(vp, 0, p);
+       if (vpp != NULL && nd->nd_repstat == 0)
                *vpp = vp;
-       } else {
+       else
                vput(vp);
-       }
        if (dirp) {
                if (nd->nd_flag & ND_NFSV3)
                        dattr_ret = nfsvno_getattr(dirp, &dattr, nd->nd_cred,
@@ -1218,12 +1216,11 @@ nfsrvd_mknod(struct nfsrv_descript *nd, 
                if ((nd->nd_flag & ND_NFSV3) && !nd->nd_repstat)
                        nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred,
                            p, 1);
-               if (vpp) {
-                       NFSVOPUNLOCK(vp, 0, p);
+               if (vpp != NULL && nd->nd_repstat == 0) {
+                       VOP_UNLOCK(vp, 0);
                        *vpp = vp;
-               } else {
+               } else
                        vput(vp);
-               }
        }
 
        diraft_ret = nfsvno_getattr(dirp, &diraft, nd->nd_cred, p, 0);
@@ -1706,12 +1703,11 @@ nfsrvd_symlinksub(struct nfsrv_descript 
                                nd->nd_repstat = nfsvno_getattr(ndp->ni_vp,
                                    nvap, nd->nd_cred, p, 1);
                }
-               if (vpp) {
-                       NFSVOPUNLOCK(ndp->ni_vp, 0, p);
+               if (vpp != NULL && nd->nd_repstat == 0) {
+                       VOP_UNLOCK(ndp->ni_vp, 0);
                        *vpp = ndp->ni_vp;
-               } else {
+               } else
                        vput(ndp->ni_vp);
-               }
        }
        if (dirp) {
                *diraft_retp = nfsvno_getattr(dirp, diraftp, nd->nd_cred, p, 0);

Modified: head/sys/fs/nfsserver/nfs_nfsdsocket.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdsocket.c      Mon Jan  3 00:11:10 2011        
(r216896)
+++ head/sys/fs/nfsserver/nfs_nfsdsocket.c      Mon Jan  3 00:33:32 2011        
(r216897)
@@ -861,10 +861,14 @@ nfsrvd_compound(struct nfsrv_descript *n
                                            nfsvno_lockvfs(mp);
                                    }
                            }
+                           if (op == NFSV4OP_LOOKUP || op == NFSV4OP_LOOKUPP)
+                                   /* Lookup ops return a locked vnode */
+                                   VOP_UNLOCK(nvp, 0);
                            if (!nd->nd_repstat) {
                                    vrele(vp);
                                    vp = nvp;
-                           }
+                           } else
+                                   vrele(nvp);
                        }
                        if (nfsv4_opflag[op].modifyfs)
                                NFS_ENDWRITE(mp);
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to