From owner-freebsd-current Thu Dec 17 03:34:41 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id DAA11156 for freebsd-current-outgoing; Thu, 17 Dec 1998 03:34:41 -0800 (PST) (envelope-from owner-freebsd-current@FreeBSD.ORG) Received: from nlsystems.com (nlsys.demon.co.uk [158.152.125.33]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id DAA11147 for ; Thu, 17 Dec 1998 03:34:32 -0800 (PST) (envelope-from dfr@nlsystems.com) Received: from herring.nlsystems.com (herring.nlsystems.com [10.0.0.2]) by nlsystems.com (8.9.1/8.8.5) with SMTP id LAA63273; Thu, 17 Dec 1998 11:34:12 GMT Date: Thu, 17 Dec 1998 11:34:12 +0000 (GMT) From: Doug Rabson To: Mike Smith cc: Paul van der Zwan , current@FreeBSD.ORG Subject: Re: Weird NFS error using Solaris 7 server In-Reply-To: <199812162320.PAA01606@dingo.cdrom.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG On Wed, 16 Dec 1998, Mike Smith wrote: > > To test my theory that the -1 times are causing the error because they violate > > the protocol, I chanded the #define nfsm_v3sattr in /usr/src/sys/nfs/ > > nfsm_subs.h to use NFSV3SATTRTIME_TOSERVER in stead of NFSV3SATTRTIME_TOCLIENT. > > This makes the server ignore the time values. My test program now creates > > poth testfile1 and testfile2. > > This means that the files get the server's timestamp, which is going to > break things like make(1) which expect files to be created with the > client's time. > > > I might be wrong but I think the bug is in the client code and surfaced because > > Solaris 7 has become stricter about clients adhering to the protocol specs. > > This sounds like a good starting point; any chance of tracking down > where the time values are supposed to be set in the FreeBSD code and > fixing that, since that's what seems to be wrong...? I've been looking into this today. Its clear that we are doing the wrong thing for the attributes passed to CREATE, MKNOD and SYMLINK. I made some changes which I think should do the right thing but I can't test them against a Solaris server. One strange effect on a FreeBSD server (with or without this patch) is that the modtime of testfile1 is set to -1. I'll look into that later. Could someone test this patch and tell me if it improves things for Solaris? Index: nfs_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/nfs/nfs_vnops.c,v retrieving revision 1.114 diff -u -r1.114 nfs_vnops.c --- nfs_vnops.c 1998/11/15 20:36:16 1.114 +++ nfs_vnops.c 1998/12/17 10:17:37 @@ -718,64 +718,7 @@ nfsm_reqhead(vp, NFSPROC_SETATTR, NFSX_FH(v3) + NFSX_SATTR(v3)); nfsm_fhtom(vp, v3); if (v3) { - if (vap->va_mode != (mode_t)VNOVAL) { - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - *tl++ = nfs_true; - *tl = txdr_unsigned(vap->va_mode); - } else { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = nfs_false; - } - if (vap->va_uid != (uid_t)VNOVAL) { - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - *tl++ = nfs_true; - *tl = txdr_unsigned(vap->va_uid); - } else { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = nfs_false; - } - if (vap->va_gid != (gid_t)VNOVAL) { - nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - *tl++ = nfs_true; - *tl = txdr_unsigned(vap->va_gid); - } else { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = nfs_false; - } - if (vap->va_size != VNOVAL) { - nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); - *tl++ = nfs_true; - txdr_hyper(&vap->va_size, tl); - } else { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = nfs_false; - } - if (vap->va_atime.tv_sec != VNOVAL) { - if (vap->va_atime.tv_sec != time_second) { - nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); - *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); - txdr_nfsv3time(&vap->va_atime, tl); - } else { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); - } - } else { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); - } - if (vap->va_mtime.tv_sec != VNOVAL) { - if (vap->va_mtime.tv_sec != time_second) { - nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); - *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); - txdr_nfsv3time(&vap->va_mtime, tl); - } else { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); - } - } else { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); - } + nfsm_v3attrbuild(vap, TRUE); nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); *tl = nfs_false; } else { @@ -1261,7 +1204,6 @@ register struct vattr *vap; { register struct nfsv2_sattr *sp; - register struct nfsv3_sattr *sp3; register u_int32_t *tl; register caddr_t cp; register int32_t t1, t2; @@ -1293,10 +1235,9 @@ nfsm_fhtom(dvp, v3); nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); if (v3) { - nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_V3SRVSATTR); + nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); *tl++ = vtonfsv3_type(vap->va_type); - sp3 = (struct nfsv3_sattr *)tl; - nfsm_v3sattr(sp3, vap); + nfsm_v3attrbuild(vap, FALSE); if (vap->va_type == VCHR || vap->va_type == VBLK) { nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); *tl++ = txdr_unsigned(major(vap->va_rdev)); @@ -1383,7 +1324,6 @@ register struct vattr *vap = ap->a_vap; register struct componentname *cnp = ap->a_cnp; register struct nfsv2_sattr *sp; - register struct nfsv3_sattr *sp3; register u_int32_t *tl; register caddr_t cp; register int32_t t1, t2; @@ -1416,20 +1356,18 @@ if (v3) { nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); if (fmode & O_EXCL) { - *tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE); - nfsm_build(tl, u_int32_t *, NFSX_V3CREATEVERF); + *tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE); + nfsm_build(tl, u_int32_t *, NFSX_V3CREATEVERF); #ifdef INET - if (!TAILQ_EMPTY(&in_ifaddrhead)) - *tl++ = IA_SIN(in_ifaddrhead.tqh_first)->sin_addr.s_addr; - else + if (!TAILQ_EMPTY(&in_ifaddrhead)) + *tl++ = IA_SIN(in_ifaddrhead.tqh_first)->sin_addr.s_addr; + else #endif - *tl++ = create_verf; - *tl = ++create_verf; + *tl++ = create_verf; + *tl = ++create_verf; } else { - *tl = txdr_unsigned(NFSV3CREATE_UNCHECKED); - nfsm_build(tl, u_int32_t *, NFSX_V3SRVSATTR); - sp3 = (struct nfsv3_sattr *)tl; - nfsm_v3sattr(sp3, vap); + *tl = txdr_unsigned(NFSV3CREATE_UNCHECKED); + nfsm_v3attrbuild(vap, FALSE); } } else { nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR); @@ -1820,8 +1758,7 @@ nfsm_fhtom(dvp, v3); nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); if (v3) { - nfsm_build(sp3, struct nfsv3_sattr *, NFSX_V3SRVSATTR); - nfsm_v3sattr(sp3, vap); + nfsm_v3attrbuild(vap, FALSE); } nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN); if (!v3) { @@ -1895,8 +1832,7 @@ nfsm_fhtom(dvp, v3); nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); if (v3) { - nfsm_build(sp3, struct nfsv3_sattr *, NFSX_V3SRVSATTR); - nfsm_v3sattr(sp3, vap); + nfsm_v3attrbuild(vap, FALSE); } else { nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR); sp->sa_mode = vtonfsv2_mode(VDIR, vap->va_mode); Index: nfsm_subs.h =================================================================== RCS file: /home/ncvs/src/sys/nfs/nfsm_subs.h,v retrieving revision 1.21 diff -u -r1.21 nfsm_subs.h --- nfsm_subs.h 1998/05/31 20:08:57 1.21 +++ nfsm_subs.h 1998/12/17 11:23:50 @@ -235,17 +235,68 @@ (f) = ttattrf; \ } } -#define nfsm_v3sattr(s, a) \ - { (s)->sa_modetrue = nfs_true; \ - (s)->sa_mode = vtonfsv3_mode((a)->va_mode); \ - (s)->sa_uidfalse = nfs_false; \ - (s)->sa_gidfalse = nfs_false; \ - (s)->sa_sizefalse = nfs_false; \ - (s)->sa_atimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \ - txdr_nfsv3time(&(a)->va_atime, &(s)->sa_atime); \ - (s)->sa_mtimetype = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \ - txdr_nfsv3time(&(a)->va_mtime, &(s)->sa_mtime); \ +/* If full is true, set all fields, otherwise just set mode and time fields */ +#define nfsm_v3attrbuild(a, full) \ + { if ((a)->va_mode != (mode_t)VNOVAL) { \ + nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ + *tl++ = nfs_true; \ + *tl = txdr_unsigned((a)->va_mode); \ + } else { \ + nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ + *tl = nfs_false; \ + } \ + if ((full) && (a)->va_uid != (uid_t)VNOVAL) { \ + nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ + *tl++ = nfs_true; \ + *tl = txdr_unsigned((a)->va_uid); \ + } else { \ + nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ + *tl = nfs_false; \ + } \ + if ((full) && (a)->va_gid != (gid_t)VNOVAL) { \ + nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED); \ + *tl++ = nfs_true; \ + *tl = txdr_unsigned((a)->va_gid); \ + } else { \ + nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ + *tl = nfs_false; \ + } \ + if ((full) && (a)->va_size != VNOVAL) { \ + nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); \ + *tl++ = nfs_true; \ + txdr_hyper(&(a)->va_size, tl); \ + } else { \ + nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ + *tl = nfs_false; \ + } \ + if ((a)->va_atime.tv_sec != VNOVAL) { \ + if ((a)->va_atime.tv_sec != time_second) { \ + nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); \ + *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \ + txdr_nfsv3time(&(a)->va_atime, tl); \ + } else { \ + nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ + *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); \ + } \ + } else { \ + nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ + *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); \ + } \ + if ((a)->va_mtime.tv_sec != VNOVAL) { \ + if ((a)->va_mtime.tv_sec != time_second) { \ + nfsm_build(tl, u_int32_t *, 3 * NFSX_UNSIGNED); \ + *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT); \ + txdr_nfsv3time(&(a)->va_mtime, tl); \ + } else { \ + nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ + *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER); \ + } \ + } else { \ + nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED); \ + *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE); \ + } \ } + #define nfsm_strsiz(s,m) \ { nfsm_dissect(tl,u_int32_t *,NFSX_UNSIGNED); \ -- Doug Rabson Mail: dfr@nlsystems.com Nonlinear Systems Ltd. Phone: +44 181 442 9037 To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message