Commit e143b1c8 authored by Trond Myklebust's avatar Trond Myklebust

NFSv2: In the NFSv3 RFC, the sattr3 structure passed in the SETATTR

   call allows for the client to request that the mtime and/or atime
   of an inode be set to the current server time, the given (client)
   time, or not changed.  The set-to-current-server value is used
   when you run "touch file" on the client.

The NFSv2 RFC defines no such encoding for the sattr structure. 
   However Solaris and Irix machine obey a convention where passing
   the invalid value mtime.useconds=1000000 means "set both mtime and
   atime to the current server time".  The convention is documented
   in the book "NFS Illustrated" by Brent Callaghan.  The patch below
   implements this convention for the Linux client and server (hence
   multiple To:s).
Signed-off-by: default avatarGreg Banks <gnb@sgi.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@fys.uio.no>
parent 9053c575
...@@ -92,6 +92,23 @@ xdr_encode_time(u32 *p, struct timespec *timep) ...@@ -92,6 +92,23 @@ xdr_encode_time(u32 *p, struct timespec *timep)
return p; return p;
} }
static inline u32*
xdr_encode_current_server_time(u32 *p, struct timespec *timep)
{
/*
* Passing the invalid value useconds=1000000 is a
* Sun convention for "set to current server time".
* It's needed to make permissions checks for the
* "touch" program across v2 mounts to Solaris and
* Irix boxes work correctly. See description of
* sattr in section 6.1 of "NFS Illustrated" by
* Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5
*/
*p++ = htonl(timep->tv_sec);
*p++ = htonl(1000000);
return p;
}
static inline u32* static inline u32*
xdr_decode_time(u32 *p, struct timespec *timep) xdr_decode_time(u32 *p, struct timespec *timep)
{ {
...@@ -140,15 +157,19 @@ xdr_encode_sattr(u32 *p, struct iattr *attr) ...@@ -140,15 +157,19 @@ xdr_encode_sattr(u32 *p, struct iattr *attr)
SATTR(p, attr, ATTR_GID, ia_gid); SATTR(p, attr, ATTR_GID, ia_gid);
SATTR(p, attr, ATTR_SIZE, ia_size); SATTR(p, attr, ATTR_SIZE, ia_size);
if (attr->ia_valid & (ATTR_ATIME|ATTR_ATIME_SET)) { if (attr->ia_valid & ATTR_ATIME_SET) {
p = xdr_encode_time(p, &attr->ia_atime); p = xdr_encode_time(p, &attr->ia_atime);
} else if (attr->ia_valid & ATTR_ATIME) {
p = xdr_encode_current_server_time(p, &attr->ia_atime);
} else { } else {
*p++ = ~(u32) 0; *p++ = ~(u32) 0;
*p++ = ~(u32) 0; *p++ = ~(u32) 0;
} }
if (attr->ia_valid & (ATTR_MTIME|ATTR_MTIME_SET)) { if (attr->ia_valid & ATTR_MTIME_SET) {
p = xdr_encode_time(p, &attr->ia_mtime); p = xdr_encode_time(p, &attr->ia_mtime);
} else if (attr->ia_valid & ATTR_MTIME) {
p = xdr_encode_current_server_time(p, &attr->ia_mtime);
} else { } else {
*p++ = ~(u32) 0; *p++ = ~(u32) 0;
*p++ = ~(u32) 0; *p++ = ~(u32) 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment