Author: pjd
Date: Tue Dec 21 23:12:45 2010
New Revision: 216632
URL: http://svn.freebsd.org/changeset/base/216632

Log:
  - Move pubflag and lockflag handling from nfsrv_fhtovp() to nfs_namei() -
    this is the only place that is different from all the other nfsrv_fhtovp()
    consumers.
    This simplifies nfsrv_fhtovp() a bit and also eliminates one
    vn_lock/VOP_UNLOCK() cycle in case of NFSv3.
  - Implement NFSRV_FLAG_BUSY flag for nfsrv_fhtovp() that tells it to leave
    mount point busy.
  
  Reviewed by:  kib
  MFC after:    5 days

Modified:
  head/sys/nfsserver/nfs.h
  head/sys/nfsserver/nfs_serv.c
  head/sys/nfsserver/nfs_srvsubs.c

Modified: head/sys/nfsserver/nfs.h
==============================================================================
--- head/sys/nfsserver/nfs.h    Tue Dec 21 23:04:04 2010        (r216631)
+++ head/sys/nfsserver/nfs.h    Tue Dec 21 23:12:45 2010        (r216632)
@@ -239,6 +239,12 @@ extern int nfs_debug;
 
 #endif
 
+/*
+ * The following flags can be passed to nfsrv_fhtovp() function.
+ */
+/* Leave file system busy on success. */
+#define        NFSRV_FLAG_BUSY         0x01
+
 struct mbuf *nfs_rephead(int, struct nfsrv_descript *, int, struct mbuf **,
            caddr_t *);
 void   nfsm_srvfattr(struct nfsrv_descript *, struct vattr *,
@@ -264,7 +270,7 @@ int nfsrv_create(struct nfsrv_descript *
            struct mbuf **mrq);
 int    nfsrv_fhtovp(fhandle_t *, int, struct vnode **, int *,
            struct nfsrv_descript *, struct nfssvc_sock *, struct sockaddr *,
-           int *, int);
+           int *);
 int    nfsrv_setpublicfs(struct mount *, struct netexport *,
            struct export_args *);
 int    nfs_ispublicfh(fhandle_t *);

