From 8f61f055ebc52fb88c3bdb000cf29e746544d207 Mon Sep 17 00:00:00 2001 From: Henri Doreau Date: Mon, 24 Aug 2015 12:03:51 +0200 Subject: [PATCH] LU-7034 obd: Remove dead code in precleanup There used to be several pre-cleanup phases, but only OBD_CLEANUP_EXPORTS is actually used. Thus remove the whole notion of precleanup phases. Signed-off-by: Henri Doreau Change-Id: Id1b0922b5d2637aebd409a612c906fe9e15f00d6 Reviewed-on: http://review.whamcloud.com/16061 Tested-by: Jenkins Reviewed-by: John L. Hammond Tested-by: Maloo Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin --- lustre/include/obd.h | 128 ++++++++++++++++++++----------------------- lustre/include/obd_class.h | 43 +++++++-------- lustre/lmv/lmv_obd.c | 24 ++------ lustre/lov/lov_obd.c | 26 --------- lustre/mdc/mdc_request.c | 31 ++++------- lustre/mgc/mgc_request.c | 50 ++++++++--------- lustre/obdclass/obd_config.c | 126 +++++++++++++++++++++--------------------- lustre/ofd/ofd_obd.c | 16 +----- lustre/osc/osc_request.c | 69 +++++++++-------------- 9 files changed, 215 insertions(+), 298 deletions(-) diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 291f4b3..ca71e04 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -726,13 +726,6 @@ struct obd_device { int obd_conn_inprogress; }; -enum obd_cleanup_stage { -/* Special case hack for MDS LOVs */ - OBD_CLEANUP_EARLY, -/* can be directly mapped to .ldto_device_fini() */ - OBD_CLEANUP_EXPORTS, -}; - /* get/set_info keys */ #define KEY_ASYNC "async" #define KEY_CHANGELOG_CLEAR "changelog_clear" @@ -894,29 +887,28 @@ struct obd_ops { __u32 keylen, void *key, __u32 vallen, void *val, struct ptlrpc_request_set *set); - int (*o_setup) (struct obd_device *dev, struct lustre_cfg *cfg); - int (*o_precleanup)(struct obd_device *dev, - enum obd_cleanup_stage cleanup_stage); - int (*o_cleanup)(struct obd_device *dev); + int (*o_setup) (struct obd_device *dev, struct lustre_cfg *cfg); + int (*o_precleanup)(struct obd_device *dev); + int (*o_cleanup)(struct obd_device *dev); int (*o_process_config)(struct obd_device *dev, size_t len, void *data); - int (*o_postrecov)(struct obd_device *dev); - int (*o_add_conn)(struct obd_import *imp, struct obd_uuid *uuid, - int priority); - int (*o_del_conn)(struct obd_import *imp, struct obd_uuid *uuid); - /* connect to the target device with given connection - * data. @ocd->ocd_connect_flags is modified to reflect flags actually - * granted by the target, which are guaranteed to be a subset of flags - * asked for. If @ocd == NULL, use default parameters. */ - int (*o_connect)(const struct lu_env *env, - struct obd_export **exp, struct obd_device *src, - struct obd_uuid *cluuid, struct obd_connect_data *ocd, - void *localdata); - int (*o_reconnect)(const struct lu_env *env, - struct obd_export *exp, struct obd_device *src, - struct obd_uuid *cluuid, - struct obd_connect_data *ocd, - void *localdata); - int (*o_disconnect)(struct obd_export *exp); + int (*o_postrecov)(struct obd_device *dev); + int (*o_add_conn)(struct obd_import *imp, struct obd_uuid *uuid, + int priority); + int (*o_del_conn)(struct obd_import *imp, struct obd_uuid *uuid); + /* connect to the target device with given connection + * data. @ocd->ocd_connect_flags is modified to reflect flags actually + * granted by the target, which are guaranteed to be a subset of flags + * asked for. If @ocd == NULL, use default parameters. */ + int (*o_connect)(const struct lu_env *env, + struct obd_export **exp, struct obd_device *src, + struct obd_uuid *cluuid, struct obd_connect_data *ocd, + void *localdata); + int (*o_reconnect)(const struct lu_env *env, + struct obd_export *exp, struct obd_device *src, + struct obd_uuid *cluuid, + struct obd_connect_data *ocd, + void *localdata); + int (*o_disconnect)(struct obd_export *exp); /* Initialize/finalize fids infrastructure. */ int (*o_fid_init)(struct obd_device *obd, @@ -927,14 +919,14 @@ struct obd_ops { int (*o_fid_alloc)(const struct lu_env *env, struct obd_export *exp, struct lu_fid *fid, struct md_op_data *op_data); - /* - * Object with @fid is getting deleted, we may want to do something - * about this. - */ - int (*o_statfs)(const struct lu_env *, struct obd_export *exp, - struct obd_statfs *osfs, __u64 max_age, __u32 flags); - int (*o_statfs_async)(struct obd_export *exp, struct obd_info *oinfo, - __u64 max_age, struct ptlrpc_request_set *set); + /* + * Object with @fid is getting deleted, we may want to do something + * about this. + */ + int (*o_statfs)(const struct lu_env *, struct obd_export *exp, + struct obd_statfs *osfs, __u64 max_age, __u32 flags); + int (*o_statfs_async)(struct obd_export *exp, struct obd_info *oinfo, + __u64 max_age, struct ptlrpc_request_set *set); int (*o_create)(const struct lu_env *env, struct obd_export *exp, struct obdo *oa); int (*o_destroy)(const struct lu_env *env, struct obd_export *exp, @@ -952,37 +944,37 @@ struct obd_ops { int objcount, struct obd_ioobj *obj, struct niobuf_remote *remote, int pages, struct niobuf_local *local, int rc); - int (*o_init_export)(struct obd_export *exp); - int (*o_destroy_export)(struct obd_export *exp); - - int (*o_import_event)(struct obd_device *, struct obd_import *, - enum obd_import_event); - - int (*o_notify)(struct obd_device *obd, struct obd_device *watched, - enum obd_notify_event ev, void *data); - - int (*o_health_check)(const struct lu_env *env, struct obd_device *); - struct obd_uuid *(*o_get_uuid) (struct obd_export *exp); - - /* quota methods */ - int (*o_quotactl)(struct obd_device *, struct obd_export *, - struct obd_quotactl *); - - int (*o_ping)(const struct lu_env *, struct obd_export *exp); - - /* pools methods */ - int (*o_pool_new)(struct obd_device *obd, char *poolname); - int (*o_pool_del)(struct obd_device *obd, char *poolname); - int (*o_pool_add)(struct obd_device *obd, char *poolname, - char *ostname); - int (*o_pool_rem)(struct obd_device *obd, char *poolname, - char *ostname); - void (*o_getref)(struct obd_device *obd); - void (*o_putref)(struct obd_device *obd); - /* - * NOTE: If adding ops, add another LPROCFS_OBD_OP_INIT() line - * to lprocfs_alloc_obd_stats() in obdclass/lprocfs_status.c. - * Also, add a wrapper function in include/linux/obd_class.h. */ + int (*o_init_export)(struct obd_export *exp); + int (*o_destroy_export)(struct obd_export *exp); + + int (*o_import_event)(struct obd_device *, struct obd_import *, + enum obd_import_event); + + int (*o_notify)(struct obd_device *obd, struct obd_device *watched, + enum obd_notify_event ev, void *data); + + int (*o_health_check)(const struct lu_env *env, struct obd_device *); + struct obd_uuid *(*o_get_uuid) (struct obd_export *exp); + + /* quota methods */ + int (*o_quotactl)(struct obd_device *, struct obd_export *, + struct obd_quotactl *); + + int (*o_ping)(const struct lu_env *, struct obd_export *exp); + + /* pools methods */ + int (*o_pool_new)(struct obd_device *obd, char *poolname); + int (*o_pool_del)(struct obd_device *obd, char *poolname); + int (*o_pool_add)(struct obd_device *obd, char *poolname, + char *ostname); + int (*o_pool_rem)(struct obd_device *obd, char *poolname, + char *ostname); + void (*o_getref)(struct obd_device *obd); + void (*o_putref)(struct obd_device *obd); + /* + * NOTE: If adding ops, add another LPROCFS_OBD_OP_INIT() line + * to lprocfs_alloc_obd_stats() in obdclass/lprocfs_status.c. + * Also, add a wrapper function in include/linux/obd_class.h. */ }; /* lmv structures */ diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index 8f01ef5..cd7198d 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -593,32 +593,29 @@ static inline int obd_setup(struct obd_device *obd, struct lustre_cfg *cfg) RETURN(rc); } -static inline int obd_precleanup(struct obd_device *obd, - enum obd_cleanup_stage cleanup_stage) +static inline int obd_precleanup(struct obd_device *obd) { - int rc; - DECLARE_LU_VARS(ldt, d); - ENTRY; + int rc; + DECLARE_LU_VARS(ldt, d); + ENTRY; - OBD_CHECK_DEV(obd); - ldt = obd->obd_type->typ_lu; - d = obd->obd_lu_dev; - if (ldt != NULL && d != NULL) { - if (cleanup_stage == OBD_CLEANUP_EXPORTS) { - struct lu_env env; - - rc = lu_env_init(&env, ldt->ldt_ctx_tags); - if (rc == 0) { - ldt->ldt_ops->ldto_device_fini(&env, d); - lu_env_fini(&env); - } - } - } - OBD_CHECK_DT_OP(obd, precleanup, 0); - OBD_COUNTER_INCREMENT(obd, precleanup); + OBD_CHECK_DEV(obd); + ldt = obd->obd_type->typ_lu; + d = obd->obd_lu_dev; + if (ldt != NULL && d != NULL) { + struct lu_env env; - rc = OBP(obd, precleanup)(obd, cleanup_stage); - RETURN(rc); + rc = lu_env_init(&env, ldt->ldt_ctx_tags); + if (rc == 0) { + ldt->ldt_ops->ldto_device_fini(&env, d); + lu_env_fini(&env); + } + } + OBD_CHECK_DT_OP(obd, precleanup, 0); + OBD_COUNTER_INCREMENT(obd, precleanup); + + rc = OBP(obd, precleanup)(obd); + RETURN(rc); } static inline int obd_cleanup(struct obd_device *obd) diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index 8d90c41..5c36f49 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -2738,25 +2738,13 @@ try_next_stripe: goto retry_unlink; } -static int lmv_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) +static int lmv_precleanup(struct obd_device *obd) { - struct lmv_obd *lmv = &obd->u.lmv; - int rc = 0; - - switch (stage) { - case OBD_CLEANUP_EARLY: - /* XXX: here should be calling obd_precleanup() down to - * stack. */ - break; - case OBD_CLEANUP_EXPORTS: - fld_client_proc_fini(&lmv->lmv_fld); - lprocfs_obd_cleanup(obd); - lprocfs_free_md_stats(obd); - break; - default: - break; - } - RETURN(rc); + ENTRY; + fld_client_proc_fini(&obd->u.lmv.lmv_fld); + lprocfs_obd_cleanup(obd); + lprocfs_free_md_stats(obd); + RETURN(0); } /** diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index 73a5944..cd94f2a 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -881,31 +881,6 @@ out: return rc; } -static int lov_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) -{ - int rc = 0; - struct lov_obd *lov = &obd->u.lov; - - ENTRY; - - switch (stage) { - case OBD_CLEANUP_EARLY: { - int i; - for (i = 0; i < lov->desc.ld_tgt_count; i++) { - if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active) - continue; - obd_precleanup(class_exp2obd(lov->lov_tgts[i]->ltd_exp), - OBD_CLEANUP_EARLY); - } - break; - } - default: - break; - } - - RETURN(rc); -} - static int lov_cleanup(struct obd_device *obd) { struct lov_obd *lov = &obd->u.lov; @@ -1463,7 +1438,6 @@ static int lov_quotactl(struct obd_device *obd, struct obd_export *exp, static struct obd_ops lov_obd_ops = { .o_owner = THIS_MODULE, .o_setup = lov_setup, - .o_precleanup = lov_precleanup, .o_cleanup = lov_cleanup, .o_connect = lov_connect, .o_disconnect = lov_disconnect, diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index 06daca0..5ecae7c 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -2663,27 +2663,20 @@ static int mdc_init_ea_size(struct obd_export *exp, __u32 easize, RETURN(0); } -static int mdc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) +static int mdc_precleanup(struct obd_device *obd) { - int rc = 0; - ENTRY; + ENTRY; - switch (stage) { - case OBD_CLEANUP_EARLY: - break; - case OBD_CLEANUP_EXPORTS: - /* Failsafe, ok if racy */ - if (obd->obd_type->typ_refcnt <= 1) - libcfs_kkuc_group_rem(0, KUC_GRP_HSM); - - obd_cleanup_client_import(obd); - ptlrpc_lprocfs_unregister_obd(obd); - lprocfs_obd_cleanup(obd); - lprocfs_free_md_stats(obd); - mdc_llog_finish(obd); - break; - } - RETURN(rc); + /* Failsafe, ok if racy */ + if (obd->obd_type->typ_refcnt <= 1) + libcfs_kkuc_group_rem(0, KUC_GRP_HSM); + + obd_cleanup_client_import(obd); + ptlrpc_lprocfs_unregister_obd(obd); + lprocfs_obd_cleanup(obd); + lprocfs_free_md_stats(obd); + mdc_llog_finish(obd); + RETURN(0); } static int mdc_cleanup(struct obd_device *obd) diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c index d63999c..0df709b 100644 --- a/lustre/mgc/mgc_request.c +++ b/lustre/mgc/mgc_request.c @@ -858,36 +858,34 @@ static int mgc_llog_fini(const struct lu_env *env, struct obd_device *obd) static atomic_t mgc_count = ATOMIC_INIT(0); -static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) +static int mgc_precleanup(struct obd_device *obd) { - int rc = 0; - int temp; + int rc = 0; + int temp; ENTRY; - switch (stage) { - case OBD_CLEANUP_EARLY: - break; - case OBD_CLEANUP_EXPORTS: - if (atomic_dec_and_test(&mgc_count)) { - LASSERT(rq_state & RQ_RUNNING); - /* stop requeue thread */ - temp = RQ_STOP; - } else { - /* wakeup requeue thread to clean our cld */ - temp = RQ_NOW | RQ_PRECLEANUP; - } - spin_lock(&config_list_lock); - rq_state |= temp; - spin_unlock(&config_list_lock); - wake_up(&rq_waitq); - if (temp & RQ_STOP) - wait_for_completion(&rq_exit); - obd_cleanup_client_import(obd); - rc = mgc_llog_fini(NULL, obd); - if (rc != 0) - CERROR("failed to cleanup llogging subsystems\n"); - break; + if (atomic_dec_and_test(&mgc_count)) { + LASSERT(rq_state & RQ_RUNNING); + /* stop requeue thread */ + temp = RQ_STOP; + } else { + /* wakeup requeue thread to clean our cld */ + temp = RQ_NOW | RQ_PRECLEANUP; } + + spin_lock(&config_list_lock); + rq_state |= temp; + spin_unlock(&config_list_lock); + wake_up(&rq_waitq); + + if (temp & RQ_STOP) + wait_for_completion(&rq_exit); + obd_cleanup_client_import(obd); + + rc = mgc_llog_fini(NULL, obd); + if (rc != 0) + CERROR("failed to cleanup llogging subsystems\n"); + RETURN(rc); } diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index 222038c..2d070e8 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -612,16 +612,16 @@ EXPORT_SYMBOL(class_detach); */ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg) { - int err = 0; - char *flag; - ENTRY; + int err = 0; + char *flag; + ENTRY; - OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS); + OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS); - if (!obd->obd_set_up) { - CERROR("Device %d not setup\n", obd->obd_minor); - RETURN(-ENODEV); - } + if (!obd->obd_set_up) { + CERROR("Device %d not setup\n", obd->obd_minor); + RETURN(-ENODEV); + } spin_lock(&obd->obd_dev_lock); if (obd->obd_stopping) { @@ -638,66 +638,66 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg) yield(); smp_rmb(); - if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) { - for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++) - switch (*flag) { - case 'F': - obd->obd_force = 1; - break; - case 'A': - LCONSOLE_WARN("Failing over %s\n", - obd->obd_name); - obd->obd_fail = 1; - obd->obd_no_transno = 1; - obd->obd_no_recov = 1; - if (OBP(obd, iocontrol)) { - obd_iocontrol(OBD_IOC_SYNC, - obd->obd_self_export, - 0, NULL, NULL); - } - break; - default: - CERROR("Unrecognised flag '%c'\n", *flag); - } - } + if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) { + for (flag = lustre_cfg_string(lcfg, 1); *flag != 0; flag++) + switch (*flag) { + case 'F': + obd->obd_force = 1; + break; + case 'A': + LCONSOLE_WARN("Failing over %s\n", + obd->obd_name); + obd->obd_fail = 1; + obd->obd_no_transno = 1; + obd->obd_no_recov = 1; + if (OBP(obd, iocontrol)) { + obd_iocontrol(OBD_IOC_SYNC, + obd->obd_self_export, + 0, NULL, NULL); + } + break; + default: + CERROR("Unrecognised flag '%c'\n", *flag); + } + } - LASSERT(obd->obd_self_export); + LASSERT(obd->obd_self_export); - /* The three references that should be remaining are the - * obd_self_export and the attach and setup references. */ + /* The three references that should be remaining are the + * obd_self_export and the attach and setup references. */ if (atomic_read(&obd->obd_refcount) > 3) { - /* refcounf - 3 might be the number of real exports - (excluding self export). But class_incref is called - by other things as well, so don't count on it. */ - CDEBUG(D_IOCTL, "%s: forcing exports to disconnect: %d\n", + /* refcounf - 3 might be the number of real exports + (excluding self export). But class_incref is called + by other things as well, so don't count on it. */ + CDEBUG(D_IOCTL, "%s: forcing exports to disconnect: %d\n", obd->obd_name, atomic_read(&obd->obd_refcount) - 3); - dump_exports(obd, 0); - class_disconnect_exports(obd); - } + dump_exports(obd, 0); + class_disconnect_exports(obd); + } - /* Precleanup, we must make sure all exports get destroyed. */ - err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS); - if (err) - CERROR("Precleanup %s returned %d\n", - obd->obd_name, err); + /* Precleanup, we must make sure all exports get destroyed. */ + err = obd_precleanup(obd); + if (err) + CERROR("Precleanup %s returned %d\n", + obd->obd_name, err); - /* destroy an uuid-export hash body */ - if (obd->obd_uuid_hash) { - cfs_hash_putref(obd->obd_uuid_hash); - obd->obd_uuid_hash = NULL; - } + /* destroy an uuid-export hash body */ + if (obd->obd_uuid_hash) { + cfs_hash_putref(obd->obd_uuid_hash); + obd->obd_uuid_hash = NULL; + } - /* destroy a nid-export hash body */ - if (obd->obd_nid_hash) { - cfs_hash_putref(obd->obd_nid_hash); - obd->obd_nid_hash = NULL; - } + /* destroy a nid-export hash body */ + if (obd->obd_nid_hash) { + cfs_hash_putref(obd->obd_nid_hash); + obd->obd_nid_hash = NULL; + } - /* destroy a nid-stats hash body */ - if (obd->obd_nid_stats_hash) { - cfs_hash_putref(obd->obd_nid_stats_hash); - obd->obd_nid_stats_hash = NULL; - } + /* destroy a nid-stats hash body */ + if (obd->obd_nid_stats_hash) { + cfs_hash_putref(obd->obd_nid_stats_hash); + obd->obd_nid_stats_hash = NULL; + } /* destroy a client_generation-export hash body */ if (obd->obd_gen_hash) { @@ -705,10 +705,10 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg) obd->obd_gen_hash = NULL; } - class_decref(obd, "setup", obd); - obd->obd_set_up = 0; + class_decref(obd, "setup", obd); + obd->obd_set_up = 0; - RETURN(0); + RETURN(0); } struct obd_device *class_incref(struct obd_device *obd, diff --git a/lustre/ofd/ofd_obd.c b/lustre/ofd/ofd_obd.c index 24848f6..8bc5f50 100644 --- a/lustre/ofd/ofd_obd.c +++ b/lustre/ofd/ofd_obd.c @@ -1349,24 +1349,14 @@ static int ofd_iocontrol(unsigned int cmd, struct obd_export *exp, int len, * special actions, it just invokes target_recovery_cleanup(). * * \param[in] obd OBD device of OFD - * \param[in] stage cleanup stage * * \retval 0 */ -static int ofd_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) +static int ofd_precleanup(struct obd_device *obd) { - int rc = 0; - ENTRY; - - switch(stage) { - case OBD_CLEANUP_EARLY: - break; - case OBD_CLEANUP_EXPORTS: - target_cleanup_recovery(obd); - break; - } - RETURN(rc); + target_cleanup_recovery(obd); + RETURN(0); } /** diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 060ef0d..ecec663 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -2713,50 +2713,35 @@ out_ptlrpcd: RETURN(rc); } -static int osc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) +static int osc_precleanup(struct obd_device *obd) { - int rc = 0; - ENTRY; + struct client_obd *cli = &obd->u.cli; + ENTRY; - switch (stage) { - case OBD_CLEANUP_EARLY: { - struct obd_import *imp; - imp = obd->u.cli.cl_import; - CDEBUG(D_HA, "Deactivating import %s\n", obd->obd_name); - /* ptlrpc_abort_inflight to stop an mds_lov_synchronize */ - ptlrpc_deactivate_import(imp); - spin_lock(&imp->imp_lock); - imp->imp_pingable = 0; - spin_unlock(&imp->imp_lock); - break; - } - case OBD_CLEANUP_EXPORTS: { - struct client_obd *cli = &obd->u.cli; - /* LU-464 - * for echo client, export may be on zombie list, wait for - * zombie thread to cull it, because cli.cl_import will be - * cleared in client_disconnect_export(): - * class_export_destroy() -> obd_cleanup() -> - * echo_device_free() -> echo_client_cleanup() -> - * obd_disconnect() -> osc_disconnect() -> - * client_disconnect_export() - */ - obd_zombie_barrier(); - if (cli->cl_writeback_work) { - ptlrpcd_destroy_work(cli->cl_writeback_work); - cli->cl_writeback_work = NULL; - } - if (cli->cl_lru_work) { - ptlrpcd_destroy_work(cli->cl_lru_work); - cli->cl_lru_work = NULL; - } - obd_cleanup_client_import(obd); - ptlrpc_lprocfs_unregister_obd(obd); - lprocfs_obd_cleanup(obd); - break; - } - } - RETURN(rc); + /* LU-464 + * for echo client, export may be on zombie list, wait for + * zombie thread to cull it, because cli.cl_import will be + * cleared in client_disconnect_export(): + * class_export_destroy() -> obd_cleanup() -> + * echo_device_free() -> echo_client_cleanup() -> + * obd_disconnect() -> osc_disconnect() -> + * client_disconnect_export() + */ + obd_zombie_barrier(); + if (cli->cl_writeback_work) { + ptlrpcd_destroy_work(cli->cl_writeback_work); + cli->cl_writeback_work = NULL; + } + + if (cli->cl_lru_work) { + ptlrpcd_destroy_work(cli->cl_lru_work); + cli->cl_lru_work = NULL; + } + + obd_cleanup_client_import(obd); + ptlrpc_lprocfs_unregister_obd(obd); + lprocfs_obd_cleanup(obd); + RETURN(0); } int osc_cleanup(struct obd_device *obd) -- 1.8.3.1