aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/client.c2
-rw-r--r--fs/nfs/file.c19
-rw-r--r--fs/nfs/nfs3xdr.c3
-rw-r--r--include/linux/nfs_fs_sb.h1
-rw-r--r--include/linux/nfs_xdr.h1
5 files changed, 22 insertions, 4 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index da2f2f024a4d..a63bce8d0596 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -915,6 +915,8 @@ static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *
915 915
916 server->maxfilesize = fsinfo->maxfilesize; 916 server->maxfilesize = fsinfo->maxfilesize;
917 917
918 server->time_delta = fsinfo->time_delta;
919
918 /* We're airborne Set socket buffersize */ 920 /* We're airborne Set socket buffersize */
919 rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100); 921 rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
920} 922}
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 39672b731736..c3f2477c16c1 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -758,6 +758,11 @@ do_unlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
758} 758}
759 759
760static int 760static int
761is_time_granular(struct timespec *ts) {
762 return ((ts->tv_sec == 0) && (ts->tv_nsec <= 1000));
763}
764
765static int
761do_setlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) 766do_setlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
762{ 767{
763 struct inode *inode = filp->f_mapping->host; 768 struct inode *inode = filp->f_mapping->host;
@@ -781,13 +786,21 @@ do_setlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
781 status = do_vfs_lock(filp, fl); 786 status = do_vfs_lock(filp, fl);
782 if (status < 0) 787 if (status < 0)
783 goto out; 788 goto out;
789
784 /* 790 /*
785 * Make sure we clear the cache whenever we try to get the lock. 791 * Revalidate the cache if the server has time stamps granular
792 * enough to detect subsecond changes. Otherwise, clear the
793 * cache to prevent missing any changes.
794 *
786 * This makes locking act as a cache coherency point. 795 * This makes locking act as a cache coherency point.
787 */ 796 */
788 nfs_sync_mapping(filp->f_mapping); 797 nfs_sync_mapping(filp->f_mapping);
789 if (!nfs_have_delegation(inode, FMODE_READ)) 798 if (!nfs_have_delegation(inode, FMODE_READ)) {
790 nfs_zap_caches(inode); 799 if (is_time_granular(&NFS_SERVER(inode)->time_delta))
800 __nfs_revalidate_inode(NFS_SERVER(inode), inode);
801 else
802 nfs_zap_caches(inode);
803 }
791out: 804out:
792 return status; 805 return status;
793} 806}
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index 31a44df40aea..d9a5e832c257 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -1044,8 +1044,9 @@ nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res)
1044 res->wtmult = ntohl(*p++); 1044 res->wtmult = ntohl(*p++);
1045 res->dtpref = ntohl(*p++); 1045 res->dtpref = ntohl(*p++);
1046 p = xdr_decode_hyper(p, &res->maxfilesize); 1046 p = xdr_decode_hyper(p, &res->maxfilesize);
1047 p = xdr_decode_time3(p, &res->time_delta);
1047 1048
1048 /* ignore time_delta and properties */ 1049 /* ignore properties */
1049 res->lease_time = 0; 1050 res->lease_time = 0;
1050 return 0; 1051 return 0;
1051} 1052}
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index c82ee7cd6288..5eef862ec187 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -124,6 +124,7 @@ struct nfs_server {
124 124
125 struct nfs_fsid fsid; 125 struct nfs_fsid fsid;
126 __u64 maxfilesize; /* maximum file size */ 126 __u64 maxfilesize; /* maximum file size */
127 struct timespec time_delta; /* smallest time granularity */
127 unsigned long mount_time; /* when this fs was mounted */ 128 unsigned long mount_time; /* when this fs was mounted */
128 dev_t s_dev; /* superblock dev numbers */ 129 dev_t s_dev; /* superblock dev numbers */
129 130
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index efe2eab8ac94..da7a1300dc60 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -112,6 +112,7 @@ struct nfs_fsinfo {
112 __u32 wtmult; /* writes should be multiple of this */ 112 __u32 wtmult; /* writes should be multiple of this */
113 __u32 dtpref; /* pref. readdir transfer size */ 113 __u32 dtpref; /* pref. readdir transfer size */
114 __u64 maxfilesize; 114 __u64 maxfilesize;
115 struct timespec time_delta; /* server time granularity */
115 __u32 lease_time; /* in seconds */ 116 __u32 lease_time; /* in seconds */
116}; 117};
117 118