diff --git a/lustre/lov/lov_log.c b/lustre/lov/lov_log.c index 1c47d999162c27364c1cac33398a4157173fb2a5..7a5923e084a0b0626566c298c871f1eca1c227a6 100644 --- a/lustre/lov/lov_log.c +++ b/lustre/lov/lov_log.c @@ -218,7 +218,7 @@ int lov_llog_init(struct obd_device *obd, struct obd_llog_group *olg, rc = llog_setup(obd, olg, LLOG_SIZE_REPL_CTXT, tgt, 0, NULL, &lov_size_repl_logops); if (rc) - RETURN(rc); + GOTO(err_cleanup, rc); lov_getref(obd); /* count may not match lov->desc.ld_tgt_count during dynamic ost add */ @@ -238,7 +238,18 @@ int lov_llog_init(struct obd_device *obd, struct obd_llog_group *olg, break; } lov_putref(obd); - RETURN(rc); + GOTO(err_cleanup, rc); +err_cleanup: + if (rc) { + struct llog_ctxt *ctxt = + llog_get_context(obd, LLOG_SIZE_REPL_CTXT); + if (ctxt) + llog_cleanup(ctxt); + ctxt = llog_get_context(obd, LLOG_MDS_OST_ORIG_CTXT); + if (ctxt) + llog_cleanup(ctxt); + } + return rc; } int lov_llog_finish(struct obd_device *obd, int count) diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 27e6bb0a9df6da4a57d52171c6473f3548ac5474..5bf89a25ef679ccbd28b8b4e83bef02a553e6be5 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -184,6 +184,7 @@ static int mds_lov_clean(struct obd_device *obd) static int mds_postsetup(struct obd_device *obd) { struct mds_obd *mds = &obd->u.mds; + struct llog_ctxt *ctxt; int rc = 0; ENTRY; @@ -195,7 +196,7 @@ static int mds_postsetup(struct obd_device *obd) rc = llog_setup(obd, &obd->obd_olg, LLOG_LOVEA_ORIG_CTXT, obd, 0, NULL, &llog_lvfs_ops); if (rc) - RETURN(rc); + GOTO(err_llog, rc); if (mds->mds_profile) { struct lustre_profile *lprof; @@ -218,9 +219,14 @@ static int mds_postsetup(struct obd_device *obd) err_cleanup: mds_lov_clean(obd); - llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT)); - llog_cleanup(llog_get_context(obd, LLOG_LOVEA_ORIG_CTXT)); - RETURN(rc); + ctxt = llog_get_context(obd, LLOG_LOVEA_ORIG_CTXT); + if (ctxt) + llog_cleanup(ctxt); +err_llog: + ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT); + if (ctxt) + llog_cleanup(ctxt); + return rc; } int mds_postrecov(struct obd_device *obd) diff --git a/lustre/mds/mds_log.c b/lustre/mds/mds_log.c index 0e8447ffc16f4879df325b440d0a361cd4ff6b08..705d7300be1c93ac94410090751dcb5dfb487b38 100644 --- a/lustre/mds/mds_log.c +++ b/lustre/mds/mds_log.c @@ -118,6 +118,7 @@ int mds_llog_init(struct obd_device *obd, struct obd_llog_group *olg, struct obd_uuid *uuid) { struct obd_device *lov_obd = obd->u.mds.mds_osc_obd; + struct llog_ctxt *ctxt; int rc; ENTRY; @@ -130,13 +131,24 @@ int mds_llog_init(struct obd_device *obd, struct obd_llog_group *olg, rc = llog_setup(obd, &obd->obd_olg, LLOG_SIZE_REPL_CTXT, tgt, 0, NULL, &mds_size_repl_logops); if (rc) - RETURN(rc); + GOTO(err_llog, rc); rc = obd_llog_init(lov_obd, &lov_obd->obd_olg, tgt, count, logid, uuid); - if (rc) + if (rc) { CERROR("lov_llog_init err %d\n", rc); + GOTO(err_cleanup, rc); + } RETURN(rc); +err_cleanup: + ctxt = llog_get_context(obd, LLOG_SIZE_REPL_CTXT); + if (ctxt) + llog_cleanup(ctxt); +err_llog: + ctxt = llog_get_context(obd, LLOG_MDS_OST_ORIG_CTXT); + if (ctxt) + llog_cleanup(ctxt); + return rc; } int mds_llog_finish(struct obd_device *obd, int count) diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c index bd1f214db7271df26b86fe9d584763895868830d..c99aab6eba1003441eae7ea818fd22b8effc8399 100644 --- a/lustre/mgc/mgc_request.c +++ b/lustre/mgc/mgc_request.c @@ -922,6 +922,10 @@ static int mgc_llog_init(struct obd_device *obd, struct obd_llog_group *olg, ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT); llog_initiator_connect(ctxt); llog_ctxt_put(ctxt); + } else { + ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT); + if (ctxt) + llog_cleanup(ctxt); } RETURN(rc); diff --git a/lustre/obdclass/class_hash.c b/lustre/obdclass/class_hash.c index 55b41dfe46f2ca6a62704d1402c828a42e98096e..0dd18f137d7673827bc46c8598fb58fd3590b87c 100644 --- a/lustre/obdclass/class_hash.c +++ b/lustre/obdclass/class_hash.c @@ -128,8 +128,7 @@ lustre_hash_exit(lustre_hash_t *lh) int i; ENTRY; - if (!lh) - return; + LASSERT(lh != NULL); write_lock(&lh->lh_rwlock); diff --git a/lustre/obdclass/llog_obd.c b/lustre/obdclass/llog_obd.c index 77c28eb366bdafba171e60c379a64ed66338b63b..6d24d60e532960eb84712a4e9162c9403b3b705a 100644 --- a/lustre/obdclass/llog_obd.c +++ b/lustre/obdclass/llog_obd.c @@ -94,7 +94,14 @@ int __llog_ctxt_put(struct llog_ctxt *ctxt) obd = ctxt->loc_obd; spin_lock(&obd->obd_dev_lock); spin_unlock(&obd->obd_dev_lock); /* sync with llog ctxt user thread */ - LASSERT(obd->obd_stopping == 1 || obd->obd_set_up == 0); + + /* obd->obd_starting is needed for the case of cleanup + * in error case while obd is starting up. */ + LASSERTF(obd->obd_starting == 1 || + obd->obd_stopping == 1 || obd->obd_set_up == 0, + "wrong obd state: %d/%d/%d\n", !!obd->obd_starting, + !!obd->obd_stopping, !!obd->obd_set_up); + /* cleanup the llog ctxt here */ if (CTXTP(ctxt, cleanup)) rc = CTXTP(ctxt, cleanup)(ctxt); diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index 99680431db1c3a267e66c54253d4b968ae003381..8e3a854e9d7f083ca5d8aed0048209637c641d35 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -292,23 +292,23 @@ int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg) obd->obd_uuid_hash = lustre_hash_init("UUID_HASH", 128, 128, &uuid_hash_ops, 0); if (!obd->obd_uuid_hash) - GOTO(err_hash, -ENOMEM); + GOTO(err_hash, err = -ENOMEM); /* create a nid-export lustre hash */ obd->obd_nid_hash = lustre_hash_init("NID_HASH", 128, 128, &nid_hash_ops, 0); if (!obd->obd_nid_hash) - GOTO(err_hash, -ENOMEM); + GOTO(err_hash, err = -ENOMEM); /* create a nid-stats lustre hash */ obd->obd_nid_stats_hash = lustre_hash_init("NID_STATS", 128, 128, &nid_stat_hash_ops, 0); if (!obd->obd_nid_stats_hash) - GOTO(err_hash, -ENOMEM); + GOTO(err_hash, err = -ENOMEM); exp = class_new_export(obd, &obd->obd_uuid); if (IS_ERR(exp)) - RETURN(PTR_ERR(exp)); + GOTO(err_hash, err = PTR_ERR(exp)); obd->obd_self_export = exp; list_del_init(&exp->exp_obd_chain_timed); @@ -329,17 +329,25 @@ int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg) obd->obd_name, obd->obd_uuid.uuid); RETURN(0); - err_exp: class_unlink_export(obd->obd_self_export); obd->obd_self_export = NULL; err_hash: - lustre_hash_exit(obd->obd_uuid_hash); - lustre_hash_exit(obd->obd_nid_hash); - lustre_hash_exit(obd->obd_nid_stats_hash); + if (obd->obd_uuid_hash) { + lustre_hash_exit(obd->obd_uuid_hash); + obd->obd_uuid_hash = NULL; + } + if (obd->obd_nid_hash) { + lustre_hash_exit(obd->obd_nid_hash); + obd->obd_nid_hash = NULL; + } + if (obd->obd_nid_stats_hash) { + lustre_hash_exit(obd->obd_nid_stats_hash); + obd->obd_nid_stats_hash = NULL; + } obd->obd_starting = 0; CERROR("setup %s failed (%d)\n", obd->obd_name, err); - RETURN(err); + return err; } int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg) diff --git a/lustre/obdclass/obd_mount.c b/lustre/obdclass/obd_mount.c index 9cef3236a0d8e24c26147d372f3c73e8d4485414..f55604bea620b471f6c8d4e9d1a9d627ba1a0682 100644 --- a/lustre/obdclass/obd_mount.c +++ b/lustre/obdclass/obd_mount.c @@ -167,7 +167,7 @@ struct lustre_mount_info *server_get_mount(const char *name) lsi = s2lsi(lmi->lmi_sb); mntget(lmi->lmi_mnt); atomic_inc(&lsi->lsi_mounts); - + CDEBUG(D_MOUNT, "get_mnt %p from %s, refs=%d, vfscount=%d\n", lmi->lmi_mnt, name, atomic_read(&lsi->lsi_mounts), atomic_read(&lmi->lmi_mnt->mnt_count)); @@ -1132,7 +1132,6 @@ static int server_start_targets(struct super_block *sb, struct vfsmount *mnt) if (rc) { CERROR("failed to start server %s: %d\n", lsi->lsi_ldd->ldd_svname, rc); - server_deregister_mount(lsi->lsi_ldd->ldd_svname); GOTO(out_mgc, rc); } @@ -1193,10 +1192,8 @@ static int lustre_free_lsi(struct super_block *sb) struct lustre_sb_info *lsi = s2lsi(sb); ENTRY; - if (!lsi) - RETURN(0); - - CDEBUG(D_MOUNT, "Freeing lsi\n"); + LASSERT(lsi != NULL); + CDEBUG(D_MOUNT, "Freeing lsi %p\n", lsi); /* someone didn't call server_put_mount. */ LASSERT(atomic_read(&lsi->lsi_mounts) == 0); @@ -1235,10 +1232,9 @@ static int lustre_put_lsi(struct super_block *sb) struct lustre_sb_info *lsi = s2lsi(sb); ENTRY; - LASSERT(lsi); + LASSERT(lsi != NULL); CDEBUG(D_MOUNT, "put %p %d\n", sb, atomic_read(&lsi->lsi_mounts)); - if (atomic_dec_and_test(&lsi->lsi_mounts)) { lustre_free_lsi(sb); RETURN(1); @@ -1586,9 +1582,9 @@ static int server_fill_super(struct super_block *sb) if (IS_ERR(mnt)) { rc = PTR_ERR(mnt); CERROR("Unable to mount device %s: %d\n", - lsi->lsi_lmd->lmd_dev, rc); + lsi->lsi_lmd->lmd_dev, rc); lustre_put_lsi(sb); - GOTO(out, rc); + RETURN(rc); } lsi->lsi_srv_mnt = mnt; @@ -1602,12 +1598,12 @@ static int server_fill_super(struct super_block *sb) "running. Double-mount may have compromised" " the disk journal.\n", lsi->lsi_ldd->ldd_svname); - unlock_mntput(mnt); lustre_put_lsi(sb); - GOTO(out, rc = -EALREADY); + unlock_mntput(mnt); + RETURN(-EALREADY); } - /* start MGS before MGC */ + /* Start MGS before MGC */ if (IS_MGS(lsi->lsi_ldd) && !(lsi->lsi_lmd->lmd_flags & LMD_FLG_NOMGS)) { rc = server_start_mgs(sb); if (rc) @@ -1645,11 +1641,12 @@ static int server_fill_super(struct super_block *sb) lsi->lsi_ldd->ldd_svname, lsi->lsi_lmd->lmd_dev); RETURN(0); - out_mnt: + /* We jump here in case of failure while starting targets or MGS. + * In this case we can't just put @mnt and have to do real cleanup + * with stoping targets, etc. */ server_put_super(sb); -out: - RETURN(rc); + return rc; } /* Get the index from the obd name. @@ -1945,7 +1942,7 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent) /* Figure out the lmd from the mount options */ if (lmd_parse((char *)data, lmd)) { lustre_put_lsi(sb); - RETURN(-EINVAL); + GOTO(out, rc = -EINVAL); } if (lmd_is_client(lmd)) { @@ -1954,12 +1951,13 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent) LCONSOLE_ERROR_MSG(0x165, "Nothing registered for " "client mount! Is the 'lustre' " "module loaded?\n"); + lustre_put_lsi(sb); rc = -ENODEV; } else { rc = lustre_start_mgc(sb); if (rc) { - lustre_stop_mgc(sb); - goto out; + lustre_put_lsi(sb); + GOTO(out, rc); } /* Connect and start */ /* (should always be ll_fill_super) */ @@ -1976,14 +1974,18 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent) /* s_f_s will call server_put_super on failure */ } + /* If error happens in fill_super() call, @lsi will be killed there. + * This is why we do not put it here. */ + GOTO(out, rc); out: - if (rc){ + if (rc) { CERROR("Unable to mount %s (%d)\n", s2lsi(sb) ? lmd->lmd_dev : "", rc); } else { - CDEBUG(D_SUPER, "mount %s complete\n", lmd->lmd_dev); + CDEBUG(D_SUPER, "Mount %s complete\n", + lmd->lmd_dev); } - RETURN(rc); + return rc; } diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index ec49db6d98da3dea79a5ba2229eac5bf5f03ecbc..8ce49e27bb16e7d6ae48b70a82031bd987424023 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -3866,8 +3866,14 @@ static int osc_llog_init(struct obd_device *obd, struct obd_llog_group *olg, rc = llog_setup(obd, &obd->obd_olg, LLOG_SIZE_REPL_CTXT, tgt, count, NULL, &osc_size_repl_logops); - if (rc) + if (rc) { + struct llog_ctxt *ctxt = + llog_get_context(obd, LLOG_MDS_OST_ORIG_CTXT); + if (ctxt) + llog_cleanup(ctxt); CERROR("failed LLOG_SIZE_REPL_CTXT\n"); + } + GOTO(out, rc); out: if (rc) { CERROR("osc '%s' tgt '%s' cnt %d catid %p rc=%d\n", @@ -3875,7 +3881,7 @@ out: CERROR("logid "LPX64":0x%x\n", catid->lci_logid.lgl_oid, catid->lci_logid.lgl_ogen); } - RETURN(rc); + return rc; } static int osc_llog_finish(struct obd_device *obd, int count)