kern/178713: Correct WebNFS support in NFS server and client from sys/fs

Andrey Simonenko simon at comsys.ntu-kpi.kiev.ua
Fri May 17 11:20:04 UTC 2013


>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:


More information about the freebsd-bugs mailing list