From gnb@sgi.com Fri May 28 12:10:55 2004 Return-Path: Received: from mail-imap3.uio.no ([unix socket]) by mail-imap3.uio.no (Cyrus v2.1.11) with LMTP; Fri, 28 May 2004 12:10:55 +0200 X-Sieve: CMU Sieve 2.2 Delivery-date: Fri, 28 May 2004 12:10:55 +0200 Received: from mail-mx2.uio.no ([129.240.10.30]) by mail-imap3.uio.no with esmtp (Exim 4.34) id 1BTeKE-0005rs-R9 for trond.myklebust@fys.uio.no; Fri, 28 May 2004 12:10:54 +0200 Received: from mtvcafw.sgi.com ([192.48.171.6] helo=omx2.sgi.com) by smtp.uio.no with esmtp (Exim 4.34) id 1BTeKD-000772-41 for trond.myklebust@fys.uio.no; Fri, 28 May 2004 12:10:53 +0200 Received: from larry.melbourne.sgi.com (larry.melbourne.sgi.com [134.14.52.130]) by omx2.sgi.com (8.12.11/8.12.9/linux-outbound_gateway-1.1) with SMTP id i4SAGKGD003195; Fri, 28 May 2004 03:16:21 -0700 Received: from speed.melbourne.sgi.com (speed.melbourne.sgi.com [134.14.55.174]) by larry.melbourne.sgi.com (950413.SGI.8.6.12/950213.SGI.AUTOCF) via ESMTP id UAA18569; Fri, 28 May 2004 20:10:49 +1000 Received: by speed.melbourne.sgi.com (Postfix, from userid 16345) id 2218857980; Fri, 28 May 2004 20:10:49 +1000 (EST) Date: Fri, 28 May 2004 20:10:49 +1000 From: Greg Banks To: Trond Myklebust Cc: Linux NFS Mailing List Subject: [PATCH 2.6] SGI 901086: NFSv2 SETATTR current server time support Message-ID: <20040528101049.GF9014@sgi.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.3.27i X-MailScanner-Information: This message has been scanned for viruses/spam. Contact postmaster@uio.no if you have questions about this scanning X-UiO-MailScanner: No virus found X-UiO-Spam-info: not spam, SpamAssassin (score=0, required 12) X-Evolution-Source: imap://trondmy@imap.uio.no/ Content-Transfer-Encoding: 8bit G'day, This is the 2.6 version of the client side NFSv2 SETATTR current server time patch. This is the first send. SGI bug 901086. 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. This is significant for two reasons. First, if there is clock skew between the client and server there are times when you want the server time. Secondly, the filesystem permissions checks for the two cases are actually different: setting to an explicit time requires the setting process to own the file (or be root), but setting to the current time requires only that the file be writable to the process (or the process be root). 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). Tested between ia64 Linux 2.6.4 Irix & Solaris. --- linux.orig/fs/nfs/nfs2xdr.c Fri May 28 18:20:02 2004 +++ linux/fs/nfs/nfs2xdr.c Fri May 28 19:36:48 2004 @@ -95,6 +95,23 @@ } 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) { timep->tv_sec = ntohl(*p++); @@ -142,15 +159,19 @@ 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; Greg. -- Greg Banks, R&D Software Engineer, SGI Australian Software Group. I don't speak for SGI.