Whamcloud - gitweb
LU-5264 obdclass: fix race during key quiescency 03/13103/3
authorBruno Faccini <bruno.faccini@intel.com>
Wed, 17 Dec 2014 09:57:07 +0000 (10:57 +0100)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 3 Mar 2015 02:16:48 +0000 (02:16 +0000)
Upon umount, presumably of last device using same OSD back-end,
to prepare for module unload, lu_context_key_quiesce() is run to
remove all module's key reference in any context linked on
lu_context_remembered list.
Threads must protect against such transversal processing when
exiting from its context.

Signed-off-by: Bruno Faccini <bruno.faccini@intel.com>
Change-Id: If2c8199fa764236308b49950672129a63b8877f5
Reviewed-on: http://review.whamcloud.com/13103
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Mike Pershin <mike.pershin@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/obdclass/lu_object.c

index 337069b..dac8c2a 100644 (file)
@@ -1721,15 +1721,20 @@ void lu_context_exit(struct lu_context *ctx)
         ctx->lc_state = LCS_LEFT;
         if (ctx->lc_tags & LCT_HAS_EXIT && ctx->lc_value != NULL) {
                 for (i = 0; i < ARRAY_SIZE(lu_keys); ++i) {
-                        if (ctx->lc_value[i] != NULL) {
-                                struct lu_context_key *key;
-
-                                key = lu_keys[i];
-                                LASSERT(key != NULL);
-                                if (key->lct_exit != NULL)
-                                        key->lct_exit(ctx,
-                                                      key, ctx->lc_value[i]);
-                        }
+                       /* could race with key quiescency */
+                       if (ctx->lc_tags & LCT_REMEMBER)
+                               spin_lock(&lu_keys_guard);
+                       if (ctx->lc_value[i] != NULL) {
+                               struct lu_context_key *key;
+
+                               key = lu_keys[i];
+                               LASSERT(key != NULL);
+                               if (key->lct_exit != NULL)
+                                       key->lct_exit(ctx,
+                                                     key, ctx->lc_value[i]);
+                       }
+                       if (ctx->lc_tags & LCT_REMEMBER)
+                               spin_unlock(&lu_keys_guard);
                 }
         }
 }