diff options
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/client.c | 2 | ||||
-rw-r--r-- | fs/nfs/file.c | 19 | ||||
-rw-r--r-- | fs/nfs/nfs3xdr.c | 3 |
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 | ||
760 | static int | 760 | static int |
761 | is_time_granular(struct timespec *ts) { | ||
762 | return ((ts->tv_sec == 0) && (ts->tv_nsec <= 1000)); | ||
763 | } | ||
764 | |||
765 | static int | ||
761 | do_setlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) | 766 | do_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 | } | ||
791 | out: | 804 | out: |
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 | } |