From owner-freebsd-stable Wed Jan 3 23:54:38 2001 From owner-freebsd-stable@FreeBSD.ORG Wed Jan 3 23:54:34 2001 Return-Path: Delivered-To: freebsd-stable@freebsd.org Received: from earth.backplane.com (placeholder-dcat-1076843399.broadbandoffice.net [64.47.83.135]) by hub.freebsd.org (Postfix) with ESMTP id 5F6BB37B404 for ; Wed, 3 Jan 2001 23:54:34 -0800 (PST) Received: (from dillon@localhost) by earth.backplane.com (8.11.1/8.9.3) id f047sUW55674; Wed, 3 Jan 2001 23:54:30 -0800 (PST) (envelope-from dillon) Date: Wed, 3 Jan 2001 23:54:30 -0800 (PST) From: Matt Dillon Message-Id: <200101040754.f047sUW55674@earth.backplane.com> To: Marc Culler , freebsd-stable@FreeBSD.ORG Subject: NFSv3 O_EXCL file create - protocol spec & solution (was Re: Bug in NFSv3 client) References: <20010103155533.B71238@math.uic.edu> <200101032243.f03Mhar51440@earth.backplane.com> <200101032308.f03N84f51776@earth.backplane.com> <200101032322.f03NMTK51973@earth.backplane.com> Sender: owner-freebsd-stable@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG The RFC (1813) says that the exclusive-file-create NFS op passes a verifier. It says, and I quote: "One aspect of the NFS version 3 protocol CREATE procedure warrants particularly careful consideration: the mechanism introduced to support the reliable exclusive creation of regular files. The mechanism comes into play when how.mode is EXCLUSIVE. In this case, how.verf contains a verifier that can reasonably be expected to be unique. A combination of a client identifier, perhaps the client network address, and a unique number generated by the client, perhaps the RPC transaction identifier, may be appropriate." What that means is that the verifier can be anything. Here's why the FreeBSD server was storing the verifier as the file access time: "verifier must be stored in stable storage to prevent erroneous failure on retransmission of the request. It is assumed that an exclusive create is being performed because exclusive semantics are critical to the application. Because of the expected usage, exclusive CREATE does not rely solely on the normally volatile duplicate request cache for storage of the verifier. The duplicate request cache in volatile storage does not survive a crash and may actually flush on a long network partition, opening failure windows. In the UNIX local file system environment, the expected storage location for the verifier on creation is the metadata (time stamps) of the file. For this reason, an exclusive file create may not include initial attributes because the server would have nowhere to store the verifier." Ahhh, so now we know why FreeBSD is passing the IP address of the interface plus a 'unique' number! Or trying anyway. And also: "Once the client has performed a successful exclusive create, it must issue a SETATTR to set the correct file attributes. Until it does so, it should not rely upon any of the file attributes, since the server implementation may need to overload file metadata to store the verifier." What this means is that the FreeBSD client is supposed to call SETATTR to set the correct file attributes after the O_EXCL open succeeds. It is in fact doing this, but the 'atime' attribute in the 'vap' structure is not initialized, so the SETATTR call never actually fixes up the access time. Solaris probably shouldn't be generating an error for the 'bogus' time specification, as that can race with an O_EXCL create, but I think fixing the FreeBSD clients to do the proper SETATTR should solve the problem. I've included the patch below. The patch will fix FreeBSD clients. I will commit it to -current now and to -stable in two days if there aren't any problems. (Throw away any previous patches you might have applied). -Matt Index: nfs_vnops.c =================================================================== RCS file: /home/ncvs/src/sys/nfs/nfs_vnops.c,v retrieving revision 1.150 diff -u -r1.150 nfs_vnops.c --- nfs_vnops.c 2000/01/05 00:32:18 1.150 +++ nfs_vnops.c 2001/01/04 07:48:37 @@ -1436,8 +1436,21 @@ } if (newvp) vput(newvp); - } else if (v3 && (fmode & O_EXCL)) + } else if (v3 && (fmode & O_EXCL)) { + /* + * We are normally called with only a partially initialized + * VAP. Since the NFSv3 spec says that server may use the + * file attributes to store the verifier, the spec requires + * us to do a SETATTR RPC. FreeBSD servers store the verifier + * in atime, but we can't really assume that all servers will + * so we ensure that our SETATTR sets both atime and mtime. + */ + if (vap->va_mtime.tv_sec == VNOVAL) + vfs_timestamp(&vap->va_mtime); + if (vap->va_atime.tv_sec == VNOVAL) + vap->va_atime = vap->va_mtime; error = nfs_setattrrpc(newvp, vap, cnp->cn_cred, cnp->cn_proc); + } if (!error) { if (cnp->cn_flags & MAKEENTRY) cache_enter(dvp, newvp, cnp); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-stable" in the body of the message