int __llog_ctxt_put(const struct lu_env *env, struct llog_ctxt *ctxt) { struct obd_llog_group *olg = ctxt->loc_olg; struct obd_device *obd; int rc = 0; spin_lock(&olg->olg_lock); if (!atomic_dec_and_test(&ctxt->loc_refcount)) { spin_unlock(&olg->olg_lock); return rc; } olg->olg_ctxts[ctxt->loc_idx] = NULL; spin_unlock(&olg->olg_lock); obd = ctxt->loc_obd; spin_lock(&obd->obd_dev_lock); /* sync with llog ctxt user thread */ spin_unlock(&obd->obd_dev_lock); /* 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)(env, ctxt); llog_ctxt_destroy(ctxt); wake_up(&olg->olg_waitq); return rc; }
int llog_setup(const struct lu_env *env, struct obd_device *obd, struct obd_llog_group *olg, int index, struct obd_device *disk_obd, struct llog_operations *op) { struct llog_ctxt *ctxt; int rc = 0; if (index < 0 || index >= LLOG_MAX_CTXTS) return -EINVAL; LASSERT(olg != NULL); ctxt = llog_new_ctxt(obd); if (!ctxt) return -ENOMEM; ctxt->loc_obd = obd; ctxt->loc_olg = olg; ctxt->loc_idx = index; ctxt->loc_logops = op; mutex_init(&ctxt->loc_mutex); ctxt->loc_exp = class_export_get(disk_obd->obd_self_export); ctxt->loc_flags = LLOG_CTXT_FLAG_UNINITIALIZED; rc = llog_group_set_ctxt(olg, ctxt, index); if (rc) { llog_ctxt_destroy(ctxt); if (rc == -EEXIST) { ctxt = llog_group_get_ctxt(olg, index); if (ctxt) { /* * mds_lov_update_desc() might call here multiple * times. So if the llog is already set up then * don't to do it again. */ CDEBUG(D_CONFIG, "obd %s ctxt %d already set up\n", obd->obd_name, index); LASSERT(ctxt->loc_olg == olg); LASSERT(ctxt->loc_obd == obd); LASSERT(ctxt->loc_exp == disk_obd->obd_self_export); LASSERT(ctxt->loc_logops == op); llog_ctxt_put(ctxt); } rc = 0; } return rc; } if (op->lop_setup) { if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LLOG_SETUP)) rc = -EOPNOTSUPP; else rc = op->lop_setup(env, obd, olg, index, disk_obd); } if (rc) { CERROR("%s: ctxt %d lop_setup=%p failed: rc = %d\n", obd->obd_name, index, op->lop_setup, rc); llog_group_clear_ctxt(olg, index); llog_ctxt_destroy(ctxt); } else { CDEBUG(D_CONFIG, "obd %s ctxt %d is initialized\n", obd->obd_name, index); ctxt->loc_flags &= ~LLOG_CTXT_FLAG_UNINITIALIZED; } return rc; }
int llog_setup(const struct lu_env *env, struct obd_device *obd, struct obd_llog_group *olg, int index, struct obd_device *disk_obd, struct llog_operations *op) { struct llog_ctxt *ctxt; int rc = 0; ENTRY; if (index < 0 || index >= LLOG_MAX_CTXTS) RETURN(-EINVAL); LASSERT(olg != NULL); ctxt = llog_new_ctxt(obd); if (!ctxt) RETURN(-ENOMEM); ctxt->loc_obd = obd; ctxt->loc_olg = olg; ctxt->loc_idx = index; ctxt->loc_logops = op; mutex_init(&ctxt->loc_mutex); if (disk_obd != NULL) ctxt->loc_exp = class_export_get(disk_obd->obd_self_export); else ctxt->loc_exp = class_export_get(obd->obd_self_export); ctxt->loc_flags = LLOG_CTXT_FLAG_UNINITIALIZED; ctxt->loc_chunk_size = LLOG_MIN_CHUNK_SIZE; rc = llog_group_set_ctxt(olg, ctxt, index); if (rc) { llog_ctxt_destroy(ctxt); if (rc == -EEXIST) { ctxt = llog_group_get_ctxt(olg, index); if (ctxt) { CDEBUG(D_CONFIG, "%s: ctxt %d already set up\n", obd->obd_name, index); LASSERT(ctxt->loc_olg == olg); LASSERT(ctxt->loc_obd == obd); if (disk_obd != NULL) LASSERT(ctxt->loc_exp == disk_obd->obd_self_export); else LASSERT(ctxt->loc_exp == obd->obd_self_export); LASSERT(ctxt->loc_logops == op); llog_ctxt_put(ctxt); } rc = 0; } RETURN(rc); } if (op->lop_setup) { if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LLOG_SETUP)) rc = -EOPNOTSUPP; else rc = op->lop_setup(env, obd, olg, index, disk_obd); } if (rc) { CERROR("%s: ctxt %d lop_setup=%p failed: rc = %d\n", obd->obd_name, index, op->lop_setup, rc); llog_group_clear_ctxt(olg, index); llog_ctxt_destroy(ctxt); } else { CDEBUG(D_CONFIG, "obd %s ctxt %d is initialized\n", obd->obd_name, index); ctxt->loc_flags &= ~LLOG_CTXT_FLAG_UNINITIALIZED; } RETURN(rc); }