svn commit: r199616 - in head/sys/fs: nfs nfsserver

Rick Macklem rmacklem at FreeBSD.org
Fri Nov 20 21:21:13 UTC 2009


Author: rmacklem
Date: Fri Nov 20 21:21:13 2009
New Revision: 199616
URL: http://svn.freebsd.org/changeset/base/199616

Log:
  Patch the experimental NFS server is a manner analagous to
  r197525, so that the creation verifier is handled correctly
  in va_atime for 64bit architectures. There were two problems.
  One was that the code incorrectly assumed that
  sizeof (struct timespec) == 8 and the other was that the tv_sec
  field needs to be assigned from a signed 32bit integer, so that
  sign extension occurs on 64bit architectures. This is required
  for correct operation when exporting ZFS volumes.
  
  Reviewed by:	pjd
  MFC after:	2 weeks

Modified:
  head/sys/fs/nfs/nfs_var.h
  head/sys/fs/nfsserver/nfs_nfsdport.c
  head/sys/fs/nfsserver/nfs_nfsdserv.c

Modified: head/sys/fs/nfs/nfs_var.h
==============================================================================
--- head/sys/fs/nfs/nfs_var.h	Fri Nov 20 21:12:40 2009	(r199615)
+++ head/sys/fs/nfs/nfs_var.h	Fri Nov 20 21:21:13 2009	(r199616)
@@ -529,7 +529,7 @@ int nfsvno_read(vnode_t, off_t, int, str
 int nfsvno_write(vnode_t, off_t, int, int, int, mbuf_t,
     char *, struct ucred *, NFSPROC_T *);
 int nfsvno_createsub(struct nfsrv_descript *, struct nameidata *,
-    vnode_t *, struct nfsvattr *, int *, u_char *, NFSDEV_T, NFSPROC_T *,
+    vnode_t *, struct nfsvattr *, int *, int32_t *, NFSDEV_T, NFSPROC_T *,
     struct nfsexstuff *);
 int nfsvno_mknod(struct nameidata *, struct nfsvattr *, struct ucred *,
     NFSPROC_T *);
@@ -552,7 +552,7 @@ int nfsvno_fsync(vnode_t, u_int64_t, int
 int nfsvno_statfs(vnode_t, struct statfs *);
 void nfsvno_getfs(struct nfsfsinfo *, int);
 void nfsvno_open(struct nfsrv_descript *, struct nameidata *, nfsquad_t,
-    nfsv4stateid_t *, struct nfsstate *, int *, struct nfsvattr *, u_char *,
+    nfsv4stateid_t *, struct nfsstate *, int *, struct nfsvattr *, int32_t *,
     int, NFSACL_T *, nfsattrbit_t *, struct ucred *, NFSPROC_T *,
     struct nfsexstuff *, vnode_t *);
 void nfsvno_updfilerev(vnode_t, struct nfsvattr *, struct ucred *,

Modified: head/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdport.c	Fri Nov 20 21:12:40 2009	(r199615)
+++ head/sys/fs/nfsserver/nfs_nfsdport.c	Fri Nov 20 21:21:13 2009	(r199616)
@@ -720,7 +720,7 @@ nfsvno_write(struct vnode *vp, off_t off
 int
 nfsvno_createsub(struct nfsrv_descript *nd, struct nameidata *ndp,
     struct vnode **vpp, struct nfsvattr *nvap, int *exclusive_flagp,
-    u_char *cverf, NFSDEV_T rdev, struct thread *p, struct nfsexstuff *exp)
+    int32_t *cverf, NFSDEV_T rdev, struct thread *p, struct nfsexstuff *exp)
 {
 	u_quad_t tempsize;
 	int error;
@@ -737,8 +737,8 @@ nfsvno_createsub(struct nfsrv_descript *
 				if (*exclusive_flagp) {
 					*exclusive_flagp = 0;
 					NFSVNO_ATTRINIT(nvap);
-					NFSBCOPY(cverf,(caddr_t)&nvap->na_atime,
-					    NFSX_VERF);
+					nvap->na_atime.tv_sec = cverf[0];
+					nvap->na_atime.tv_nsec = cverf[1];
 					error = VOP_SETATTR(ndp->ni_vp,
 					    &nvap->na_vattr, nd->nd_cred);
 				}
@@ -1285,7 +1285,7 @@ nfsvno_statfs(struct vnode *vp, struct s
 void
 nfsvno_open(struct nfsrv_descript *nd, struct nameidata *ndp,
     nfsquad_t clientid, nfsv4stateid_t *stateidp, struct nfsstate *stp,
-    int *exclusive_flagp, struct nfsvattr *nvap, u_char *cverf, int create,
+    int *exclusive_flagp, struct nfsvattr *nvap, int32_t *cverf, int create,
     NFSACL_T *aclp, nfsattrbit_t *attrbitp, struct ucred *cred, struct thread *p,
     struct nfsexstuff *exp, struct vnode **vpp)
 {
@@ -1307,9 +1307,8 @@ nfsvno_open(struct nfsrv_descript *nd, s
 				if (*exclusive_flagp) {
 					*exclusive_flagp = 0;
 					NFSVNO_ATTRINIT(nvap);
-					NFSBCOPY(cverf,
-					    (caddr_t)&nvap->na_atime,
-					    NFSX_VERF);
+					nvap->na_atime.tv_sec = cverf[0];
+					nvap->na_atime.tv_nsec = cverf[1];
 					nd->nd_repstat = VOP_SETATTR(ndp->ni_vp,
 					    &nvap->na_vattr, cred);
 				} else {

Modified: head/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdserv.c	Fri Nov 20 21:12:40 2009	(r199615)
+++ head/sys/fs/nfsserver/nfs_nfsdserv.c	Fri Nov 20 21:21:13 2009	(r199616)
@@ -865,11 +865,11 @@ nfsrvd_create(struct nfsrv_descript *nd,
 	int how = NFSCREATE_UNCHECKED, exclusive_flag = 0;
 	NFSDEV_T rdev = 0;
 	vnode_t vp = NULL, dirp = NULL;
-	u_char cverf[NFSX_VERF], *cp;
 	fhandle_t fh;
 	char *bufp;
 	u_long *hashp;
 	enum vtype vtyp;
+	int32_t cverf[2], tverf[2] = { 0, 0 };
 
 	if (nd->nd_repstat) {
 		nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, &diraft);
@@ -920,8 +920,9 @@ nfsrvd_create(struct nfsrv_descript *nd,
 					goto nfsmout;
 				break;
 			case NFSCREATE_EXCLUSIVE:
-				NFSM_DISSECT(cp, u_char *, NFSX_VERF);
-				NFSBCOPY(cp, cverf, NFSX_VERF);
+				NFSM_DISSECT(tl, u_int32_t *, NFSX_VERF);
+				cverf[0] = *tl++;
+				cverf[1] = *tl;
 				exclusive_flag = 1;
 				break;
 			};
@@ -988,6 +989,10 @@ nfsrvd_create(struct nfsrv_descript *nd,
 			nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred,
 			    p);
 		vput(vp);
+		if (!nd->nd_repstat) {
+			tverf[0] = nva.na_atime.tv_sec;
+			tverf[1] = nva.na_atime.tv_nsec;
+		}
 	}
 	if (nd->nd_flag & ND_NFSV2) {
 		if (!nd->nd_repstat) {
@@ -995,8 +1000,8 @@ nfsrvd_create(struct nfsrv_descript *nd,
 			nfsrv_fillattr(nd, &nva);
 		}
 	} else {
-		if (exclusive_flag && !nd->nd_repstat &&
-			NFSBCMP(cverf, (caddr_t)&nva.na_atime, NFSX_VERF))
+		if (exclusive_flag && !nd->nd_repstat && (cverf[0] != tverf[0]
+		    || cverf[1] != tverf[1]))
 			nd->nd_repstat = EEXIST;
 		diraft_ret = nfsvno_getattr(dirp, &diraft, nd->nd_cred, p);
 		vrele(dirp);
@@ -2406,7 +2411,7 @@ nfsrvd_open(struct nfsrv_descript *nd, _
 	int error = 0, create, claim, exclusive_flag = 0;
 	u_int32_t rflags = NFSV4OPEN_LOCKTYPEPOSIX, acemask;
 	int how = NFSCREATE_UNCHECKED;
-	u_char cverf[NFSX_VERF];
+	int32_t cverf[2], tverf[2] = { 0, 0 };
 	vnode_t vp = NULL, dirp = NULL;
 	struct nfsvattr nva, dirfor, diraft;
 	struct nameidata named;
@@ -2517,7 +2522,8 @@ nfsrvd_open(struct nfsrv_descript *nd, _
 			break;
 		case NFSCREATE_EXCLUSIVE:
 			NFSM_DISSECT(tl, u_int32_t *, NFSX_VERF);
-			NFSBCOPY((caddr_t)tl, cverf, NFSX_VERF);
+			cverf[0] = *tl++;
+			cverf[1] = *tl;
 			break;
 		default:
 			nd->nd_repstat = NFSERR_BADXDR;
@@ -2677,10 +2683,15 @@ nfsrvd_open(struct nfsrv_descript *nd, _
 		    NFSACCCHK_VPISLOCKED);
 	}
 
-	if (!nd->nd_repstat)
+	if (!nd->nd_repstat) {
 		nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p);
-	if (!nd->nd_repstat && exclusive_flag &&
-	    NFSBCMP(cverf, (caddr_t)&nva.na_atime, NFSX_VERF))
+		if (!nd->nd_repstat) {
+			tverf[0] = nva.na_atime.tv_sec;
+			tverf[1] = nva.na_atime.tv_nsec;
+		}
+	}
+	if (!nd->nd_repstat && exclusive_flag && (cverf[0] != tverf[0] ||
+	    cverf[1] != tverf[1]))
 		nd->nd_repstat = EEXIST;
 	/*
 	 * Do the open locking/delegation stuff.


More information about the svn-src-all mailing list