From 1dc6122d7e8aada552fc15b693b1cabf82bf4970 Mon Sep 17 00:00:00 2001
From: yury <yury>
Date: Fri, 7 Nov 2008 13:18:17 +0000
Subject: [PATCH] b=17445 r=tappro,johann

- implements proper locking for rq pool freeing
---
 lustre/ldlm/ldlm_lib.c   | 7 +++++--
 lustre/mdc/mdc_request.c | 3 ++-
 lustre/osc/osc_request.c | 7 ++++++-
 lustre/ptlrpc/client.c   | 7 ++++---
 4 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c
index ae38782bfa..4417b6792b 100644
--- a/lustre/ldlm/ldlm_lib.c
+++ b/lustre/ldlm/ldlm_lib.c
@@ -504,8 +504,11 @@ int client_disconnect_export(struct obd_export *exp)
          * some connect requests in flight, and his need store a connect flags
          * in obd_namespace. bug 14260 */
         obd->obd_namespace = NULL;
-	
-        ptlrpc_free_rq_pool(imp->imp_rq_pool);
+
+        if (imp->imp_rq_pool) {
+                ptlrpc_free_rq_pool(imp->imp_rq_pool);
+                imp->imp_rq_pool = NULL;
+        }
         class_destroy_import(imp);
         cli->cl_import = NULL;
 
diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c
index 4613655efd..5702dd758b 100644
--- a/lustre/mdc/mdc_request.c
+++ b/lustre/mdc/mdc_request.c
@@ -1306,11 +1306,12 @@ static int mdc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
                    client import will not have been cleaned. */
                 if (obd->u.cli.cl_import) {
                         struct obd_import *imp;
+                        down_write(&obd->u.cli.cl_sem);
                         imp = obd->u.cli.cl_import;
                         CERROR("client import never connected\n");
                         ptlrpc_invalidate_import(imp);
-                        ptlrpc_free_rq_pool(imp->imp_rq_pool);
                         class_destroy_import(imp);
+                        up_write(&obd->u.cli.cl_sem);
                         obd->u.cli.cl_import = NULL;
                 }
                 rc = obd_llog_finish(obd, 0);
diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c
index 9c6665495a..3151dcd9fd 100644
--- a/lustre/osc/osc_request.c
+++ b/lustre/osc/osc_request.c
@@ -3885,12 +3885,17 @@ static int osc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
                    client import will not have been cleaned. */
                 if (obd->u.cli.cl_import) {
                         struct obd_import *imp;
+                        down_write(&obd->u.cli.cl_sem);
                         imp = obd->u.cli.cl_import;
                         CDEBUG(D_CONFIG, "%s: client import never connected\n",
                                obd->obd_name);
                         ptlrpc_invalidate_import(imp);
-                        ptlrpc_free_rq_pool(imp->imp_rq_pool);
+                        if (imp->imp_rq_pool) {
+                                ptlrpc_free_rq_pool(imp->imp_rq_pool);
+                                imp->imp_rq_pool = NULL;
+                        }
                         class_destroy_import(imp);
+                        up_write(&obd->u.cli.cl_sem);
                         obd->u.cli.cl_import = NULL;
                 }
                 rc = obd_llog_finish(obd, 0);
diff --git a/lustre/ptlrpc/client.c b/lustre/ptlrpc/client.c
index 5211006733..40603b3416 100644
--- a/lustre/ptlrpc/client.c
+++ b/lustre/ptlrpc/client.c
@@ -419,16 +419,17 @@ void ptlrpc_free_rq_pool(struct ptlrpc_request_pool *pool)
         struct list_head *l, *tmp;
         struct ptlrpc_request *req;
 
-        if (!pool)
-                return;
+        LASSERT(pool != NULL);
 
+        spin_lock(&pool->prp_lock);
         list_for_each_safe(l, tmp, &pool->prp_req_list) {
                 req = list_entry(l, struct ptlrpc_request, rq_list);
                 list_del(&req->rq_list);
-                LASSERT (req->rq_reqmsg);
+                LASSERT(req->rq_reqmsg);
                 OBD_FREE(req->rq_reqmsg, pool->prp_rq_size);
                 OBD_FREE(req, sizeof(*req));
         }
+        spin_unlock(&pool->prp_lock);
         OBD_FREE(pool, sizeof(*pool));
 }
 
-- 
GitLab