
From: NeilBrown <neilb@cse.unsw.edu.au>



---

 25-akpm/fs/nfsd/nfs4xdr.c         |   31 +++++++------------------------
 25-akpm/include/linux/nfsd/xdr4.h |   16 ++++++++--------
 2 files changed, 15 insertions(+), 32 deletions(-)

diff -puN fs/nfsd/nfs4xdr.c~knfsd-changeinfo-time-higher-resolution fs/nfsd/nfs4xdr.c
--- 25/fs/nfsd/nfs4xdr.c~knfsd-changeinfo-time-higher-resolution	Mon Feb 23 16:33:44 2004
+++ 25-akpm/fs/nfsd/nfs4xdr.c	Mon Feb 23 16:33:44 2004
@@ -1183,10 +1183,10 @@ nfsd4_decode_compound(struct nfsd4_compo
 } while (0)
 #define WRITECINFO(c)		do {				\
 	*p++ = htonl(c.atomic);					\
-	*p++ = htonl(c.before_size);				\
-	*p++ = htonl(c.before_ctime);				\
-	*p++ = htonl(c.after_size);				\
-	*p++ = htonl(c.after_ctime);				\
+	*p++ = htonl(c.before_ctime_sec);				\
+	*p++ = htonl(c.before_ctime_nsec);				\
+	*p++ = htonl(c.after_ctime_sec);				\
+	*p++ = htonl(c.after_ctime_nsec);				\
 } while (0)
 
 #define RESERVE_SPACE(nbytes)	do {				\
@@ -1326,32 +1326,15 @@ nfsd4_encode_fattr(struct svc_fh *fhp, s
 	}
 	if (bmval0 & FATTR4_WORD0_CHANGE) {
 		/*
-		 * XXX: We currently use the inode ctime as the nfsv4 "changeid"
-		 * attribute.  This violates the spec, which says
-		 *
-		 *    The server may return the object's time_modify attribute
-		 *    for this attribute, but only if the file system object
-		 *    can not be updated more frequently than the resolution
-		 *    of time_modify.
-		 *
-		 * Since we only have 1-second ctime resolution, this is a pretty
-		 * serious violation.  Indeed, 1-second ctime resolution is known
-		 * to be a problem in practice in the NFSv3 world.
-		 *
-		 * The real solution to this problem is probably to work on
-		 * adding high-resolution mtimes to the VFS layer.
-		 *
-		 * Note: Started using i_size for the high 32 bits of the changeid.
-		 *
-		 * Note 2: This _must_ be consistent with the scheme for writing
+		 * Note: This _must_ be consistent with the scheme for writing
 		 * change_info, so any changes made here must be reflected there
 		 * as well.  (See xdr4.h:set_change_info() and the WRITECINFO()
 		 * macro above.)
 		 */
 		if ((buflen -= 8) < 0)
 			goto out_resource;
-		WRITE32(stat.size);
-		WRITE32(stat.mtime.tv_sec); /* AK: nsec dropped? */
+		WRITE32(stat.ctime.tv_sec);
+		WRITE32(stat.ctime.tv_nsec);
 	}
 	if (bmval0 & FATTR4_WORD0_SIZE) {
 		if ((buflen -= 8) < 0)
diff -puN include/linux/nfsd/xdr4.h~knfsd-changeinfo-time-higher-resolution include/linux/nfsd/xdr4.h
--- 25/include/linux/nfsd/xdr4.h~knfsd-changeinfo-time-higher-resolution	Mon Feb 23 16:33:44 2004
+++ 25-akpm/include/linux/nfsd/xdr4.h	Mon Feb 23 16:33:44 2004
@@ -54,10 +54,10 @@ typedef struct {
 
 struct nfsd4_change_info {
 	u32		atomic;
-	u32		before_size;
-	u32		before_ctime;
-	u32		after_size;
-	u32		after_ctime;
+	u32		before_ctime_sec;
+	u32		before_ctime_nsec;
+	u32		after_ctime_sec;
+	u32		after_ctime_nsec;
 };
 
 struct nfsd4_access {
@@ -406,10 +406,10 @@ set_change_info(struct nfsd4_change_info
 {
 	BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved);
 	cinfo->atomic = 1;
-	cinfo->before_size = fhp->fh_pre_size;
-	cinfo->before_ctime = fhp->fh_pre_ctime.tv_sec;
-	cinfo->after_size = fhp->fh_post_size;
-	cinfo->after_ctime = fhp->fh_post_ctime.tv_sec;
+	cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec;
+	cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec;
+	cinfo->after_ctime_sec = fhp->fh_post_ctime.tv_sec;
+	cinfo->after_ctime_nsec = fhp->fh_post_ctime.tv_nsec;
 }
 
 int nfs4svc_encode_voidres(struct svc_rqst *, u32 *, void *);

_
