Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Dec 2014 09:34:01 -0500 (EST)
From:      Rick Macklem <rmacklem@uoguelph.ca>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        FreeBSD Filesystems <freebsd-fs@freebsd.org>, Christian Corti <corti@informatik.uni-stuttgart.de>, Jason Naughton <jnaughto@ee.ryerson.ca>
Subject:   Re: RFC: new NFS mount option to work around Solaris server bug
Message-ID:  <364990673.2236008.1419518041925.JavaMail.root@uoguelph.ca>
In-Reply-To: <20141225101604.GC1754@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
Kostik wrote:
> On Wed, Dec 24, 2014 at 06:14:58PM -0500, Rick Macklem wrote:
> > Hi,
> > 
> > https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=193128
> > 
> > This bug report discusses a bug in the Solaris NFS server
> > that is tickled by the way FreeBSD currently does exclusive
> > open in the NFS client.
> > FreeBSD sets both the mtime to the time of the client and
> > also the file's mode using a Setattr RPC done after an
> > exclusive create of the file in an exclusive open.
> > 
> > Jason (jnaughto@ee.ryerson.ca) was able to figure out that
> > the server bug can be avoided if the mtime is set to the
> > server's time (xxx_TOSERVER option in the Setattr RPC request).
> > 
> > I'd like to propose a new mount option that forces the
> > FreeBSD client to use xxx_TOSERVER for setting times,
> > mostly to be used as a work around for this Solaris server bug.
> > 1 - Does doing this make sense to others?
> > 2 - If the answer to one is "Yes", then what do you think
> >     the option should be called?
> >     useservertime
> >     useservtm
> >     ust
> >     OR ??
> 
> What are drawbacks of unconditionally using the workaround ?
> 
Interesting question. I took a look at the history of this and
the story is kinda interesting (and a little long, I'm afraid).
If you don't want to read the story, there is a summary statement
at the end, which is the important part.

First off, there is this rather weird comment in the NFS client
(which has been around for ages and the new client inherited it
from the old one):
1664   /*
1665 	* We are normally called with only a partially initialized
1666 	* VAP. Since the NFSv3 spec says that server may use the
1667 	* file attributes to store the verifier, the spec requires
1668 	* us to do a SETATTR RPC. FreeBSD servers store the verifier
1669 	* in atime, but we can't really assume that all servers will
1670 	* so we ensure that our SETATTR sets both atime and mtime.
1671 	*/
Now, I'm not sure why the client did this, although my guess is that
it was a workaround for a broken server. If you are interested, here's
a clip from RFC-1813 that describes that the creation verifier must
be on stable storage. (I would expect servers to do this, so the client
shouldn't need to set it, but...)
      If the file does not exist, the server creates the file
      and stores the verifier in stable storage. For file
      systems that do not provide a mechanism for the storage of
      arbitrary file attributes, the server may use one or more
      elements of the file metadata to store the verifier. The
      verifier must be stored in stable storage to prevent
      erroneous failure on retransmission of the request.

The code after the above comment sets both va_atime and va_mtime to
the current filesystem timestamp.

Now, prior to r245508 in head (r247502 in stable/9 for the old client),
the NFS client code did:
    if (vap->va_mtime.tv_sec != time_second)
        - use xx_TOCLIENT and specify the time
    else
        - use xx_TOSERVER
--> So, for FreeBSD9.0 and earlier, the NFS client would normally
    specify xxx_TOSERVER. (There was probably a very slight chance the
    clock would tick to the next second and generate xx_TOCLIENT.)

r245508 changed this to:
    if ((vap->va_aflags & VA_NULL_UTIMES) == 0)
        - use xx_TOCLIENT
    else
        - use xx_TOSERVER
I think this was to fix setutimes() and deal with higher than 1sec
vfs timestamp resolutions.
--> As such, more recent NFS clients have been sending xx_TOCLIENT.

Summary:
Maybe the best fix for this is just to have the NFS
client exclusive create set VA_NULL_UTIMES when setting the times,
so it will again use xx_TOSERVER for this case?
In other words, I think the code should use VA_UTIMES_NULL for
setutimes() etc, but maybe it should just always use xx_TOSERVER
for the exclusive create, since that is what happened up until
around FreeBSD9.0. (This would avoid yet another mount option, yippee.)

I'll take a look at the FreeBSD server, to see how it stores the
create verifier these days, but I have no idea what all the other
NFS servers out there do.

Thanks for the good question Kostik, rick




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?364990673.2236008.1419518041925.JavaMail.root>