X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Flod%2Flod_dev.c;h=767b8502b48ef87ec7b7cf6945d5c39c3392d6fc;hp=be0dfbf5b987c160c7c6ca18edf690556537b287;hb=c9f3efded4ef5aea926e4c67cfb0859d8592e58a;hpb=42e786f742fa3d13f7d6b66afaba63e77707015c diff --git a/lustre/lod/lod_dev.c b/lustre/lod/lod_dev.c index be0dfbf..767b850 100644 --- a/lustre/lod/lod_dev.c +++ b/lustre/lod/lod_dev.c @@ -23,7 +23,7 @@ * Copyright 2009 Sun Microsystems, Inc. All rights reserved * Use is subject to license terms. * - * Copyright (c) 2012, 2015, Intel Corporation. + * Copyright (c) 2012, 2017, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -93,7 +93,7 @@ #include #include #include -#include +#include #include #include @@ -164,7 +164,7 @@ int lod_fld_lookup(const struct lu_env *env, struct lod_device *lod, *tgt = range.lsr_index; *type = range.lsr_flags; - CDEBUG(D_INFO, "%s: got tgt %x for sequence: "LPX64"\n", + CDEBUG(D_INFO, "%s: got tgt %x for sequence: %#llx\n", lod2obd(lod)->obd_name, *tgt, fid_seq(fid)); RETURN(0); @@ -213,6 +213,7 @@ static struct lu_object *lod_object_alloc(const struct lu_env *env, if (lod_obj == NULL) RETURN(ERR_PTR(-ENOMEM)); + mutex_init(&lod_obj->ldo_layout_mutex); lu_obj = lod2lu_obj(lod_obj); dt_object_init(&lod_obj->ldo_obj, NULL, dev); lod_obj->ldo_obj.do_ops = &lod_obj_ops; @@ -316,21 +317,25 @@ static int lod_process_recovery_updates(const struct lu_env *env, if (rec->lrh_len != llog_update_record_size((struct llog_update_record *)rec)) { - CERROR("%s broken update record! index %u "DOSTID":%u :" + CERROR("%s broken update record! index %u "DFID".%u :" " rc = %d\n", lod2obd(lrd->lrd_lod)->obd_name, index, - POSTID(&llh->lgh_id.lgl_oi), rec->lrh_index, -EIO); - return -EIO; + PFID(&llh->lgh_id.lgl_oi.oi_fid), rec->lrh_index, -EIO); + return -EINVAL; } cookie->lgc_lgl = llh->lgh_id; cookie->lgc_index = rec->lrh_index; cookie->lgc_subsys = LLOG_UPDATELOG_ORIG_CTXT; - CDEBUG(D_HA, "%s: process recovery updates "DOSTID":%u\n", + CDEBUG(D_HA, "%s: process recovery updates "DFID".%u\n", lod2obd(lrd->lrd_lod)->obd_name, - POSTID(&llh->lgh_id.lgl_oi), rec->lrh_index); + PFID(&llh->lgh_id.lgl_oi.oi_fid), rec->lrh_index); lut = lod2lu_dev(lrd->lrd_lod)->ld_site->ls_tgt; + if (lut->lut_obd->obd_stopping || + lut->lut_obd->obd_abort_recovery) + return -ESHUTDOWN; + return insert_update_records_to_replay_list(lut->lut_tdtd, (struct llog_update_record *)rec, cookie, index); @@ -349,13 +354,19 @@ static int lod_process_recovery_updates(const struct lu_env *env, */ static int lod_sub_recovery_thread(void *arg) { - struct lod_recovery_data *lrd = arg; - struct lod_device *lod = lrd->lrd_lod; - struct dt_device *dt; - struct ptlrpc_thread *thread = lrd->lrd_thread; - struct llog_ctxt *ctxt; - struct lu_env env; - int rc; + struct lod_recovery_data *lrd = arg; + struct lod_device *lod = lrd->lrd_lod; + struct dt_device *dt; + struct ptlrpc_thread *thread = lrd->lrd_thread; + struct llog_ctxt *ctxt = NULL; + struct lu_env env; + struct lu_target *lut; + struct lod_tgt_descs *ltd = &lod->lod_mdt_descs; + struct lod_tgt_desc *tgt = NULL; + time64_t start; + int retries = 0; + int i; + int rc; ENTRY; thread->t_flags = SVC_RUNNING; @@ -369,24 +380,27 @@ static int lod_sub_recovery_thread(void *arg) RETURN(rc); } + lut = lod2lu_dev(lod)->ld_site->ls_tgt; + atomic_inc(&lut->lut_tdtd->tdtd_recovery_threads_count); if (lrd->lrd_ltd == NULL) dt = lod->lod_child; else dt = lrd->lrd_ltd->ltd_tgt; + start = ktime_get_real_seconds(); + again: rc = lod_sub_prep_llog(&env, lod, dt, lrd->lrd_idx); - if (rc != 0) - GOTO(out, rc); - - /* Process the recovery record */ - ctxt = llog_get_context(dt->dd_lu_dev.ld_obd, LLOG_UPDATELOG_ORIG_CTXT); - LASSERT(ctxt != NULL); - LASSERT(ctxt->loc_handle != NULL); - - rc = llog_cat_process(&env, ctxt->loc_handle, - lod_process_recovery_updates, lrd, 0, 0); - llog_ctxt_put(ctxt); + if (!rc && !lod->lod_child->dd_rdonly) { + /* Process the recovery record */ + ctxt = llog_get_context(dt->dd_lu_dev.ld_obd, + LLOG_UPDATELOG_ORIG_CTXT); + LASSERT(ctxt != NULL); + LASSERT(ctxt->loc_handle != NULL); + + rc = llog_cat_process(&env, ctxt->loc_handle, + lod_process_recovery_updates, lrd, 0, 0); + } if (rc < 0) { struct lu_device *top_device; @@ -394,54 +408,74 @@ again: top_device = lod->lod_dt_dev.dd_lu_dev.ld_site->ls_top_dev; /* Because the remote target might failover at the same time, * let's retry here */ - if (rc == -ETIMEDOUT && dt != lod->lod_child && - !top_device->ld_obd->obd_force_abort_recovery) + if ((rc == -ETIMEDOUT || rc == -EAGAIN || rc == -EIO) && + dt != lod->lod_child && + !top_device->ld_obd->obd_abort_recovery && + !top_device->ld_obd->obd_stopping) { + if (ctxt != NULL) { + if (ctxt->loc_handle != NULL) + llog_cat_close(&env, + ctxt->loc_handle); + llog_ctxt_put(ctxt); + } + retries++; + CDEBUG(D_HA, "%s get update log failed %d, retry\n", + dt->dd_lu_dev.ld_obd->obd_name, rc); goto again; + } - CERROR("%s getting update log failed: rc = %d\n", + CERROR("%s get update log failed: rc = %d\n", dt->dd_lu_dev.ld_obd->obd_name, rc); + llog_ctxt_put(ctxt); + + spin_lock(&top_device->ld_obd->obd_dev_lock); + if (!top_device->ld_obd->obd_abort_recovery && + !top_device->ld_obd->obd_stopping) + top_device->ld_obd->obd_abort_recovery = 1; + spin_unlock(&top_device->ld_obd->obd_dev_lock); + GOTO(out, rc); } + llog_ctxt_put(ctxt); - CDEBUG(D_HA, "%s retrieve update log: rc = %d\n", - dt->dd_lu_dev.ld_obd->obd_name, rc); + CDEBUG(D_HA, "%s retrieved update log, duration %lld, retries %d\n", + dt->dd_lu_dev.ld_obd->obd_name, ktime_get_real_seconds() - start, + retries); + spin_lock(&lod->lod_lock); if (lrd->lrd_ltd == NULL) lod->lod_child_got_update_log = 1; else lrd->lrd_ltd->ltd_got_update_log = 1; - if (lod->lod_child_got_update_log) { - struct lod_tgt_descs *ltd = &lod->lod_mdt_descs; - struct lod_tgt_desc *tgt = NULL; - bool all_got_log = true; - int i; - - cfs_foreach_bit(ltd->ltd_tgt_bitmap, i) { - tgt = LTD_TGT(ltd, i); - if (!tgt->ltd_got_update_log) { - all_got_log = false; - break; - } - } - - if (all_got_log) { - struct lu_target *lut; + if (!lod->lod_child_got_update_log) { + spin_unlock(&lod->lod_lock); + GOTO(out, rc = 0); + } - lut = lod2lu_dev(lod)->ld_site->ls_tgt; - CDEBUG(D_HA, "%s got update logs from all MDTs.\n", - lut->lut_obd->obd_name); - lut->lut_tdtd->tdtd_replay_ready = 1; - wake_up(&lut->lut_obd->obd_next_transno_waitq); + cfs_foreach_bit(ltd->ltd_tgt_bitmap, i) { + tgt = LTD_TGT(ltd, i); + if (!tgt->ltd_got_update_log) { + spin_unlock(&lod->lod_lock); + GOTO(out, rc = 0); } } + lut->lut_tdtd->tdtd_replay_ready = 1; + spin_unlock(&lod->lod_lock); + + CDEBUG(D_HA, "%s got update logs from all MDTs.\n", + lut->lut_obd->obd_name); + wake_up(&lut->lut_obd->obd_next_transno_waitq); + EXIT; out: OBD_FREE_PTR(lrd); thread->t_flags = SVC_STOPPED; + atomic_dec(&lut->lut_tdtd->tdtd_recovery_threads_count); + wake_up(&lut->lut_tdtd->tdtd_recovery_threads_waitq); wake_up(&thread->t_ctl_waitq); lu_env_fini(&env); - RETURN(rc); + return rc; } /** @@ -714,6 +748,57 @@ static void lod_sub_fini_all_llogs(const struct lu_env *env, lod_putref(lod, ltd); } +static char *lod_show_update_logs_retrievers(void *data, int *size, int *count) +{ + struct lod_device *lod = (struct lod_device *)data; + struct lu_target *lut = lod2lu_dev(lod)->ld_site->ls_tgt; + struct lod_tgt_descs *ltd = &lod->lod_mdt_descs; + struct lod_tgt_desc *tgt = NULL; + char *buf; + int len = 0; + int rc; + int i; + + *count = atomic_read(&lut->lut_tdtd->tdtd_recovery_threads_count); + if (*count == 0) { + *size = 0; + return NULL; + } + + *size = 5 * *count + 1; + OBD_ALLOC(buf, *size); + if (buf == NULL) + return NULL; + + *count = 0; + memset(buf, 0, *size); + + if (!lod->lod_child_got_update_log) { + rc = lodname2mdt_index(lod2obd(lod)->obd_name, &i); + LASSERTF(rc == 0, "Fail to parse target index: rc = %d\n", rc); + + rc = snprintf(buf + len, *size - len, " %04x", i); + LASSERT(rc > 0); + + len += rc; + (*count)++; + } + + cfs_foreach_bit(ltd->ltd_tgt_bitmap, i) { + tgt = LTD_TGT(ltd, i); + if (!tgt->ltd_got_update_log) { + rc = snprintf(buf + len, *size - len, " %04x", i); + if (unlikely(rc <= 0)) + break; + + len += rc; + (*count)++; + } + } + + return buf; +} + /** * Prepare distribute txn * @@ -750,6 +835,10 @@ static int lod_prepare_distribute_txn(const struct lu_env *env, RETURN(rc); } + tdtd->tdtd_show_update_logs_retrievers = + lod_show_update_logs_retrievers; + tdtd->tdtd_show_retrievers_cbdata = lod; + lut->lut_tdtd = tdtd; RETURN(0); @@ -770,6 +859,7 @@ static void lod_fini_distribute_txn(const struct lu_env *env, struct lu_target *lut; lut = lod2lu_dev(lod)->ld_site->ls_tgt; + target_recovery_fini(lut->lut_obd); if (lut->lut_tdtd == NULL) return; @@ -871,6 +961,7 @@ static int lod_process_config(const struct lu_env *env, case LCFG_PARAM: { struct obd_device *obd; + ssize_t count; char *param; /* Check if it is activate/deactivate mdc @@ -942,11 +1033,14 @@ static int lod_process_config(const struct lu_env *env, GOTO(out, rc); } - obd = lod2obd(lod); - rc = class_process_proc_param(PARAM_LOV, obd->obd_vars, - lcfg, obd); - if (rc > 0) - rc = 0; + + if (strstr(param, PARAM_LOD) != NULL) + count = class_modify_config(lcfg, PARAM_LOD, + &lod->lod_dt_dev.dd_kobj); + else + count = class_modify_config(lcfg, PARAM_LOV, + &lod->lod_dt_dev.dd_kobj); + rc = count > 0 ? 0 : count; GOTO(out, rc); } case LCFG_PRE_CLEANUP: { @@ -964,6 +1058,11 @@ static int lod_process_config(const struct lu_env *env, break; } case LCFG_CLEANUP: { + if (lod->lod_md_root != NULL) { + dt_object_put(env, &lod->lod_md_root->ldo_obj); + lod->lod_md_root = NULL; + } + /* * do cleanup on underlying storage only when * all OSPs are cleaned up, as they use that OSD as well @@ -1117,7 +1216,7 @@ static int lod_prepare(const struct lu_env *env, struct lu_device *pdev, if (IS_ERR(dto)) GOTO(out_put, rc = PTR_ERR(dto)); - lu_object_put(env, &dto->do_lu); + dt_object_put(env, dto); /* Create update log dir */ lu_update_log_dir_fid(fid, index); @@ -1128,7 +1227,7 @@ static int lod_prepare(const struct lu_env *env, struct lu_device *pdev, if (IS_ERR(dto)) GOTO(out_put, rc = PTR_ERR(dto)); - lu_object_put(env, &dto->do_lu); + dt_object_put(env, dto); rc = lod_prepare_distribute_txn(env, lod); if (rc != 0) @@ -1139,7 +1238,7 @@ static int lod_prepare(const struct lu_env *env, struct lu_device *pdev, GOTO(out_put, rc); out_put: - lu_object_put(env, &root->do_lu); + dt_object_put(env, root); RETURN(rc); } @@ -1162,6 +1261,30 @@ static int lod_root_get(const struct lu_env *env, return dt_root_get(env, dt2lod_dev(dev)->lod_child, f); } +static void lod_statfs_sum(struct obd_statfs *sfs, + struct obd_statfs *ost_sfs, int *bs) +{ + while (ost_sfs->os_bsize < *bs) { + *bs >>= 1; + sfs->os_bsize >>= 1; + sfs->os_bavail <<= 1; + sfs->os_blocks <<= 1; + sfs->os_bfree <<= 1; + sfs->os_granted <<= 1; + } + while (ost_sfs->os_bsize > *bs) { + ost_sfs->os_bsize >>= 1; + ost_sfs->os_bavail <<= 1; + ost_sfs->os_blocks <<= 1; + ost_sfs->os_bfree <<= 1; + ost_sfs->os_granted <<= 1; + } + sfs->os_bavail += ost_sfs->os_bavail; + sfs->os_blocks += ost_sfs->os_blocks; + sfs->os_bfree += ost_sfs->os_bfree; + sfs->os_granted += ost_sfs->os_granted; +} + /** * Implementation of dt_device_operations::dt_statfs() for LOD * @@ -1170,7 +1293,73 @@ static int lod_root_get(const struct lu_env *env, static int lod_statfs(const struct lu_env *env, struct dt_device *dev, struct obd_statfs *sfs) { - return dt_statfs(env, dt2lod_dev(dev)->lod_child, sfs); + struct lod_device *lod = dt2lod_dev(dev); + struct lod_ost_desc *ost; + struct lod_mdt_desc *mdt; + struct obd_statfs ost_sfs; + int i, rc, bs; + bool mdtonly; + + rc = dt_statfs(env, dt2lod_dev(dev)->lod_child, sfs); + if (rc) + GOTO(out, rc); + + bs = sfs->os_bsize; + + sfs->os_bavail = 0; + sfs->os_blocks = 0; + sfs->os_bfree = 0; + sfs->os_granted = 0; + + lod_getref(&lod->lod_mdt_descs); + lod_foreach_mdt(lod, i) { + mdt = MDT_TGT(lod, i); + LASSERT(mdt && mdt->ltd_mdt); + rc = dt_statfs(env, mdt->ltd_mdt, &ost_sfs); + /* ignore errors */ + if (rc) + continue; + sfs->os_files += ost_sfs.os_files; + sfs->os_ffree += ost_sfs.os_ffree; + lod_statfs_sum(sfs, &ost_sfs, &bs); + } + lod_putref(lod, &lod->lod_mdt_descs); + + /* at some point we can check whether DoM is enabled and + * decide how to account MDT space. for simplicity let's + * just fallback to pre-DoM policy if any OST is alive */ + mdtonly = true; + + lod_getref(&lod->lod_ost_descs); + lod_foreach_ost(lod, i) { + ost = OST_TGT(lod, i); + LASSERT(ost && ost->ltd_ost); + rc = dt_statfs(env, ost->ltd_ost, &ost_sfs); + /* ignore errors */ + if (rc || ost_sfs.os_bsize == 0) + continue; + if (mdtonly) { + /* if only MDTs and DoM report MDT space, + * otherwise only OST space */ + sfs->os_bavail = 0; + sfs->os_blocks = 0; + sfs->os_bfree = 0; + sfs->os_granted = 0; + mdtonly = false; + } + ost_sfs.os_bavail += ost_sfs.os_granted; + lod_statfs_sum(sfs, &ost_sfs, &bs); + LASSERTF(bs == ost_sfs.os_bsize, "%d != %d\n", + (int)sfs->os_bsize, (int)ost_sfs.os_bsize); + } + lod_putref(lod, &lod->lod_ost_descs); + sfs->os_state |= OS_STATE_SUM; + + /* a single successful statfs should be enough */ + rc = 0; + +out: + RETURN(rc); } /** @@ -1299,6 +1488,7 @@ static int lod_sync(const struct lu_env *env, struct dt_device *dev) { struct lod_device *lod = dt2lod_dev(dev); struct lod_ost_desc *ost; + struct lod_mdt_desc *mdt; unsigned int i; int rc = 0; ENTRY; @@ -1307,14 +1497,41 @@ static int lod_sync(const struct lu_env *env, struct dt_device *dev) lod_foreach_ost(lod, i) { ost = OST_TGT(lod, i); LASSERT(ost && ost->ltd_ost); + if (!ost->ltd_active) + continue; rc = dt_sync(env, ost->ltd_ost); if (rc) { - CERROR("%s: can't sync %u: %d\n", - lod2obd(lod)->obd_name, i, rc); - break; + if (rc != -ENOTCONN) { + CERROR("%s: can't sync ost %u: %d\n", + lod2obd(lod)->obd_name, i, rc); + break; + } + rc = 0; } } lod_putref(lod, &lod->lod_ost_descs); + + if (rc) + RETURN(rc); + + lod_getref(&lod->lod_mdt_descs); + lod_foreach_mdt(lod, i) { + mdt = MDT_TGT(lod, i); + LASSERT(mdt && mdt->ltd_mdt); + if (!mdt->ltd_active) + continue; + rc = dt_sync(env, mdt->ltd_mdt); + if (rc) { + if (rc != -ENOTCONN) { + CERROR("%s: can't sync mdt %u: %d\n", + lod2obd(lod)->obd_name, i, rc); + break; + } + rc = 0; + } + } + lod_putref(lod, &lod->lod_mdt_descs); + if (rc == 0) rc = dt_sync(env, lod->lod_child); @@ -1527,6 +1744,7 @@ static int lod_init0(const struct lu_env *env, struct lod_device *lod, dt_conf_get(env, &lod->lod_dt_dev, &ddp); lod->lod_osd_max_easize = ddp.ddp_max_ea_size; + lod->lod_dom_max_stripesize = (1ULL << 20); /* 1Mb as default value */ /* setup obd to be used with old lov code */ rc = lod_pools_init(lod, cfg); @@ -1537,7 +1755,7 @@ static int lod_init0(const struct lu_env *env, struct lod_device *lod, if (rc) GOTO(out_pools, rc); - spin_lock_init(&lod->lod_desc_lock); + spin_lock_init(&lod->lod_lock); spin_lock_init(&lod->lod_connects_lock); lod_tgt_desc_init(&lod->lod_mdt_descs); lod_tgt_desc_init(&lod->lod_ost_descs); @@ -1565,6 +1783,11 @@ static struct lu_device *lod_device_free(const struct lu_env *env, struct lu_device *next = &lod->lod_child->dd_lu_dev; ENTRY; + if (atomic_read(&lu->ld_ref) > 0 && + !cfs_hash_is_empty(lu->ld_site->ls_obj_hash)) { + LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_ERROR, NULL); + lu_site_print(env, lu->ld_site, &msgdata, lu_cdebug_printer); + } LASSERTF(atomic_read(&lu->ld_ref) == 0, "lu is %p\n", lu); dt_device_fini(&lod->lod_dt_dev); OBD_FREE_PTR(lod); @@ -1603,6 +1826,15 @@ static struct lu_device *lod_device_alloc(const struct lu_env *env, return lu_dev; } +static void lod_avoid_guide_fini(struct lod_avoid_guide *lag) +{ + if (lag->lag_oss_avoid_array) + OBD_FREE(lag->lag_oss_avoid_array, + sizeof(__u32) * lag->lag_oaa_size); + if (lag->lag_ost_avoid_bitmap) + CFS_FREE_BITMAP(lag->lag_ost_avoid_bitmap); +} + /** * Implementation of lu_device_type_operations::ldto_device_fini() for LOD * @@ -1725,6 +1957,9 @@ static void lod_key_fini(const struct lu_context *ctx, struct lu_context_key *key, void *data) { struct lod_thread_info *info = data; + struct lod_layout_component *lds = + info->lti_def_striping.lds_def_comp_entries; + /* allocated in lod_get_lov_ea * XXX: this is overload, a tread may have such store but used only * once. Probably better would be pool of such stores per LOD. @@ -1735,6 +1970,16 @@ static void lod_key_fini(const struct lu_context *ctx, info->lti_ea_store_size = 0; } lu_buf_free(&info->lti_linkea_buf); + + if (lds != NULL) + lod_free_def_comp_entries(&info->lti_def_striping); + + if (info->lti_comp_size > 0) + OBD_FREE(info->lti_comp_idx, + info->lti_comp_size * sizeof(__u32)); + + lod_avoid_guide_fini(&info->lti_avoid); + OBD_FREE_PTR(info); } @@ -1898,7 +2143,7 @@ static int lod_obd_set_info_async(const struct lu_env *env, if (no_set) { - rc2 = ptlrpc_set_wait(set); + rc2 = ptlrpc_set_wait(env, set); if (rc2 == 0 && rc == 0) rc = rc2; ptlrpc_set_destroy(set); @@ -1918,9 +2163,14 @@ static struct obd_ops lod_obd_device_ops = { .o_pool_del = lod_pool_del, }; -static int __init lod_mod_init(void) +static struct obd_type sym; + +static int __init lod_init(void) { + struct dentry *symlink; struct obd_type *type; + struct kobject *kobj; + struct qstr dname; int rc; rc = lu_kmem_init(lod_caches); @@ -1934,10 +2184,42 @@ static int __init lod_mod_init(void) return rc; } - /* create "lov" entry in procfs for compatibility purposes */ + /* create "lov" entry for compatibility purposes */ + dname.name = "lov"; + dname.len = strlen(dname.name); + dname.hash = ll_full_name_hash(debugfs_lustre_root, dname.name, + dname.len); + symlink = d_lookup(debugfs_lustre_root, &dname); + if (!symlink) { + symlink = debugfs_create_dir(dname.name, debugfs_lustre_root); + if (IS_ERR_OR_NULL(symlink)) { + rc = symlink ? PTR_ERR(symlink) : -ENOMEM; + GOTO(no_lov, rc); + } + sym.typ_debugfs_entry = symlink; + } else { + dput(symlink); + } + + kobj = kset_find_obj(lustre_kset, dname.name); + if (kobj) { + kobject_put(kobj); + goto try_proc; + } + + kobj = class_setup_tunables(dname.name); + if (IS_ERR(kobj)) { + rc = PTR_ERR(kobj); + if (sym.typ_debugfs_entry) + ldebugfs_remove(&sym.typ_debugfs_entry); + GOTO(no_lov, rc); + } + sym.typ_kobj = kobj; + +try_proc: type = class_search_type(LUSTRE_LOV_NAME); if (type != NULL && type->typ_procroot != NULL) - return rc; + GOTO(no_lov, rc); type = class_search_type(LUSTRE_LOD_NAME); type->typ_procsym = lprocfs_register("lov", proc_lustre_root, @@ -1947,11 +2229,14 @@ static int __init lod_mod_init(void) (int)PTR_ERR(type->typ_procsym)); type->typ_procsym = NULL; } +no_lov: return rc; } -static void __exit lod_mod_exit(void) +static void __exit lod_exit(void) { + ldebugfs_remove(&sym.typ_debugfs_entry); + kobject_put(sym.typ_kobj); class_unregister_type(LUSTRE_LOD_NAME); lu_kmem_fini(lod_caches); } @@ -1961,6 +2246,5 @@ MODULE_DESCRIPTION("Lustre Logical Object Device ("LUSTRE_LOD_NAME")"); MODULE_VERSION(LUSTRE_VERSION_STRING); MODULE_LICENSE("GPL"); -module_init(lod_mod_init); -module_exit(lod_mod_exit); - +module_init(lod_init); +module_exit(lod_exit);