[Devel] [PATCH vz9 6/9] nfsd: return file system superblock time granulaty on FSINFO request

Nikita Yushchenko nikita.yushchenko at virtuozzo.com
Fri Oct 1 09:32:52 MSK 2021


From: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>

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 at virtuozzo.com>

(cherry-picked from vz8 commit bcd8b870950a ("nfsd: return file system
superblock time granulaty on FSINFO request"))

Adopt to refactored nfs3xdr encoder code.

Signed-off-by: Nikita Yushchenko <nikita.yushchenko at virtuozzo.com>
---
 fs/nfsd/nfs3proc.c |  3 +++
 fs/nfsd/nfs3xdr.c  | 22 +++++++++++++---------
 fs/nfsd/xdr3.h     |  1 +
 3 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 17715a6c7a40..986d5a632832 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -597,6 +597,9 @@ nfsd3_proc_fsinfo(struct svc_rqst *rqstp)
 			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 0a5ebc52e6a9..704e727464ca 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -21,15 +21,6 @@ static const struct svc_fh nfs3svc_null_fh = {
 	.fh_no_wcc	= true,
 };
 
-/*
- * time_delta. {1, 0} means the server is accurate only
- * to the nearest second.
- */
-static const struct timespec64 nfs3svc_time_delta = {
-	.tv_sec		= 1,
-	.tv_nsec	= 0,
-};
-
 /*
  * Mapping of S_IF* types to NFS file types
  */
@@ -1336,6 +1327,19 @@ svcxdr_encode_fsinfo3resok(struct xdr_stream *xdr,
 			   const struct nfsd3_fsinfores *resp)
 {
 	__be32 *p;
+	struct timespec64 nfs3svc_time_delta;
+
+	if (resp->f_time_gran) {
+		nfs3svc_time_delta.tv_sec = 0;
+		nfs3svc_time_delta.tv_nsec = resp->f_time_gran;
+	} else {
+		/*
+		 * {1, 0} means the server is accurate only to the nearest
+		 * second.
+		 */
+		nfs3svc_time_delta.tv_sec = 1;
+		nfs3svc_time_delta.tv_nsec = 0;
+	}
 
 	p = xdr_reserve_space(xdr, XDR_UNIT * 12);
 	if (!p)
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index 933008382bbe..9a33ea0b678d 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -201,6 +201,7 @@ struct nfsd3_fsinfores {
 	__u32			f_dtpref;
 	__u64			f_maxfilesize;
 	__u32			f_properties;
+	__u32			f_time_gran;
 };
 
 struct nfsd3_pathconfres {
-- 
2.30.2



More information about the Devel mailing list