From 6ff417169a2ad84478cce1b0321e70a030ffed83 Mon Sep 17 00:00:00 2001 From: Bruno Faccini Date: Mon, 26 Oct 2015 14:37:19 +0100 Subject: [PATCH] LU-7221 ldlm: do not take a reference on target if stopping In the set of changes of patch for LU-5569 (http://review.whamcloud.com/11750/, commit 892078e3b566c04471e7dcf2c28e66f2f3584f93) one is to take a reference on target even if it is stopping (umount'ed). Then, upon connections attempts, this can lead to unwanted cleanup actions to occur on [obd_self_]export from class_decref(), finally causing a LBUG in class_export_put() because export's exp_refcount has already reached 0. Signed-off-by: Bruno Faccini Change-Id: If960437934fb694d173a4fd1fbfb9e43d496fea6 Reviewed-on: http://review.whamcloud.com/16940 Tested-by: Jenkins Reviewed-by: Jinshan Xiong Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- lustre/ldlm/ldlm_lib.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c index d7816f0..c2f2b82 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -923,6 +923,7 @@ int target_handle_connect(struct ptlrpc_request *req) bool mds_conn = false, lw_client = false; bool mds_mds_conn = false; bool new_mds_mds_conn = false; + bool target_referenced = false; struct obd_connect_data *data, *tmpdata; int size, tmpsize; lnet_nid_t *client_nid = NULL; @@ -952,11 +953,6 @@ int target_handle_connect(struct ptlrpc_request *req) } spin_lock(&target->obd_dev_lock); - /* Make sure the target isn't cleaned up while we're here. Yes, - * there's still a race between the above check and our incref here. - * Really, class_uuid2obd should take the ref. */ - class_incref(target, __func__, current); - if (target->obd_stopping || !target->obd_set_up) { spin_unlock(&target->obd_dev_lock); @@ -978,6 +974,12 @@ int target_handle_connect(struct ptlrpc_request *req) GOTO(out, rc = -EAGAIN); } + /* Make sure the target isn't cleaned up while we're here. Yes, + * there's still a race between the above check and our incref here. + * Really, class_uuid2obd should take the ref. */ + class_incref(target, __func__, current); + target_referenced = true; + target->obd_conn_inprogress++; spin_unlock(&target->obd_dev_lock); @@ -1386,7 +1388,7 @@ out: class_export_put(export); } - if (target != NULL) { + if (target_referenced == true && target != NULL) { spin_lock(&target->obd_dev_lock); target->obd_conn_inprogress--; spin_unlock(&target->obd_dev_lock); -- 1.8.3.1