From d0c19023fe71b5bb438eee27b351ccc21cf892a1 Mon Sep 17 00:00:00 2001 From: nikita Date: Fri, 14 Apr 2006 22:02:11 +0000 Subject: [PATCH] improve lu_context_key() functions, add lu_context_key_degister() --- lustre/include/linux/lu_object.h | 2 ++ lustre/obdclass/lu_object.c | 77 +++++++++++++++++++++++++--------------- 2 files changed, 50 insertions(+), 29 deletions(-) diff --git a/lustre/include/linux/lu_object.h b/lustre/include/linux/lu_object.h index eb8f36c..48623e5 100644 --- a/lustre/include/linux/lu_object.h +++ b/lustre/include/linux/lu_object.h @@ -476,9 +476,11 @@ struct lu_context_key { void *(*lct_init)(struct lu_context *ctx); void (*lct_fini)(struct lu_context *ctx, void *data); int lct_index; + unsigned lct_used; }; int lu_context_key_register(struct lu_context_key *key); +void lu_context_key_degister(struct lu_context_key *key); void *lu_context_key_get(struct lu_context *ctx, struct lu_context_key *key); int lu_context_init(struct lu_context *ctx); diff --git a/lustre/obdclass/lu_object.c b/lustre/obdclass/lu_object.c index a0ea5c1..b07f39d 100644 --- a/lustre/obdclass/lu_object.c +++ b/lustre/obdclass/lu_object.c @@ -392,36 +392,47 @@ enum { LU_CONTEXT_KEY_NR = 16 }; -static struct lu_context_key *keys[LU_CONTEXT_KEY_NR] = { NULL, }; +static struct lu_context_key *lu_keys[LU_CONTEXT_KEY_NR] = { NULL, }; -static int keys_nr = 0; -static spinlock_t keys_guard = SPIN_LOCK_UNLOCKED; -static int key_registration_over = 0; +static spinlock_t lu_keys_guard = SPIN_LOCK_UNLOCKED; int lu_context_key_register(struct lu_context_key *key) { int result; + int i; - if (!key_registration_over) { - spin_lock(&keys_guard); - if (keys_nr < ARRAY_SIZE(keys)) { - key->lct_index = keys_nr; - keys[keys_nr] = key; - keys_nr++; + result = -ENFILE; + spin_lock(&lu_keys_guard); + for (i = 0; i < ARRAY_SIZE(lu_keys); ++i) { + if (lu_keys[i] == NULL) { + key->lct_index = i; + key->lct_used = 1; + lu_keys[i] = key; result = 0; - } else - result = -ENFILE; - spin_unlock(&keys_guard); - } else { - CERROR("Too late to register a key.\n"); - result = -EBUSY; + break; + } } + spin_unlock(&lu_keys_guard); return result; } EXPORT_SYMBOL(lu_context_key_register); +void lu_context_key_degister(struct lu_context_key *key) +{ + LASSERT(key->lct_used >= 1); + LASSERT(0 <= key->lct_index && key->lct_index < ARRAY_SIZE(lu_keys)); + + if (key->lct_used > 1) + CERROR("key has instances.\n"); + spin_lock(&lu_keys_guard); + lu_keys[key->lct_index] = NULL; + spin_unlock(&lu_keys_guard); +} +EXPORT_SYMBOL(lu_context_key_degister); + void *lu_context_key_get(struct lu_context *ctx, struct lu_context_key *key) { + LASSERT(0 <= key->lct_index && key->lct_index < ARRAY_SIZE(lu_keys)); return ctx->lc_value[key->lct_index]; } EXPORT_SYMBOL(lu_context_key_get); @@ -431,16 +442,22 @@ static void keys_fini(struct lu_context *ctx) int i; if (ctx->lc_value != NULL) { - for (i = 0; i < keys_nr; ++i) { + for (i = 0; i < ARRAY_SIZE(lu_keys); ++i) { if (ctx->lc_value[i] != NULL) { - LASSERT(keys[i] != NULL); - LASSERT(keys[i]->lct_fini != NULL); + struct lu_context_key *key; + + key = lu_keys[i]; + LASSERT(key != NULL); + LASSERT(key->lct_fini != NULL); + LASSERT(key->lct_used > 1); - keys[i]->lct_fini(ctx, ctx->lc_value[i]); + key->lct_fini(ctx, ctx->lc_value[i]); + key->lct_used--; ctx->lc_value[i] = NULL; } } - OBD_FREE(ctx->lc_value, keys_nr * sizeof ctx->lc_value[0]); + OBD_FREE(ctx->lc_value, + ARRAY_SIZE(lu_keys) * sizeof ctx->lc_value[0]); ctx->lc_value = NULL; } } @@ -450,22 +467,24 @@ static int keys_init(struct lu_context *ctx) int i; int result; - key_registration_over = 1; - - OBD_ALLOC(ctx->lc_value, keys_nr * sizeof ctx->lc_value[0]); + OBD_ALLOC(ctx->lc_value, ARRAY_SIZE(lu_keys) * sizeof ctx->lc_value[0]); if (ctx->lc_value != NULL) { - for (i = 0; i < ARRAY_SIZE(keys); ++i) { - if (keys[i] != NULL) { + for (i = 0; i < ARRAY_SIZE(lu_keys); ++i) { + struct lu_context_key *key; + + key = lu_keys[i]; + if (key != NULL) { void *value; - LASSERT(keys[i]->lct_init != NULL); - LASSERT(keys[i]->lct_index == i); + LASSERT(key->lct_init != NULL); + LASSERT(key->lct_index == i); - value = keys[i]->lct_init(ctx); + value = key->lct_init(ctx); if (IS_ERR(value)) { keys_fini(ctx); return PTR_ERR(value); } + key->lct_used++; ctx->lc_value[i] = value; } } -- 1.8.3.1