X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdclass%2Fgenops.c;h=9a9adfa4d409b018e973c10465b30180643a5705;hb=e3932b15a2aa2b6e2c99fc7449aba38c3afd526e;hp=a8c6c342cdcabc3b84b966141a5b35d2948de9de;hpb=77a5896c94f30149e4c511ec83e9aada90153d38;p=fs%2Flustre-release.git diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c index a8c6c34..9a9adfa 100644 --- a/lustre/obdclass/genops.c +++ b/lustre/obdclass/genops.c @@ -26,7 +26,7 @@ * GPL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. */ /* @@ -80,7 +80,6 @@ static struct obd_device *obd_device_alloc(void) } return obd; } -EXPORT_SYMBOL(obd_device_alloc); static void obd_device_free(struct obd_device *obd) { @@ -712,7 +711,7 @@ static void class_export_destroy(struct obd_export *exp) struct obd_device *obd = exp->exp_obd; ENTRY; - LASSERT (cfs_atomic_read(&exp->exp_refcount) == 0); + LASSERT_ATOMIC_ZERO(&exp->exp_refcount); CDEBUG(D_IOCTL, "destroying export %p/%s for %s\n", exp, exp->exp_client_uuid.uuid, obd->obd_name); @@ -751,15 +750,18 @@ EXPORT_SYMBOL(class_export_get); void class_export_put(struct obd_export *exp) { LASSERT(exp != NULL); + LASSERT_ATOMIC_GT_LT(&exp->exp_refcount, 0, 0x5a5a5a); CDEBUG(D_INFO, "PUTting export %p : new refcount %d\n", exp, cfs_atomic_read(&exp->exp_refcount) - 1); - LASSERT(cfs_atomic_read(&exp->exp_refcount) > 0); - LASSERT(cfs_atomic_read(&exp->exp_refcount) < 0x5a5a5a); if (cfs_atomic_dec_and_test(&exp->exp_refcount)) { LASSERT(!cfs_list_empty(&exp->exp_obd_chain)); CDEBUG(D_IOCTL, "final put %p/%s\n", exp, exp->exp_client_uuid.uuid); + + /* release nid stat refererence */ + lprocfs_exp_cleanup(exp); + obd_zombie_export_add(exp); } } @@ -772,6 +774,7 @@ struct obd_export *class_new_export(struct obd_device *obd, struct obd_uuid *cluuid) { struct obd_export *export; + cfs_hash_t *hash = NULL; int rc = 0; ENTRY; @@ -800,6 +803,7 @@ struct obd_export *class_new_export(struct obd_device *obd, class_handle_hash(&export->exp_handle, export_handle_addref); export->exp_last_request_time = cfs_time_current_sec(); cfs_spin_lock_init(&export->exp_lock); + cfs_spin_lock_init(&export->exp_rpc_lock); CFS_INIT_HLIST_NODE(&export->exp_uuid_hash); CFS_INIT_HLIST_NODE(&export->exp_nid_hash); @@ -811,11 +815,15 @@ struct obd_export *class_new_export(struct obd_device *obd, cfs_spin_lock(&obd->obd_dev_lock); /* shouldn't happen, but might race */ if (obd->obd_stopping) - GOTO(exit_err, rc = -ENODEV); + GOTO(exit_unlock, rc = -ENODEV); + + hash = cfs_hash_getref(obd->obd_uuid_hash); + if (hash == NULL) + GOTO(exit_unlock, rc = -ENODEV); + cfs_spin_unlock(&obd->obd_dev_lock); if (!obd_uuid_equals(cluuid, &obd->obd_uuid)) { - rc = cfs_hash_add_unique(obd->obd_uuid_hash, cluuid, - &export->exp_uuid_hash); + rc = cfs_hash_add_unique(hash, cluuid, &export->exp_uuid_hash); if (rc != 0) { LCONSOLE_WARN("%s: denying duplicate export for %s, %d\n", obd->obd_name, cluuid->uuid, rc); @@ -823,16 +831,26 @@ struct obd_export *class_new_export(struct obd_device *obd, } } + cfs_spin_lock(&obd->obd_dev_lock); + if (obd->obd_stopping) { + cfs_hash_del(hash, cluuid, &export->exp_uuid_hash); + GOTO(exit_unlock, rc = -ENODEV); + } + class_incref(obd, "export", export); cfs_list_add(&export->exp_obd_chain, &export->exp_obd->obd_exports); cfs_list_add_tail(&export->exp_obd_chain_timed, &export->exp_obd->obd_exports_timed); export->exp_obd->obd_num_exports++; cfs_spin_unlock(&obd->obd_dev_lock); + cfs_hash_putref(hash); RETURN(export); -exit_err: +exit_unlock: cfs_spin_unlock(&obd->obd_dev_lock); +exit_err: + if (hash) + cfs_hash_putref(hash); class_handle_unhash(&export->exp_handle); LASSERT(cfs_hlist_unhashed(&export->exp_uuid_hash)); obd_destroy_export(export); @@ -868,7 +886,7 @@ void class_import_destroy(struct obd_import *imp) CDEBUG(D_IOCTL, "destroying import %p for %s\n", imp, imp->imp_obd->obd_name); - LASSERT(cfs_atomic_read(&imp->imp_refcount) == 0); + LASSERT_ATOMIC_ZERO(&imp->imp_refcount); ptlrpc_put_connection_superhack(imp->imp_connection); @@ -895,8 +913,6 @@ static void import_handle_addref(void *import) struct obd_import *class_import_get(struct obd_import *import) { - LASSERT(cfs_atomic_read(&import->imp_refcount) >= 0); - LASSERT(cfs_atomic_read(&import->imp_refcount) < 0x5a5a5a); cfs_atomic_inc(&import->imp_refcount); CDEBUG(D_INFO, "import %p refcount=%d obd=%s\n", import, cfs_atomic_read(&import->imp_refcount), @@ -909,9 +925,8 @@ void class_import_put(struct obd_import *imp) { ENTRY; - LASSERT(cfs_atomic_read(&imp->imp_refcount) > 0); - LASSERT(cfs_atomic_read(&imp->imp_refcount) < 0x5a5a5a); LASSERT(cfs_list_empty(&imp->imp_zombie_chain)); + LASSERT_ATOMIC_GE_LT(&imp->imp_refcount, 0, 0x5a5a5a); CDEBUG(D_INFO, "import %p refcount=%d obd=%s\n", imp, cfs_atomic_read(&imp->imp_refcount) - 1, @@ -1063,7 +1078,7 @@ void class_export_recovery_cleanup(struct obd_export *exp) { struct obd_device *obd = exp->exp_obd; - cfs_spin_lock_bh(&obd->obd_processing_task_lock); + cfs_spin_lock(&obd->obd_recovery_task_lock); if (exp->exp_delayed) obd->obd_delayed_clients--; if (obd->obd_recovering && exp->exp_in_recovery) { @@ -1073,6 +1088,7 @@ void class_export_recovery_cleanup(struct obd_export *exp) LASSERT(obd->obd_connected_clients); obd->obd_connected_clients--; } + cfs_spin_unlock(&obd->obd_recovery_task_lock); /** Cleanup req replay fields */ if (exp->exp_req_replay_needed) { cfs_spin_lock(&exp->exp_lock); @@ -1089,7 +1105,6 @@ void class_export_recovery_cleanup(struct obd_export *exp) LASSERT(cfs_atomic_read(&obd->obd_lock_replay_clients)); cfs_atomic_dec(&obd->obd_lock_replay_clients); } - cfs_spin_unlock_bh(&obd->obd_processing_task_lock); } /* This function removes 1-3 references from the export: @@ -1440,7 +1455,7 @@ void obd_exports_barrier(struct obd_device *obd) "The obd refcount = %d. Is it stuck?\n", obd->obd_name, waited, cfs_atomic_read(&obd->obd_refcount)); - dump_exports(obd, 0); + dump_exports(obd, 1); } waited *= 2; cfs_spin_lock(&obd->obd_dev_lock); @@ -1690,3 +1705,70 @@ void obd_zombie_impexp_stop(void) #endif } +/***** Kernel-userspace comm helpers *******/ + +/* Get length of entire message, including header */ +int kuc_len(int payload_len) +{ + return sizeof(struct kuc_hdr) + payload_len; +} +EXPORT_SYMBOL(kuc_len); + +/* Get a pointer to kuc header, given a ptr to the payload + * @param p Pointer to payload area + * @returns Pointer to kuc header + */ +struct kuc_hdr * kuc_ptr(void *p) +{ + struct kuc_hdr *lh = ((struct kuc_hdr *)p) - 1; + LASSERT(lh->kuc_magic == KUC_MAGIC); + return lh; +} +EXPORT_SYMBOL(kuc_ptr); + +/* Test if payload is part of kuc message + * @param p Pointer to payload area + * @returns boolean + */ +int kuc_ispayload(void *p) +{ + struct kuc_hdr *kh = ((struct kuc_hdr *)p) - 1; + + if (kh->kuc_magic == KUC_MAGIC) + return 1; + else + return 0; +} +EXPORT_SYMBOL(kuc_ispayload); + +/* Alloc space for a message, and fill in header + * @return Pointer to payload area + */ +void *kuc_alloc(int payload_len, int transport, int type) +{ + struct kuc_hdr *lh; + int len = kuc_len(payload_len); + + OBD_ALLOC(lh, len); + if (lh == NULL) + return ERR_PTR(-ENOMEM); + + lh->kuc_magic = KUC_MAGIC; + lh->kuc_transport = transport; + lh->kuc_msgtype = type; + lh->kuc_msglen = len; + + return (void *)(lh + 1); +} +EXPORT_SYMBOL(kuc_alloc); + +/* Takes pointer to payload area */ +inline void kuc_free(void *p, int payload_len) +{ + struct kuc_hdr *lh = kuc_ptr(p); + OBD_FREE(lh, kuc_len(payload_len)); +} +EXPORT_SYMBOL(kuc_free); + + +