summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2009-11-20 21:21:13 +0000
committerrmacklem <rmacklem@FreeBSD.org>2009-11-20 21:21:13 +0000
commit483d9d96d0940b7f9eaeaeaaeec623809a34c436 (patch)
treeccc33c540c4280a4a4cf32e06f3e944aa501dce7 /sys/fs
parent2d93b6e4248fe243a13bad6aae36aed5e0d576f6 (diff)
downloadFreeBSD-src-483d9d96d0940b7f9eaeaeaaeec623809a34c436.zip
FreeBSD-src-483d9d96d0940b7f9eaeaeaaeec623809a34c436.tar.gz
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
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/nfs/nfs_var.h4
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c13
-rw-r--r--sys/fs/nfsserver/nfs_nfsdserv.c31
3 files changed, 29 insertions, 19 deletions
diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h
index 2556e35..72e65c7 100644
--- a/sys/fs/nfs/nfs_var.h
+++ b/sys/fs/nfs/nfs_var.h
@@ -529,7 +529,7 @@ int nfsvno_read(vnode_t, off_t, int, struct ucred *, NFSPROC_T *,
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, struct ucred *, NFSPROC_T *);
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 *,
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index 0cebc21..1e87523 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -720,7 +720,7 @@ nfsvno_write(struct vnode *vp, off_t off, int retlen, int cnt, int stable,
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 *nd, struct nameidata *ndp,
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 statfs *sf)
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, struct nameidata *ndp,
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 {
diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c
index 668c7fb..c0ac41d 100644
--- a/sys/fs/nfsserver/nfs_nfsdserv.c
+++ b/sys/fs/nfsserver/nfs_nfsdserv.c
@@ -865,11 +865,11 @@ nfsrvd_create(struct nfsrv_descript *nd, __unused int isdgram,
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, __unused int isdgram,
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, __unused int isdgram,
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, __unused int isdgram,
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, __unused int isdgram,
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, __unused int isdgram,
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, __unused int isdgram,
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.
OpenPOWER on IntegriCloud