diff options
-rw-r--r-- | fs/nfs/client.c | 2 | ||||
-rw-r--r-- | fs/nfs/file.c | 19 | ||||
-rw-r--r-- | fs/nfs/nfs3xdr.c | 3 | ||||
-rw-r--r-- | include/linux/nfs_fs_sb.h | 1 | ||||
-rw-r--r-- | include/linux/nfs_xdr.h | 1 |
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 | ||
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 | } |
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 | ||