aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/client.c2
-rw-r--r--fs/nfs/file.c19
-rw-r--r--fs/nfs/nfs3xdr.c3
3 files changed, 20 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}