]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] A basic NFSv4 client for 2.5.x
authorTrond Myklebust <trond.myklebust@fys.uio.no>
Thu, 10 Oct 2002 05:48:22 +0000 (22:48 -0700)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Thu, 10 Oct 2002 05:48:22 +0000 (22:48 -0700)
This is a nontrivial change to the NFS client.

NFSv4 defines a new file attribute, change_attr.  This is a per-file
opaque quantity returned by the server, whose value is required to
change whenever the file is modified.  If it exists, we want to use
it for all cache consistency checks in nfs_refresh_inode().  Some
operations also return a "pre-operation" value of the change_attr;
we want to take this into account too.

First, define flags
  NFS_ATTR_FATTR_V4 - indicates that the 'struct nfs_fattr' is an
                      NFSv4 fattr, so the change_attr field is valid
  NFS_ATTR_PRE_CHANGE - indicates that the server returned a pre-operation
                      change_attr, so the pre_change_attr field is valid

Second, change nfs_refresh_inode() so that the caches are invalidated
if there is a change_attr mismatch.  Exception: If the pre_change_attr
tells us that the mismatch was caused by our operation, then do not
invalidate the caches.

This patch should leave the logic in nfs_refresh_inode() unchanged
if neither of the new flags are set.

fs/nfs/inode.c
include/linux/nfs_fs.h
include/linux/nfs_xdr.h

index c3f915274169c82c020d6abaa5af827aa37c4964..b1ba7f9211f98719e631e6aede491cb4799e1052 100644 (file)
@@ -716,6 +716,8 @@ __nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
                inode->i_mtime = nfs_time_to_secs(new_mtime);
                NFS_MTIME_UPDATE(inode) = fattr->timestamp;
                NFS_CACHE_ISIZE(inode) = new_size;
+               if (fattr->valid & NFS_ATTR_FATTR_V4)
+                       NFS_CHANGE_ATTR(inode) = fattr->change_attr;
                inode->i_size = new_isize;
                inode->i_mode = fattr->mode;
                inode->i_nlink = fattr->nlink;
@@ -1067,12 +1069,25 @@ __nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
                invalid = 1;
        }
 
+       if ((fattr->valid & NFS_ATTR_FATTR_V4)
+           && NFS_CHANGE_ATTR(inode) != fattr->change_attr) {
+#ifdef NFS_DEBUG_VERBOSE
+               printk(KERN_DEBUG "NFS: change_attr change on %s/%ld\n",
+                      inode->i_sb->s_id, inode->i_ino);
+#endif
+               invalid = 1;
+       }
+
        /* Check Weak Cache Consistency data.
         * If size and mtime match the pre-operation values, we can
         * assume that any attribute changes were caused by our NFS
          * operation, so there's no need to invalidate the caches.
          */
-        if ((fattr->valid & NFS_ATTR_WCC)
+       if ((fattr->valid & NFS_ATTR_PRE_CHANGE)
+           && NFS_CHANGE_ATTR(inode) == fattr->pre_change_attr) {
+               invalid = 0;
+       }
+       else if ((fattr->valid & NFS_ATTR_WCC)
            && NFS_CACHE_ISIZE(inode) == fattr->pre_size
            && NFS_CACHE_MTIME(inode) == fattr->pre_mtime) {
                invalid = 0;
@@ -1110,6 +1125,9 @@ __nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
                }
        }
 
+       if (fattr->valid & NFS_ATTR_FATTR_V4)
+               NFS_CHANGE_ATTR(inode) = fattr->change_attr;
+
        inode->i_mode = fattr->mode;
        inode->i_nlink = fattr->nlink;
        inode->i_uid = fattr->uid;
index a53ad5ea4ceb45274012fe5c27ca5356601129cd..588cb1437080cb0e74dd7d6d300da9a3e6f2e8bf 100644 (file)
@@ -144,6 +144,7 @@ struct nfs_inode {
        __u64                   read_cache_isize;
        unsigned long           attrtimeo;
        unsigned long           attrtimeo_timestamp;
+       __u64                   change_attr;            /* v4 only */
 
        /*
         * Timestamp that dates the change made to read_cache_mtime.
@@ -208,6 +209,7 @@ static inline struct nfs_inode *NFS_I(struct inode *inode)
 #define NFS_CACHE_CTIME(inode)         (NFS_I(inode)->read_cache_ctime)
 #define NFS_CACHE_MTIME(inode)         (NFS_I(inode)->read_cache_mtime)
 #define NFS_CACHE_ISIZE(inode)         (NFS_I(inode)->read_cache_isize)
+#define NFS_CHANGE_ATTR(inode)         (NFS_I(inode)->change_attr)
 #define NFS_NEXTSCAN(inode)            (NFS_I(inode)->nextscan)
 #define NFS_CACHEINV(inode) \
 do { \
index ce871934f6e5ad32ea5ed0d0970a0382133f9913..18c44a22b3d89593bac2be194f3db8b946f91758 100644 (file)
@@ -35,12 +35,16 @@ struct nfs_fattr {
        __u64                   atime;
        __u64                   mtime;
        __u64                   ctime;
+       __u64                   change_attr;    /* NFSv4 change attribute */
+       __u64                   pre_change_attr;/* pre-op NFSv4 change attribute */
        unsigned long           timestamp;
 };
 
 #define NFS_ATTR_WCC           0x0001          /* pre-op WCC data    */
 #define NFS_ATTR_FATTR         0x0002          /* post-op attributes */
 #define NFS_ATTR_FATTR_V3      0x0004          /* NFSv3 attributes */
+#define NFS_ATTR_FATTR_V4      0x0008
+#define NFS_ATTR_PRE_CHANGE    0x0010
 
 /*
  * Info on the file system