[Devel] nfsd: return file system superblock time granulaty on FSINFO request

Submitted by Stanislav Kinsburskiy on June 30, 2017, 5:16 p.m.

Details

Message ID 20170630171627.8464.41118.stgit@localhost.localdomain
State New
Series "nfsd: return file system superblock time granulaty on FSINFO request"
Headers show

Commit Message

Stanislav Kinsburskiy June 30, 2017, 5:16 p.m.
Current NFS client implementation can zap inode caches or just re-validate the
inode after successful lock request using it as a synchronization point.

Inode caches zapping or re-validation depends on server's file system time
granularity status: if time granularity is less than second, then
re-validation
is assumed to be enough. But Linux NFS server always return "1 second" value
for any file system. This looks like an old artefact.

So, let's so the following: return "sb->s_time_gran" to NFS client.
But only for EXT4 file system for a while.
This will remove bottleneck when many processes are concurrently trying to
lock large file like SQL database.

Ported from rhel6.

https://jira.sw.ru/browse/PSBM-66572

Signed-off-by: Stanislav Kinsburskiy <skinsbursky@virtuozzo.com>
---
 fs/nfsd/nfs3proc.c |    3 +++
 fs/nfsd/nfs3xdr.c  |    9 +++++++--
 fs/nfsd/xdr3.h     |    1 +
 3 files changed, 11 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 88afc45..3199757 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -559,6 +559,9 @@  nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle    *argp,
 			resp->f_properties = NFS3_FSF_BILLYBOY;
 		}
 		resp->f_maxfilesize = sb->s_maxbytes;
+		resp->f_time_gran = 0;
+		if (!strcmp(sb->s_type->name, "ext4"))
+			resp->f_time_gran = sb->s_time_gran;
 	}
 
 	fh_put(&argp->fh);
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 73d21f0..ff41760 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -1057,8 +1057,13 @@  nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, __be32 *p,
 		*p++ = htonl(resp->f_wtmult);
 		*p++ = htonl(resp->f_dtpref);
 		p = xdr_encode_hyper(p, resp->f_maxfilesize);
-		*p++ = xdr_one;
-		*p++ = xdr_zero;
+		if (resp->f_time_gran) {
+			*p++ = xdr_zero;
+			*p++ = htonl(resp->f_time_gran);
+		} else {
+			*p++ = xdr_one;
+			*p++ = xdr_zero;
+		}
 		*p++ = htonl(resp->f_properties);
 	}
 
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index 335e04a..2744607 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -206,6 +206,7 @@  struct nfsd3_fsinfores {
 	__u32			f_dtpref;
 	__u64			f_maxfilesize;
 	__u32			f_properties;
+	__u32			f_time_gran;
 };
 
 struct nfsd3_pathconfres {