From e143b1c817e8403679a39253194cd5b176cfcd53 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 23 Aug 2004 10:18:16 -0400 Subject: [PATCH] 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: Greg Banks Signed-off-by: Trond Myklebust --- fs/nfs/nfs2xdr.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index aa62e01b97e5..d69d2f2d5aa9 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -92,6 +92,23 @@ xdr_encode_time(u32 *p, struct timespec *timep) 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* xdr_decode_time(u32 *p, struct timespec *timep) { @@ -140,15 +157,19 @@ xdr_encode_sattr(u32 *p, struct iattr *attr) SATTR(p, attr, ATTR_GID, ia_gid); 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); + } else if (attr->ia_valid & ATTR_ATIME) { + p = xdr_encode_current_server_time(p, &attr->ia_atime); } else { *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); + } else if (attr->ia_valid & ATTR_MTIME) { + p = xdr_encode_current_server_time(p, &attr->ia_mtime); } else { *p++ = ~(u32) 0; *p++ = ~(u32) 0; -- 2.39.5