Modified: head/sys/nfsserver/nfs_serv.c
==============================================================================
--- head/sys/nfsserver/nfs_serv.c       Tue Dec 21 23:04:04 2010        
(r216631)
+++ head/sys/nfsserver/nfs_serv.c       Tue Dec 21 23:12:45 2010        
(r216632)
@@ -213,8 +213,7 @@ nfsrv3_access(struct nfsrv_descript *nfs
        fhp = &nfh.fh_generic;
        nfsm_srvmtofh(fhp);
        tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
-       error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
-           nam, &rdonly, TRUE);
+       error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
        if (error) {
                nfsm_reply(NFSX_UNSIGNED);
                nfsm_srvpostop_attr(1, NULL);
@@ -280,8 +279,7 @@ nfsrv_getattr(struct nfsrv_descript *nfs
        vfslocked = 0;
        fhp = &nfh.fh_generic;
        nfsm_srvmtofh(fhp);
-       error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp, nam,
-           &rdonly, TRUE);
+       error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
        if (error) {
                nfsm_reply(0);
                error = 0;
@@ -389,8 +387,7 @@ nfsrv_setattr(struct nfsrv_descript *nfs
        /*
         * Now that we have all the fields, lets do it.
         */
-       error = nfsrv_fhtovp(fhp, 1, &vp, &tvfslocked, nfsd, slp,
-           nam, &rdonly, TRUE);
+       error = nfsrv_fhtovp(fhp, 0, &vp, &tvfslocked, nfsd, slp, nam, &rdonly);
        vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
        if (error) {
                nfsm_reply(2 * NFSX_UNSIGNED);
@@ -712,8 +709,7 @@ nfsrv_readlink(struct nfsrv_descript *nf
        uiop->uio_rw = UIO_READ;
        uiop->uio_segflg = UIO_SYSSPACE;
        uiop->uio_td = NULL;
-       error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
-           nam, &rdonly, TRUE);
+       error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
        if (error) {
                nfsm_reply(2 * NFSX_UNSIGNED);
                if (v3)
@@ -808,8 +804,7 @@ nfsrv_read(struct nfsrv_descript *nfsd, 
         * as well.
         */
 
-       error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
-           nam, &rdonly, TRUE);
+       error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
        if (error) {
                vp = NULL;
                nfsm_reply(2 * NFSX_UNSIGNED);
@@ -1109,8 +1104,7 @@ nfsrv_write(struct nfsrv_descript *nfsd,
                error = 0;
                goto nfsmout;
        }
-       error = nfsrv_fhtovp(fhp, 1, &vp, &tvfslocked, nfsd, slp,
-           nam, &rdonly, TRUE);
+       error = nfsrv_fhtovp(fhp, 0, &vp, &tvfslocked, nfsd, slp, nam, &rdonly);
        vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
        if (error) {
                vp = NULL;
@@ -2102,8 +2096,7 @@ nfsrv_link(struct nfsrv_descript *nfsd, 
        nfsm_srvmtofh(dfhp);
        nfsm_srvnamesiz(len);
 
-       error = nfsrv_fhtovp(fhp, TRUE, &vp, &tvfslocked, nfsd, slp,
-           nam, &rdonly, TRUE);
+       error = nfsrv_fhtovp(fhp, 0, &vp, &tvfslocked, nfsd, slp, nam, &rdonly);
        vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
        if (error) {
                nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
@@ -2770,8 +2763,7 @@ nfsrv_readdir(struct nfsrv_descript *nfs
        if (siz > xfer)
                siz = xfer;
        fullsiz = siz;
-       error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
-           nam, &rdonly, TRUE);
+       error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
        if (!error && vp->v_type != VDIR) {
                error = ENOTDIR;
                vput(vp);
@@ -3066,7 +3058,7 @@ nfsrv_readdirplus(struct nfsrv_descript 
        if (siz > xfer)
                siz = xfer;
        fullsiz = siz;
-       error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
+       error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp,
            nam, &rdonly, TRUE);
        vp_locked = 1;
        if (!error && vp->v_type != VDIR) {
@@ -3375,6 +3367,8 @@ invalid:
 nfsmout:
        if (vp)
                vrele(vp);
+       if (mntp)
+               vfs_unbusy(mntp);
        VFS_UNLOCK_GIANT(vfslocked);
        return(error);
 }
@@ -3426,8 +3420,7 @@ nfsrv_commit(struct nfsrv_descript *nfsd
        off = fxdr_hyper(tl);
        tl += 2;
        cnt = fxdr_unsigned(int, *tl);
-       error = nfsrv_fhtovp(fhp, 1, &vp, &tvfslocked, nfsd, slp,
-           nam, &rdonly, TRUE);
+       error = nfsrv_fhtovp(fhp, 0, &vp, &tvfslocked, nfsd, slp, nam, &rdonly);
        vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
        if (error) {
                nfsm_reply(2 * NFSX_UNSIGNED);
@@ -3571,8 +3564,7 @@ nfsrv_statfs(struct nfsrv_descript *nfsd
        vfslocked = 0;
        fhp = &nfh.fh_generic;
        nfsm_srvmtofh(fhp);
-       error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
-           nam, &rdonly, TRUE);
+       error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
        if (error) {
                nfsm_reply(NFSX_UNSIGNED);
                if (v3)
@@ -3666,8 +3658,7 @@ nfsrv_fsinfo(struct nfsrv_descript *nfsd
        fhp = &nfh.fh_generic;
        vfslocked = 0;
        nfsm_srvmtofh(fhp);
-       error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
-           nam, &rdonly, TRUE);
+       error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
        if (error) {
                nfsm_reply(NFSX_UNSIGNED);
                nfsm_srvpostop_attr(getret, &at);
@@ -3741,8 +3732,7 @@ nfsrv_pathconf(struct nfsrv_descript *nf
        vfslocked = 0;
        fhp = &nfh.fh_generic;
        nfsm_srvmtofh(fhp);
-       error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, nfsd, slp,
-           nam, &rdonly, TRUE);
+       error = nfsrv_fhtovp(fhp, 0, &vp, &vfslocked, nfsd, slp, nam, &rdonly);
        if (error) {
                nfsm_reply(NFSX_UNSIGNED);
                nfsm_srvpostop_attr(getret, &at);

Modified: head/sys/nfsserver/nfs_srvsubs.c
==============================================================================
--- head/sys/nfsserver/nfs_srvsubs.c    Tue Dec 21 23:04:04 2010        
(r216631)
+++ head/sys/nfsserver/nfs_srvsubs.c    Tue Dec 21 23:12:45 2010        
(r216632)
@@ -639,16 +639,18 @@ nfs_namei(struct nameidata *ndp, struct 
                        goto out;
        }
 
+       if (!pubflag && nfs_ispublicfh(fhp))
+               return (ESTALE);
+
        /*
         * Extract and set starting directory.
         */
-       error = nfsrv_fhtovp(fhp, FALSE, &dp, &dvfslocked,
-           nfsd, slp, nam, &rdonly, pubflag);
+       error = nfsrv_fhtovp(fhp, 0, &dp, &dvfslocked, nfsd, slp, nam, &rdonly);
        if (error)
                goto out;
        vfslocked = VFS_LOCK_GIANT(dp->v_mount);
        if (dp->v_type != VDIR) {
-               vrele(dp);
+               vput(dp);
                error = ENOTDIR;
                goto out;
        }
@@ -662,12 +664,12 @@ nfs_namei(struct nameidata *ndp, struct 
         */
        *retdirp = dp;
        if (v3) {
-               vn_lock(dp, LK_EXCLUSIVE | LK_RETRY);
                *retdirattr_retp = VOP_GETATTR(dp, retdirattrp,
                        ndp->ni_cnd.cn_cred);
-               VOP_UNLOCK(dp, 0);
        }
 
+       VOP_UNLOCK(dp, 0);
+
        if (pubflag) {
                /*
                 * Oh joy. For WebNFS, handle those pesky '%' escapes,
@@ -1051,12 +1053,11 @@ nfsm_srvfattr(struct nfsrv_descript *nfs
  *     - look up fsid in mount list (if not found ret error)
  *     - get vp and export rights by calling VFS_FHTOVP()
  *     - if cred->cr_uid == 0 or MNT_EXPORTANON set it to credanon
- *     - if not lockflag unlock it with VOP_UNLOCK()
  */
 int
-nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, int *vfslockedp,
+nfsrv_fhtovp(fhandle_t *fhp, int flags, struct vnode **vpp, int *vfslockedp,
     struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
-    struct sockaddr *nam, int *rdonlyp, int pubflag)
+    struct sockaddr *nam, int *rdonlyp)
 {
        struct mount *mp;
        int i;
@@ -1076,7 +1077,7 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockfla
        *vpp = NULL;
 
        if (nfs_ispublicfh(fhp)) {
-               if (!pubflag || !nfs_pub.np_valid)
+               if (!nfs_pub.np_valid)
                        return (ESTALE);
                fhp = &nfs_pub.np_handle;
        }
@@ -1128,12 +1129,12 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockfla
                }
        }
        error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp);
-       if (error != 0)
+       if (error) {
                /* Make sure the server replies ESTALE to the client. */
                error = ESTALE;
-       vfs_unbusy(mp);
-       if (error)
+               vfs_unbusy(mp);
                goto out;
+       }
 #ifdef MNT_EXNORESPORT
        if (!(exflags & (MNT_EXNORESPORT|MNT_EXPUBLIC))) {
                saddr = (struct sockaddr_in *)nam;
@@ -1162,8 +1163,8 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockfla
        else
                *rdonlyp = 0;
 
-       if (!lockflag)
-               VOP_UNLOCK(*vpp, 0);
+       if (!(flags & NFSRV_FLAG_BUSY))
+               vfs_unbusy(mp);
 out:
        if (credanon != NULL)
                crfree(credanon);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to