aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r--fs/nfs/file.c19
1 files changed, 16 insertions, 3 deletions
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}