>Number:         178713
>Category:       kern
>Synopsis:       Correct WebNFS support in NFS server and client from sys/fs
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri May 17 11:20:02 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     Andrey Simonenko
>Release:        FreeBSD 10-CURRENT amd64
>Organization:
>Environment:
>Description:

The following change corrects WebNFS support in NFS server and client
from the sys/fs/ sources:

1. fs/nfs/nfs_commonsubs.c:nfsm_fhtom(): do not assume size argument
   with the zero value as default size value.  All nfsm_fhtom() calls
   with size argument with the zero value were modified and now have
   the NFSX_MYFH value.

2. fs/nfsserver/nfs_nfsdsubs.c:nfsrv_mtofh(): allow public filehandle
   to be used for all requests, not only for LOOKUPs.

3. fs/nfsclient/nfs_clvfsops.c:mountnfs(): allow filehandle with
   the zero length for NFSv3.

Index files are not supported by NFS server from sys/fs/nfsserver/
and adding such support will require API change.

>How-To-Repeat:

Add WebNFS support to mount_nfs from bin/178392 and try to mount
WebNFS exported file system.

>Fix:
diff -ruNp sys.orig/fs/nfs/nfs_commonsubs.c sys/fs/nfs/nfs_commonsubs.c
--- sys.orig/fs/nfs/nfs_commonsubs.c    2013-04-18 12:17:41.000000000 +0300
+++ sys/fs/nfs/nfs_commonsubs.c 2013-05-17 12:36:11.000000000 +0300
@@ -463,7 +463,6 @@ newnfs_init(void)
 
 /*
  * Put a file handle in an mbuf list.
- * If the size argument == 0, just use the default size.
  * set_true == 1 if there should be an newnfs_true prepended on the file 
handle.
  * Return the number of bytes output, including XDR overhead.
  */
