[PATCH] nfsd: Make NFS client_id increment atomic to avoid race condition

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The following log messages show conflict in clientid
       [err] kernel: [   16.228090] NFS: Server fct reports our clientid is in use
       [warning] kernel: [   16.228102] NFS: state manager: lease expired failed on NFSv4 server fct with error 1
       [warning] kernel: [   16.228102] NFS: state manager: lease expired failed on NFSv4 server fct with error 1

The increment to client_verifier counter and client_id counter is
set to atomic so as to avoid race condition which causes the
aforementioned error.

Change-Id: Ic0fa8c14a8bba043ae8882f6750f512bb5f3aac1
---
 fs/nfsd/netns.h     | 4 ++--
 fs/nfsd/nfs4state.c | 4 ++--
 fs/nfsd/nfsctl.c    | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
index 935c1028c217..67b5aa1516e2 100644
--- a/fs/nfsd/netns.h
+++ b/fs/nfsd/netns.h
@@ -119,8 +119,8 @@ struct nfsd_net {
 	unsigned int max_connections;
 
 	u32 clientid_base;
-	u32 clientid_counter;
-	u32 clverifier_counter;
+	atomic_t clientid_counter;
+	atomic_t clverifier_counter;
 
 	struct svc_serv *nfsd_serv;
 
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 9b660491f393..d67a6a593f59 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2321,14 +2321,14 @@ static void gen_confirm(struct nfs4_client *clp, struct nfsd_net *nn)
 	 * __force to keep sparse happy
 	 */
 	verf[0] = (__force __be32)(u32)ktime_get_real_seconds();
-	verf[1] = (__force __be32)nn->clverifier_counter++;
+	verf[1] = (__force __be32)atomic_inc_return(&(nn->clverifier_counter));
 	memcpy(clp->cl_confirm.data, verf, sizeof(clp->cl_confirm.data));
 }
 
 static void gen_clid(struct nfs4_client *clp, struct nfsd_net *nn)
 {
 	clp->cl_clientid.cl_boot = (u32)nn->boot_time;
-	clp->cl_clientid.cl_id = nn->clientid_counter++;
+	clp->cl_clientid.cl_id = atomic_inc_return(&(nn->clientid_counter));
 	gen_confirm(clp, nn);
 }
 
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index cb73c1292562..a9ef86ee7250 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -1481,10 +1481,10 @@ static __net_init int nfsd_init_net(struct net *net)
 	nn->nfsd4_grace = 90;
 	nn->somebody_reclaimed = false;
 	nn->track_reclaim_completes = false;
-	nn->clverifier_counter = prandom_u32();
+	atomic_set(&(nn->clverifier_counter), prandom_u32());
 	nn->clientid_base = prandom_u32();
-	nn->clientid_counter = nn->clientid_base + 1;
-	nn->s2s_cp_cl_id = nn->clientid_counter++;
+	atomic_set(&(nn->clientid_counter), nn->clientid_base + 1);
+	nn->s2s_cp_cl_id = atomic_inc_return(&(nn->clientid_counter));
 
 	atomic_set(&nn->ntf_refcnt, 0);
 	init_waitqueue_head(&nn->ntf_wq);
-- 
2.42.0





[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux