[lustre-devel] [PATCH 30/31] lustre: fid: race between client_fid_fini and seq_client_flush

James Simmons jsimmons at infradead.org
Mon Jul 30 19:26:22 PDT 2018


From: Fan Yong <fan.yong at intel.com>

When the client mount failed or umount, the client_fid_fini() will
be called. At that time, the async connection failure will trigger
seq_client_flush() which parameter may have been released by the
client_fid_fini() by race.

Introduce client_obd::cl_seq_rwsem to protect client_obd::cl_seq.

Signed-off-by: Fan Yong <fan.yong at intel.com>
WC-id: https://jira.whamcloud.com/browse/LU-9224
Reviewed-on: https://review.whamcloud.com/26079
Reviewed-by: John L. Hammond <jhammond at whamcloud.com>
Reviewed-by: Andreas Dilger <adilger at whamcloud.com>
Reviewed-by: Oleg Drokin <green at whamcloud.com>
Signed-off-by: James Simmons <jsimmons at infradead.org>
---
 drivers/staging/lustre/lustre/fid/fid_request.c | 21 +++++++++++++++------
 drivers/staging/lustre/lustre/include/obd.h     |  1 +
 drivers/staging/lustre/lustre/ldlm/ldlm_lib.c   |  2 ++
 drivers/staging/lustre/lustre/mdc/mdc_request.c | 11 +++++++++--
 4 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/lustre/lustre/fid/fid_request.c b/drivers/staging/lustre/lustre/fid/fid_request.c
index a34fd90..f91242c 100644
--- a/drivers/staging/lustre/lustre/fid/fid_request.c
+++ b/drivers/staging/lustre/lustre/fid/fid_request.c
@@ -343,11 +343,14 @@ int client_fid_init(struct obd_device *obd,
 {
 	struct client_obd *cli = &obd->u.cli;
 	char *prefix;
-	int rc;
+	int rc = 0;
 
+	down_write(&cli->cl_seq_rwsem);
 	cli->cl_seq = kzalloc(sizeof(*cli->cl_seq), GFP_NOFS);
-	if (!cli->cl_seq)
-		return -ENOMEM;
+	if (!cli->cl_seq) {
+		rc = -ENOMEM;
+		goto out_free_lock;
+	}
 
 	prefix = kzalloc(MAX_OBD_NAME + 5, GFP_NOFS);
 	if (!prefix) {
@@ -361,10 +364,14 @@ int client_fid_init(struct obd_device *obd,
 	seq_client_init(cli->cl_seq, exp, type, prefix);
 	kfree(prefix);
 
-	return 0;
 out_free_seq:
-	kfree(cli->cl_seq);
-	cli->cl_seq = NULL;
+	if (rc) {
+		kfree(cli->cl_seq);
+		cli->cl_seq = NULL;
+	}
+out_free_lock:
+	up_write(&cli->cl_seq_rwsem);
+
 	return rc;
 }
 EXPORT_SYMBOL(client_fid_init);
@@ -373,11 +380,13 @@ int client_fid_fini(struct obd_device *obd)
 {
 	struct client_obd *cli = &obd->u.cli;
 
+	down_write(&cli->cl_seq_rwsem);
 	if (cli->cl_seq) {
 		seq_client_fini(cli->cl_seq);
 		kfree(cli->cl_seq);
 		cli->cl_seq = NULL;
 	}
+	up_write(&cli->cl_seq_rwsem);
 
 	return 0;
 }
diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h
index 333c703..3c0dbb6 100644
--- a/drivers/staging/lustre/lustre/include/obd.h
+++ b/drivers/staging/lustre/lustre/include/obd.h
@@ -333,6 +333,7 @@ struct client_obd {
 
 	/* sequence manager */
 	struct lu_client_seq    *cl_seq;
+	struct rw_semaphore	 cl_seq_rwsem;
 
 	atomic_t	     cl_resends; /* resend count */
 
diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c
index c36d1e4..32eda4f 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lib.c
@@ -308,6 +308,8 @@ int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg)
 	}
 
 	init_rwsem(&cli->cl_sem);
+	cli->cl_seq = NULL;
+	init_rwsem(&cli->cl_seq_rwsem);
 	cli->cl_conn_count = 0;
 	memcpy(server_uuid.uuid, lustre_cfg_buf(lcfg, 2),
 	       min_t(unsigned int, LUSTRE_CFG_BUFLEN(lcfg, 2),
diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c
index c2f0a54..a759da2 100644
--- a/drivers/staging/lustre/lustre/mdc/mdc_request.c
+++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c
@@ -2517,8 +2517,10 @@ static int mdc_import_event(struct obd_device *obd, struct obd_import *imp,
 		 * Flush current sequence to make client obtain new one
 		 * from server in case of disconnect/reconnect.
 		 */
+		down_read(&cli->cl_seq_rwsem);
 		if (cli->cl_seq)
 			seq_client_flush(cli->cl_seq);
+		up_read(&cli->cl_seq_rwsem);
 
 		rc = obd_notify_observer(obd, obd, OBD_NOTIFY_INACTIVE);
 		break;
@@ -2557,9 +2559,14 @@ int mdc_fid_alloc(const struct lu_env *env, struct obd_export *exp,
 		  struct lu_fid *fid, struct md_op_data *op_data)
 {
 	struct client_obd *cli = &exp->exp_obd->u.cli;
-	struct lu_client_seq *seq = cli->cl_seq;
+	int rc = -EIO;
 
-	return seq_client_alloc_fid(env, seq, fid);
+	down_read(&cli->cl_seq_rwsem);
+	if (cli->cl_seq)
+		rc = seq_client_alloc_fid(env, cli->cl_seq, fid);
+	up_read(&cli->cl_seq_rwsem);
+
+	return rc;
 }
 
 static struct obd_uuid *mdc_get_uuid(struct obd_export *exp)
-- 
1.8.3.1



More information about the lustre-devel mailing list