[PATCH] NFS: Fix state renewals missing after boot

Joshua Watt posted 1 patch 2 months, 1 week ago
fs/nfs/client.c | 1 +
1 file changed, 1 insertion(+)
[PATCH] NFS: Fix state renewals missing after boot
Posted by Joshua Watt 2 months, 1 week ago
From: Joshua Watt <jpewhacker@gmail.com>

Since the last renewal time was initialized to 0 and jiffies start
counting at -5 minutes, any clients connected in the first 5 minutes
after a reboot would have their renewal timer set to a very long
interval. If the connection was idle, this would result in the client
state timing out on the server and the next call to the server would
return NFS4ERR_BADSESSION.

Fix this by initializing the last renewal time to the current jiffies
instead of 0.

Signed-off-by: Joshua Watt <jpewhacker@gmail.com>
---
 fs/nfs/client.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 4e3dcc157a83..96cdfeb26a90 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -181,6 +181,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
 	clp->cl_nconnect = cl_init->nconnect;
 	clp->cl_max_connect = cl_init->max_connect ? cl_init->max_connect : 1;
 	clp->cl_net = get_net_track(cl_init->net, &clp->cl_ns_tracker, GFP_KERNEL);
+	clp->cl_last_renewal = jiffies;
 
 #if IS_ENABLED(CONFIG_NFS_LOCALIO)
 	seqlock_init(&clp->cl_boot_lock);
-- 
2.51.0
Re: [PATCH] NFS: Fix state renewals missing after boot
Posted by kernel test robot 2 months, 1 week ago
Hi Joshua,

kernel test robot noticed the following build errors:

[auto build test ERROR on trondmy-nfs/linux-next]
[also build test ERROR on linus/master v6.17 next-20251010]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Joshua-Watt/NFS-Fix-state-renewals-missing-after-boot/20251010-103708
base:   git://git.linux-nfs.org/projects/trondmy/linux-nfs.git linux-next
patch link:    https://lore.kernel.org/r/20251008230935.738405-1-JPEWhacker%40gmail.com
patch subject: [PATCH] NFS: Fix state renewals missing after boot
config: mips-ip32_defconfig (https://download.01.org/0day-ci/archive/20251011/202510110046.sj3dc5HD-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project 39f292ffa13d7ca0d1edff27ac8fd55024bb4d19)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251011/202510110046.sj3dc5HD-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202510110046.sj3dc5HD-lkp@intel.com/

All errors (new ones prefixed by >>):

>> fs/nfs/client.c:184:7: error: no member named 'cl_last_renewal' in 'struct nfs_client'
     184 |         clp->cl_last_renewal = jiffies;
         |         ~~~  ^
   1 error generated.


vim +184 fs/nfs/client.c

   141	
   142	/*
   143	 * Allocate a shared client record
   144	 *
   145	 * Since these are allocated/deallocated very rarely, we don't
   146	 * bother putting them in a slab cache...
   147	 */
   148	struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
   149	{
   150		struct nfs_client *clp;
   151		int err = -ENOMEM;
   152	
   153		if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
   154			goto error_0;
   155	
   156		clp->cl_minorversion = cl_init->minorversion;
   157		clp->cl_nfs_mod = cl_init->nfs_mod;
   158		if (!get_nfs_version(clp->cl_nfs_mod))
   159			goto error_dealloc;
   160	
   161		clp->rpc_ops = clp->cl_nfs_mod->rpc_ops;
   162	
   163		refcount_set(&clp->cl_count, 1);
   164		clp->cl_cons_state = NFS_CS_INITING;
   165	
   166		memcpy(&clp->cl_addr, cl_init->addr, cl_init->addrlen);
   167		clp->cl_addrlen = cl_init->addrlen;
   168	
   169		if (cl_init->hostname) {
   170			err = -ENOMEM;
   171			clp->cl_hostname = kstrdup(cl_init->hostname, GFP_KERNEL);
   172			if (!clp->cl_hostname)
   173				goto error_cleanup;
   174		}
   175	
   176		INIT_LIST_HEAD(&clp->cl_superblocks);
   177		clp->cl_rpcclient = ERR_PTR(-EINVAL);
   178	
   179		clp->cl_flags = cl_init->init_flags;
   180		clp->cl_proto = cl_init->proto;
   181		clp->cl_nconnect = cl_init->nconnect;
   182		clp->cl_max_connect = cl_init->max_connect ? cl_init->max_connect : 1;
   183		clp->cl_net = get_net_track(cl_init->net, &clp->cl_ns_tracker, GFP_KERNEL);
 > 184		clp->cl_last_renewal = jiffies;
   185	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH] NFS: Fix state renewals missing after boot
Posted by Anna Schumaker 2 months, 1 week ago
Hi Joshua,

On 10/8/25 7:09 PM, Joshua Watt wrote:
> From: Joshua Watt <jpewhacker@gmail.com>
> 
> Since the last renewal time was initialized to 0 and jiffies start
> counting at -5 minutes, any clients connected in the first 5 minutes
> after a reboot would have their renewal timer set to a very long
> interval. If the connection was idle, this would result in the client
> state timing out on the server and the next call to the server would
> return NFS4ERR_BADSESSION.
> 
> Fix this by initializing the last renewal time to the current jiffies
> instead of 0.
> 
> Signed-off-by: Joshua Watt <jpewhacker@gmail.com>
> ---
>  fs/nfs/client.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/fs/nfs/client.c b/fs/nfs/client.c
> index 4e3dcc157a83..96cdfeb26a90 100644
> --- a/fs/nfs/client.c
> +++ b/fs/nfs/client.c
> @@ -181,6 +181,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
>  	clp->cl_nconnect = cl_init->nconnect;
>  	clp->cl_max_connect = cl_init->max_connect ? cl_init->max_connect : 1;
>  	clp->cl_net = get_net_track(cl_init->net, &clp->cl_ns_tracker, GFP_KERNEL);
> +	clp->cl_last_renewal = jiffies;

Thanks for the patch! It looks like cl_last_renewal only exists if CONFIG_NFS_V4=y, so this
will fail to compile with NFS v4 disabled. Can you please move this to nfs4_alloc_client()
in nfs4client.c?

Thanks,
Anna

>  
>  #if IS_ENABLED(CONFIG_NFS_LOCALIO)
>  	seqlock_init(&clp->cl_boot_lock);
Re: [PATCH] NFS: Fix state renewals missing after boot
Posted by Jeff Layton 2 months, 1 week ago
On Wed, 2025-10-08 at 17:09 -0600, Joshua Watt wrote:
> From: Joshua Watt <jpewhacker@gmail.com>
> 
> Since the last renewal time was initialized to 0 and jiffies start
> counting at -5 minutes, any clients connected in the first 5 minutes
> after a reboot would have their renewal timer set to a very long
> interval. If the connection was idle, this would result in the client
> state timing out on the server and the next call to the server would
> return NFS4ERR_BADSESSION.
> 
> Fix this by initializing the last renewal time to the current jiffies
> instead of 0.
> 
> Signed-off-by: Joshua Watt <jpewhacker@gmail.com>
> ---
>  fs/nfs/client.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/fs/nfs/client.c b/fs/nfs/client.c
> index 4e3dcc157a83..96cdfeb26a90 100644
> --- a/fs/nfs/client.c
> +++ b/fs/nfs/client.c
> @@ -181,6 +181,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
>  	clp->cl_nconnect = cl_init->nconnect;
>  	clp->cl_max_connect = cl_init->max_connect ? cl_init->max_connect : 1;
>  	clp->cl_net = get_net_track(cl_init->net, &clp->cl_ns_tracker, GFP_KERNEL);
> +	clp->cl_last_renewal = jiffies;
>  
>  #if IS_ENABLED(CONFIG_NFS_LOCALIO)
>  	seqlock_init(&clp->cl_boot_lock);

Nice catch!

Reviewed-by: Jeff Layton <jlayton@kernel.org>
[PATCH v2] NFS4: Fix state renewals missing after boot
Posted by Joshua Watt 2 months, 1 week ago
From: Joshua Watt <jpewhacker@gmail.com>

Since the last renewal time was initialized to 0 and jiffies start
counting at -5 minutes, any clients connected in the first 5 minutes
after a reboot would have their renewal timer set to a very long
interval. If the connection was idle, this would result in the client
state timing out on the server and the next call to the server would
return NFS4ERR_BADSESSION.

Fix this by initializing the last renewal time to the current jiffies
instead of 0.

Signed-off-by: Joshua Watt <jpewhacker@gmail.com>
---
 fs/nfs/nfs4client.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 6fddf43d729c..5998d6bd8a4f 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -222,6 +222,7 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
 	clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
 	clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion];
 	clp->cl_mig_gen = 1;
+	clp->cl_last_renewal = jiffies;
 #if IS_ENABLED(CONFIG_NFS_V4_1)
 	init_waitqueue_head(&clp->cl_lock_waitq);
 #endif
-- 
2.51.0