@@ -474,8 +473,6 @@ nfsm_fhtom(struct nfsrv_descript *nd, u_
        u_int8_t *cp;
        int fullsiz, rem, bytesize = 0;
 
-       if (size == 0)
-               size = NFSX_MYFH;
        switch (nd->nd_flag & (ND_NFSV2 | ND_NFSV3 | ND_NFSV4)) {
        case ND_NFSV2:
                if (size > NFSX_V2FH)
@@ -2189,7 +2186,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd
                        retnum += NFSX_UNSIGNED;
                        break;
                case NFSATTRBIT_FILEHANDLE:
-                       retnum += nfsm_fhtom(nd, (u_int8_t *)fhp, 0, 0);
+                       retnum += nfsm_fhtom(nd, (u_int8_t *)fhp, NFSX_MYFH, 0);
                        break;
                case NFSATTRBIT_FILEID:
                        NFSM_BUILD(tl, u_int32_t *, NFSX_HYPER);
diff -ruNp sys.orig/fs/nfsclient/nfs_clvfsops.c sys/fs/nfsclient/nfs_clvfsops.c
--- sys.orig/fs/nfsclient/nfs_clvfsops.c        2013-04-19 11:36:03.000000000 
+0300
+++ sys/fs/nfsclient/nfs_clvfsops.c     2013-05-17 12:35:02.000000000 +0300
@@ -1374,7 +1374,7 @@ mountnfs(struct nfs_args *argp, struct m
         * this problem, because one can identify root inodes by their
         * number == ROOTINO (2).
         */
-       if (nmp->nm_fhsize > 0) {
+       if (nmp->nm_fhsize > 0 || (nmp->nm_flag & NFSMNT_NFSV3)) {
                /*
                 * Set f_iosize to NFS_DIRBLKSIZ so that bo_bsize gets set
                 * non-zero for the root vnode. f_iosize will be set correctly
diff -ruNp sys.orig/fs/nfsserver/nfs_nfsdport.c sys/fs/nfsserver/nfs_nfsdport.c
--- sys.orig/fs/nfsserver/nfs_nfsdport.c        2013-04-18 12:17:41.000000000 
+0300
+++ sys/fs/nfsserver/nfs_nfsdport.c     2013-05-17 12:36:41.000000000 +0300
@@ -2147,7 +2147,8 @@ again:
                                *tl++ = 0;
                                *tl = txdr_unsigned(*cookiep);
                                nfsrv_postopattr(nd, 0, nvap);
-                               dirlen += nfsm_fhtom(nd,(u_int8_t *)&nfh,0,1);
+                               dirlen += nfsm_fhtom(nd,(u_int8_t *)&nfh,
+                                   NFSX_MYFH, 1);
                                dirlen += (5*NFSX_UNSIGNED+NFSX_V3POSTOPATTR);
                                if (nvp != NULL)
                                        vput(nvp);
diff -ruNp sys.orig/fs/nfsserver/nfs_nfsdserv.c sys/fs/nfsserver/nfs_nfsdserv.c
--- sys.orig/fs/nfsserver/nfs_nfsdserv.c        2013-01-19 13:56:24.000000000 
+0200
+++ sys/fs/nfsserver/nfs_nfsdserv.c     2013-05-17 12:37:37.000000000 +0300
@@ -561,10 +561,10 @@ nfsrvd_lookup(struct nfsrv_descript *nd,
                goto out;
        }
        if (nd->nd_flag & ND_NFSV2) {
-               (void) nfsm_fhtom(nd, (u_int8_t *)fhp, 0, 0);
+               (void) nfsm_fhtom(nd, (u_int8_t *)fhp, NFSX_MYFH, 0);
                nfsrv_fillattr(nd, &nva);
        } else if (nd->nd_flag & ND_NFSV3) {
-               (void) nfsm_fhtom(nd, (u_int8_t *)fhp, 0, 0);
+               (void) nfsm_fhtom(nd, (u_int8_t *)fhp, NFSX_MYFH, 0);
                nfsrv_postopattr(nd, 0, &nva);
                nfsrv_postopattr(nd, dattr_ret, &dattr);
        }
@@ -1092,7 +1092,7 @@ nfsrvd_create(struct nfsrv_descript *nd,
        }
        if (nd->nd_flag & ND_NFSV2) {
                if (!nd->nd_repstat) {
-                       (void) nfsm_fhtom(nd, (u_int8_t *)&fh, 0, 0);
+                       (void) nfsm_fhtom(nd, (u_int8_t *)&fh, NFSX_MYFH, 0);
                        nfsrv_fillattr(nd, &nva);
                }
        } else {
@@ -1102,7 +1102,7 @@ nfsrvd_create(struct nfsrv_descript *nd,
                diraft_ret = nfsvno_getattr(dirp, &diraft, nd->nd_cred, p, 0);
                vrele(dirp);
                if (!nd->nd_repstat) {
-                       (void) nfsm_fhtom(nd, (u_int8_t *)&fh, 0, 1);
+                       (void) nfsm_fhtom(nd, (u_int8_t *)&fh, NFSX_MYFH, 1);
                        nfsrv_postopattr(nd, 0, &nva);
                }
                nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, &diraft);
@@ -1302,7 +1302,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, 
        vrele(dirp);
        if (!nd->nd_repstat) {
                if (nd->nd_flag & ND_NFSV3) {
-                       (void) nfsm_fhtom(nd, (u_int8_t *)fhp, 0, 1);
+                       (void) nfsm_fhtom(nd, (u_int8_t *)fhp, NFSX_MYFH, 1);
                        nfsrv_postopattr(nd, 0, &nva);
                } else {
                        NFSM_BUILD(tl, u_int32_t *, 5 * NFSX_UNSIGNED);
@@ -1749,7 +1749,7 @@ nfsrvd_symlink(struct nfsrv_descript *nd
 
        if (nd->nd_flag & ND_NFSV3) {
                if (!nd->nd_repstat) {
-                       (void) nfsm_fhtom(nd, (u_int8_t *)fhp, 0, 1);
+                       (void) nfsm_fhtom(nd, (u_int8_t *)fhp, NFSX_MYFH, 1);
                        nfsrv_postopattr(nd, 0, &nva);
                }
                nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, &diraft);
@@ -1874,12 +1874,12 @@ nfsrvd_mkdir(struct nfsrv_descript *nd, 
 
        if (nd->nd_flag & ND_NFSV3) {
                if (!nd->nd_repstat) {
-                       (void) nfsm_fhtom(nd, (u_int8_t *)fhp, 0, 1);
+                       (void) nfsm_fhtom(nd, (u_int8_t *)fhp, NFSX_MYFH, 1);
                        nfsrv_postopattr(nd, 0, &nva);
                }
                nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, &diraft);
        } else if (!nd->nd_repstat) {
-               (void) nfsm_fhtom(nd, (u_int8_t *)fhp, 0, 0);
+               (void) nfsm_fhtom(nd, (u_int8_t *)fhp, NFSX_MYFH, 0);
                nfsrv_fillattr(nd, &nva);
        }
 
@@ -2998,7 +2998,7 @@ nfsrvd_getfh(struct nfsrv_descript *nd, 
        nd->nd_repstat = nfsvno_getfh(vp, &fh, p);
        vput(vp);
        if (!nd->nd_repstat)
-               (void) nfsm_fhtom(nd, (u_int8_t *)&fh, 0, 0);
+               (void) nfsm_fhtom(nd, (u_int8_t *)&fh, NFSX_MYFH, 0);
        NFSEXITCODE2(0, nd);
        return (0);
 }
diff -ruNp sys.orig/fs/nfsserver/nfs_nfsdsubs.c sys/fs/nfsserver/nfs_nfsdsubs.c
--- sys.orig/fs/nfsserver/nfs_nfsdsubs.c        2012-11-19 14:37:37.000000000 
+0200
+++ sys/fs/nfsserver/nfs_nfsdsubs.c     2013-05-17 12:41:12.000000000 +0300
@@ -1422,8 +1422,7 @@ nfsrv_mtofh(struct nfsrv_descript *nd, s
        if (nd->nd_flag & (ND_NFSV3 | ND_NFSV4)) {
                NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED);
                len = fxdr_unsigned(int, *tl);
-               if (len == 0 && nfs_pubfhset && (nd->nd_flag & ND_NFSV3) &&
-                   nd->nd_procnum == NFSPROC_LOOKUP) {
+               if (len == 0 && nfs_pubfhset && (nd->nd_flag & ND_NFSV3)) {
                        nd->nd_flag |= ND_PUBLOOKUP;
                        goto nfsmout;
                }
@@ -1456,7 +1455,6 @@ nfsrv_mtofh(struct nfsrv_descript *nd, s
        }
        NFSM_DISSECT(tl, u_int32_t *, len);
        if ((nd->nd_flag & ND_NFSV2) && nfs_pubfhset &&
-           nd->nd_procnum == NFSPROC_LOOKUP &&
            !NFSBCMP((caddr_t)tl, nfs_v2pubfh, NFSX_V2FH)) {
                nd->nd_flag |= ND_PUBLOOKUP;
                goto nfsmout;
>Release-Note:
>Audit-Trail:
>Unformatted:
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "[email protected]"

Reply via email to