/* Test named-log create/open, close */ static int llog_test_1(struct obd_device *obd, char *name) { struct llog_handle *llh; struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT); int rc; int rc2; ENTRY; CWARN("1a: create a log with name: %s\n", name); LASSERT(ctxt); rc = llog_create(ctxt, &llh, NULL, name); if (rc) { CERROR("1a: llog_create with name %s failed: %d\n", name, rc); llog_ctxt_put(ctxt); RETURN(rc); } llog_init_handle(llh, LLOG_F_IS_PLAIN, &uuid); if ((rc = verify_handle("1", llh, 1))) GOTO(out, rc); out: CWARN("1b: close newly-created log\n"); rc2 = llog_close(llh); llog_ctxt_put(ctxt); if (rc2) { CERROR("1b: close log %s failed: %d\n", name, rc2); if (rc == 0) rc = rc2; } RETURN(rc); }
static int mdd_changelog_users_seq_show(struct seq_file *m, void *data) { struct lu_env env; struct mdd_device *mdd = m->private; struct llog_ctxt *ctxt; __u64 cur; int rc; ctxt = llog_get_context(mdd2obd_dev(mdd), LLOG_CHANGELOG_USER_ORIG_CTXT); if (ctxt == NULL) return -ENXIO; LASSERT(ctxt->loc_handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT); rc = lu_env_init(&env, LCT_LOCAL); if (rc) { llog_ctxt_put(ctxt); return rc; } spin_lock(&mdd->mdd_cl.mc_lock); cur = mdd->mdd_cl.mc_index; spin_unlock(&mdd->mdd_cl.mc_lock); seq_printf(m, "current index: %llu\n", cur); seq_printf(m, "%-5s %s\n", "ID", "index"); llog_cat_process(&env, ctxt->loc_handle, lprocfs_changelog_users_cb, m, 0, 0); lu_env_fini(&env); llog_ctxt_put(ctxt); return 0; }
/* Add log records for each OSC that this object is striped over, and return * cookies for each one. We _would_ have nice abstraction here, except that * we need to keep cookies in stripe order, even if some are NULL, so that * the right cookies are passed back to the right OSTs at the client side. * Unset cookies should be all-zero (which will never occur naturally). */ static int lov_llog_origin_add(const struct lu_env *env, struct llog_ctxt *ctxt, struct llog_rec_hdr *rec, struct lov_stripe_md *lsm, struct llog_cookie *logcookies, int numcookies) { struct obd_device *obd = ctxt->loc_obd; struct lov_obd *lov = &obd->u.lov; int i, rc = 0, cookies = 0; ENTRY; LASSERTF(logcookies && numcookies >= lsm->lsm_stripe_count, "logcookies %p, numcookies %d lsm->lsm_stripe_count %d \n", logcookies, numcookies, lsm->lsm_stripe_count); for (i = 0; i < lsm->lsm_stripe_count; i++) { struct lov_oinfo *loi = lsm->lsm_oinfo[i]; struct obd_device *child = lov->lov_tgts[loi->loi_ost_idx]->ltd_exp->exp_obd; struct llog_ctxt *cctxt = llog_get_context(child, ctxt->loc_idx); /* fill mds unlink/setattr log record */ switch (rec->lrh_type) { case MDS_UNLINK_REC: { struct llog_unlink_rec *lur = (struct llog_unlink_rec *)rec; lur->lur_oid = ostid_id(&loi->loi_oi); lur->lur_oseq = (__u32)ostid_seq(&loi->loi_oi); break; } case MDS_SETATTR64_REC: { struct llog_setattr64_rec *lsr = (struct llog_setattr64_rec *)rec; lsr->lsr_oi = loi->loi_oi; break; } default: break; } /* inject error in llog_obd_add() below */ if (OBD_FAIL_CHECK(OBD_FAIL_MDS_FAIL_LOV_LOG_ADD)) { llog_ctxt_put(cctxt); cctxt = NULL; } rc = llog_obd_add(env, cctxt, rec, NULL, logcookies + cookies, numcookies - cookies); llog_ctxt_put(cctxt); if (rc < 0) { CERROR("Can't add llog (rc = %d) for stripe %d\n", rc, cookies); memset(logcookies + cookies, 0, sizeof(struct llog_cookie)); rc = 1; /* skip this cookie */ } /* Note that rc is always 1 if llog_obd_add was successful */ cookies += rc; } RETURN(cookies); }
int llog_origin_handle_next_block(struct ptlrpc_request *req) { struct llog_handle *loghandle; struct llogd_body *body; struct llogd_body *repbody; struct llog_ctxt *ctxt; __u32 flags; void *ptr; int rc; ENTRY; body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY); if (body == NULL) RETURN(err_serious(-EFAULT)); req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER, LLOG_MIN_CHUNK_SIZE); rc = req_capsule_server_pack(&req->rq_pill); if (rc) RETURN(err_serious(-ENOMEM)); if (body->lgd_ctxt_idx >= LLOG_MAX_CTXTS) { CDEBUG(D_WARNING, "%s: bad ctxt ID: idx=%d\n", req->rq_export->exp_obd->obd_name, body->lgd_ctxt_idx); RETURN(-EPROTO); } ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx); if (ctxt == NULL) RETURN(-ENODEV); rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle, &body->lgd_logid, NULL, LLOG_OPEN_EXISTS); if (rc) GOTO(out_ctxt, rc); flags = body->lgd_llh_flags; rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags, NULL); if (rc) GOTO(out_close, rc); repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY); *repbody = *body; ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA); rc = llog_next_block(req->rq_svc_thread->t_env, loghandle, &repbody->lgd_saved_index, repbody->lgd_index, &repbody->lgd_cur_offset, ptr, LLOG_MIN_CHUNK_SIZE); if (rc) GOTO(out_close, rc); EXIT; out_close: llog_origin_close(req->rq_svc_thread->t_env, loghandle); out_ctxt: llog_ctxt_put(ctxt); return rc; }
static int mds_llog_add_unlink(struct obd_device *obd, struct lov_stripe_md *lsm, obd_count count, struct llog_cookie *logcookie, int cookies) { struct llog_unlink_rec *lur; struct llog_ctxt *ctxt; int rc; if (cookies < lsm->lsm_stripe_count) RETURN(rc = -EFBIG); /* first prepare unlink log record */ OBD_ALLOC_PTR(lur); if (!lur) RETURN(rc = -ENOMEM); lur->lur_hdr.lrh_len = lur->lur_tail.lrt_len = sizeof(*lur); lur->lur_hdr.lrh_type = MDS_UNLINK_REC; lur->lur_count = count; ctxt = llog_get_context(obd, LLOG_MDS_OST_ORIG_CTXT); rc = llog_add(ctxt, &lur->lur_hdr, lsm, logcookie, cookies); llog_ctxt_put(ctxt); OBD_FREE_PTR(lur); RETURN(rc); }
int llog_origin_handle_destroy(struct ptlrpc_request *req) { struct llogd_body *body; struct llog_logid *logid = NULL; struct llog_ctxt *ctxt; int rc; ENTRY; body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY); if (body == NULL) RETURN(err_serious(-EFAULT)); rc = req_capsule_server_pack(&req->rq_pill); if (rc < 0) RETURN(err_serious(-ENOMEM)); if (ostid_id(&body->lgd_logid.lgl_oi) > 0) logid = &body->lgd_logid; if (!(body->lgd_llh_flags & LLOG_F_IS_PLAIN)) CERROR("%s: wrong llog flags %x\n", req->rq_export->exp_obd->obd_name, body->lgd_llh_flags); ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx); if (ctxt == NULL) RETURN(-ENODEV); rc = llog_erase(req->rq_svc_thread->t_env, ctxt, logid, NULL); llog_ctxt_put(ctxt); RETURN(rc); }
static int llog_osd_setup(const struct lu_env *env, struct obd_device *obd, struct obd_llog_group *olg, int ctxt_idx, struct obd_device *disk_obd) { struct local_oid_storage *los; struct llog_thread_info *lgi = llog_info(env); struct llog_ctxt *ctxt; int rc = 0; ENTRY; LASSERT(obd); LASSERT(olg->olg_ctxts[ctxt_idx]); ctxt = llog_ctxt_get(olg->olg_ctxts[ctxt_idx]); LASSERT(ctxt); /* initialize data allowing to generate new fids, * literally we need a sequece */ lgi->lgi_fid.f_seq = FID_SEQ_LLOG; lgi->lgi_fid.f_oid = 1; lgi->lgi_fid.f_ver = 0; rc = local_oid_storage_init(env, disk_obd->obd_lvfs_ctxt.dt, &lgi->lgi_fid, &los); llog_ctxt_put(ctxt); return rc; }
static int lov_llog_origin_connect(struct llog_ctxt *ctxt, struct llog_logid *logid, struct llog_gen *gen, struct obd_uuid *uuid) { struct obd_device *obd = ctxt->loc_obd; struct lov_obd *lov = &obd->u.lov; int i, rc = 0, err = 0; ENTRY; obd_getref(obd); for (i = 0; i < lov->desc.ld_tgt_count; i++) { struct obd_device *child; struct llog_ctxt *cctxt; if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active) continue; if (uuid && !obd_uuid_equals(uuid, &lov->lov_tgts[i]->ltd_uuid)) continue; CDEBUG(D_CONFIG, "connect %d/%d\n", i, lov->desc.ld_tgt_count); child = lov->lov_tgts[i]->ltd_exp->exp_obd; cctxt = llog_get_context(child, ctxt->loc_idx); rc = llog_connect(cctxt, logid, gen, uuid); llog_ctxt_put(cctxt); if (rc) { CERROR("error osc_llog_connect tgt %d (%d)\n", i, rc); if (!err) err = rc; } } obd_putref(obd); RETURN(err); }
int llog_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt) { struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL); struct obd_llog_group *olg; int rc, idx; LASSERT(ctxt != NULL); LASSERT(ctxt != LP_POISON); olg = ctxt->loc_olg; LASSERT(olg != NULL); LASSERT(olg != LP_POISON); idx = ctxt->loc_idx; /* * Banlance the ctxt get when calling llog_cleanup() */ LASSERT(atomic_read(&ctxt->loc_refcount) < LI_POISON); LASSERT(atomic_read(&ctxt->loc_refcount) > 1); llog_ctxt_put(ctxt); /* * Try to free the ctxt. */ rc = __llog_ctxt_put(env, ctxt); if (rc) CERROR("Error %d while cleaning up ctxt %p\n", rc, ctxt); l_wait_event(olg->olg_waitq, llog_group_ctxt_null(olg, idx), &lwi); return rc; }
static int mdd_changelog_user_purge(const struct lu_env *env, struct mdd_device *mdd, int id, long long endrec) { struct mdd_changelog_user_data data; struct llog_ctxt *ctxt; int rc; ENTRY; CDEBUG(D_IOCTL, "Purge request: id=%d, endrec=%lld\n", id, endrec); data.mcud_id = id; data.mcud_minid = 0; data.mcud_minrec = 0; data.mcud_usercount = 0; data.mcud_endrec = endrec; spin_lock(&mdd->mdd_cl.mc_lock); endrec = mdd->mdd_cl.mc_index; spin_unlock(&mdd->mdd_cl.mc_lock); if ((data.mcud_endrec == 0) || ((data.mcud_endrec > endrec) && (data.mcud_endrec != MCUD_UNREGISTER))) data.mcud_endrec = endrec; ctxt = llog_get_context(mdd2obd_dev(mdd), LLOG_CHANGELOG_USER_ORIG_CTXT); if (ctxt == NULL) return -ENXIO; LASSERT(ctxt->loc_handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT); rc = llog_cat_process(env, ctxt->loc_handle, mdd_changelog_user_purge_cb, (void *)&data, 0, 0); if ((rc >= 0) && (data.mcud_minrec > 0)) { CDEBUG(D_IOCTL, "Purging changelog entries up to "LPD64 ", referenced by "CHANGELOG_USER_PREFIX"%d\n", data.mcud_minrec, data.mcud_minid); rc = mdd_changelog_llog_cancel(env, mdd, data.mcud_minrec); } else { CWARN("Could not determine changelog records to purge; rc=%d\n", rc); } llog_ctxt_put(ctxt); if (!data.mcud_found) { CWARN("No entry for user %d. Last changelog reference is " LPD64" by changelog user %d\n", data.mcud_id, data.mcud_minrec, data.mcud_minid); rc = -ENOENT; } if (!rc && data.mcud_usercount == 0) /* No more users; turn changelogs off */ rc = mdd_changelog_on(env, mdd, 0); RETURN (rc); }
int llog_origin_handle_create(struct ptlrpc_request *req) { struct obd_export *exp = req->rq_export; struct obd_device *obd = exp->exp_obd; struct obd_device *disk_obd; struct llog_handle *loghandle; struct llogd_body *body; struct lvfs_run_ctxt saved; struct llog_logid *logid = NULL; struct llog_ctxt *ctxt; char *name = NULL; int rc, rc2; ENTRY; body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY); if (body == NULL) RETURN(-EFAULT); if (body->lgd_logid.lgl_oid > 0) logid = &body->lgd_logid; if (req_capsule_field_present(&req->rq_pill, &RMF_NAME, RCL_CLIENT)) { name = req_capsule_client_get(&req->rq_pill, &RMF_NAME); if (name == NULL) RETURN(-EFAULT); CDEBUG(D_INFO, "%s: opening log %s\n", obd->obd_name, name); } ctxt = llog_get_context(obd, body->lgd_ctxt_idx); if (ctxt == NULL) { CDEBUG(D_WARNING, "%s: no ctxt. group=%p idx=%d name=%s\n", obd->obd_name, &obd->obd_olg, body->lgd_ctxt_idx, name); RETURN(-ENODEV); } disk_obd = ctxt->loc_exp->exp_obd; push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); rc = llog_create(ctxt, &loghandle, logid, name); if (rc) GOTO(out_pop, rc); rc = req_capsule_server_pack(&req->rq_pill); if (rc) GOTO(out_close, rc = -ENOMEM); body = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY); body->lgd_logid = loghandle->lgh_id; GOTO(out_close, rc); out_close: rc2 = llog_close(loghandle); if (!rc) rc = rc2; out_pop: pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); llog_ctxt_put(ctxt); return rc; }
/* Only open is supported, no new llog can be created remotely */ int llog_origin_handle_open(struct ptlrpc_request *req) { struct obd_export *exp = req->rq_export; struct obd_device *obd = exp->exp_obd; struct llog_handle *loghandle; struct llogd_body *body; struct llog_logid *logid = NULL; struct llog_ctxt *ctxt; char *name = NULL; int rc; ENTRY; body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY); if (body == NULL) RETURN(err_serious(-EFAULT)); rc = req_capsule_server_pack(&req->rq_pill); if (rc) RETURN(err_serious(-ENOMEM)); if (ostid_id(&body->lgd_logid.lgl_oi) > 0) logid = &body->lgd_logid; if (req_capsule_field_present(&req->rq_pill, &RMF_NAME, RCL_CLIENT)) { name = req_capsule_client_get(&req->rq_pill, &RMF_NAME); if (name == NULL) RETURN(-EFAULT); CDEBUG(D_INFO, "%s: opening log %s\n", obd->obd_name, name); } if (body->lgd_ctxt_idx >= LLOG_MAX_CTXTS) { CDEBUG(D_WARNING, "%s: bad ctxt ID: idx=%d name=%s\n", obd->obd_name, body->lgd_ctxt_idx, name); RETURN(-EPROTO); } ctxt = llog_get_context(obd, body->lgd_ctxt_idx); if (ctxt == NULL) { CDEBUG(D_WARNING, "%s: no ctxt. group=%p idx=%d name=%s\n", obd->obd_name, &obd->obd_olg, body->lgd_ctxt_idx, name); RETURN(-ENODEV); } rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle, logid, name, LLOG_OPEN_EXISTS); if (rc) GOTO(out_ctxt, rc); body = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY); body->lgd_logid = loghandle->lgh_id; llog_origin_close(req->rq_svc_thread->t_env, loghandle); EXIT; out_ctxt: llog_ctxt_put(ctxt); return rc; }
static int lprocfs_rd_changelog_users(char *page, char **start, off_t off, int count, int *eof, void *data) { struct lu_env env; struct mdd_device *mdd = data; struct llog_ctxt *ctxt; struct cucb_data cucb; __u64 cur; int rc; *eof = 1; ctxt = llog_get_context(mdd2obd_dev(mdd), LLOG_CHANGELOG_USER_ORIG_CTXT); if (ctxt == NULL) return -ENXIO; LASSERT(ctxt->loc_handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT); rc = lu_env_init(&env, LCT_LOCAL); if (rc) { llog_ctxt_put(ctxt); return rc; } spin_lock(&mdd->mdd_cl.mc_lock); cur = mdd->mdd_cl.mc_index; spin_unlock(&mdd->mdd_cl.mc_lock); cucb.count = count; cucb.page = page; cucb.idx = 0; cucb.idx += snprintf(cucb.page + cucb.idx, cucb.count - cucb.idx, "current index: "LPU64"\n", cur); cucb.idx += snprintf(cucb.page + cucb.idx, cucb.count - cucb.idx, "%-5s %s\n", "ID", "index"); llog_cat_process(&env, ctxt->loc_handle, lprocfs_changelog_users_cb, &cucb, 0, 0); lu_env_fini(&env); llog_ctxt_put(ctxt); return cucb.idx; }
static int llog_catinfo_config(struct obd_device *obd, char *buf, int buf_len, char *client) { struct mds_obd *mds = &obd->u.mds; struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT); struct lvfs_run_ctxt saved; struct llog_handle *handle = NULL; char name[4][64]; int rc, i, l, remains = buf_len; char *out = buf; ENTRY; if (ctxt == NULL || mds == NULL) GOTO(release_ctxt, rc = -ENODEV); push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL); sprintf(name[0], "%s", mds->mds_profile); sprintf(name[1], "%s-clean", mds->mds_profile); sprintf(name[2], "%s", client); sprintf(name[3], "%s-clean", client); for (i = 0; i < 4; i++) { int index, uncanceled = 0; rc = llog_create(ctxt, &handle, NULL, name[i]); if (rc) GOTO(out_pop, rc); rc = llog_init_handle(handle, 0, NULL); if (rc) { llog_close(handle); GOTO(out_pop, rc = -ENOENT); } for (index = 1; index < (LLOG_BITMAP_BYTES * 8); index ++) { if (ext2_test_bit(index, handle->lgh_hdr->llh_bitmap)) uncanceled++; } l = snprintf(out, remains, "[Log Name]: %s\nLog Size: %llu\n" "Last Index: %d\nUncanceled Records: %d\n\n", name[i], i_size_read(handle->lgh_file->f_dentry->d_inode), handle->lgh_last_idx, uncanceled); out += l; remains -= l; llog_close(handle); if (remains <= 0) break; } GOTO(out_pop, rc); out_pop: pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL); release_ctxt: llog_ctxt_put(ctxt); return rc; }
static int mdd_changelog_user_register(const struct lu_env *env, struct mdd_device *mdd, int *id) { struct llog_ctxt *ctxt; struct llog_changelog_user_rec *rec; int rc; ENTRY; ctxt = llog_get_context(mdd2obd_dev(mdd), LLOG_CHANGELOG_USER_ORIG_CTXT); if (ctxt == NULL) RETURN(-ENXIO); OBD_ALLOC_PTR(rec); if (rec == NULL) { llog_ctxt_put(ctxt); RETURN(-ENOMEM); } /* Assume we want it on since somebody registered */ rc = mdd_changelog_on(env, mdd, 1); if (rc) GOTO(out, rc); rec->cur_hdr.lrh_len = sizeof(*rec); rec->cur_hdr.lrh_type = CHANGELOG_USER_REC; spin_lock(&mdd->mdd_cl.mc_user_lock); if (mdd->mdd_cl.mc_lastuser == (unsigned int)(-1)) { spin_unlock(&mdd->mdd_cl.mc_user_lock); CERROR("Maximum number of changelog users exceeded!\n"); GOTO(out, rc = -EOVERFLOW); } *id = rec->cur_id = ++mdd->mdd_cl.mc_lastuser; rec->cur_endrec = mdd->mdd_cl.mc_index; spin_unlock(&mdd->mdd_cl.mc_user_lock); rc = llog_cat_add(env, ctxt->loc_handle, &rec->cur_hdr, NULL); CDEBUG(D_IOCTL, "Registered changelog user %d\n", *id); out: OBD_FREE_PTR(rec); llog_ctxt_put(ctxt); RETURN(rc); }
/* ------------------------------------------------------------------------- * Tests above, boring obd functions below * ------------------------------------------------------------------------- */ static int llog_run_tests(const struct lu_env *env, struct obd_device *obd) { struct llog_handle *llh = NULL; struct llog_ctxt *ctxt; int rc, err; char name[10]; ENTRY; ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT); LASSERT(ctxt); sprintf(name, "%x", llog_test_rand); rc = llog_test_1(env, obd, name); if (rc) GOTO(cleanup_ctxt, rc); rc = llog_test_2(env, obd, name, &llh); if (rc) GOTO(cleanup_ctxt, rc); rc = llog_test_3(env, obd, llh); if (rc) GOTO(cleanup, rc); rc = llog_test_4(env, obd); if (rc) GOTO(cleanup, rc); rc = llog_test_5(env, obd); if (rc) GOTO(cleanup, rc); rc = llog_test_6(env, obd, name); if (rc) GOTO(cleanup, rc); rc = llog_test_7(env, obd); if (rc) GOTO(cleanup, rc); rc = llog_test_8(env, obd); if (rc) GOTO(cleanup, rc); cleanup: err = llog_destroy(env, llh); if (err) CERROR("cleanup: llog_destroy failed: %d\n", err); llog_close(env, llh); if (rc == 0) rc = err; cleanup_ctxt: llog_ctxt_put(ctxt); return rc; }
/* ------------------------------------------------------------------------- * Tests above, boring obd functions below * ------------------------------------------------------------------------- */ static int llog_run_tests(struct obd_device *obd) { struct llog_handle *llh; struct lvfs_run_ctxt saved; struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT); int rc, err, cleanup_phase = 0; char name[10]; ENTRY; sprintf(name, "%x", llog_test_rand); push_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL); rc = llog_test_1(obd, name); if (rc) GOTO(cleanup, rc); rc = llog_test_2(obd, name, &llh); if (rc) GOTO(cleanup, rc); cleanup_phase = 1; /* close llh */ rc = llog_test_3(obd, llh); if (rc) GOTO(cleanup, rc); rc = llog_test_4(obd); if (rc) GOTO(cleanup, rc); rc = llog_test_5(obd); if (rc) GOTO(cleanup, rc); rc = llog_test_6(obd, name); if (rc) GOTO(cleanup, rc); rc = llog_test_7(obd); if (rc) GOTO(cleanup, rc); cleanup: switch (cleanup_phase) { case 1: err = llog_close(llh); if (err) CERROR("cleanup: llog_close failed: %d\n", err); if (!rc) rc = err; case 0: pop_ctxt(&saved, &ctxt->loc_exp->exp_obd->obd_lvfs_ctxt, NULL); } llog_ctxt_put(ctxt); return rc; }
int llog_origin_handle_read_header(struct ptlrpc_request *req) { struct llog_handle *loghandle; struct llogd_body *body; struct llog_log_hdr *hdr; struct llog_ctxt *ctxt; __u32 flags; int rc; ENTRY; body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY); if (body == NULL) RETURN(err_serious(-EFAULT)); rc = req_capsule_server_pack(&req->rq_pill); if (rc) RETURN(err_serious(-ENOMEM)); if (body->lgd_ctxt_idx >= LLOG_MAX_CTXTS) { CDEBUG(D_WARNING, "%s: bad ctxt ID: idx=%d\n", req->rq_export->exp_obd->obd_name, body->lgd_ctxt_idx); RETURN(-EPROTO); } ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx); if (ctxt == NULL) RETURN(-ENODEV); rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle, &body->lgd_logid, NULL, LLOG_OPEN_EXISTS); if (rc) GOTO(out_ctxt, rc); /* * llog_init_handle() reads the llog header */ flags = body->lgd_llh_flags; rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags, NULL); if (rc) GOTO(out_close, rc); flags = loghandle->lgh_hdr->llh_flags; hdr = req_capsule_server_get(&req->rq_pill, &RMF_LLOG_LOG_HDR); *hdr = *loghandle->lgh_hdr; EXIT; out_close: llog_origin_close(req->rq_svc_thread->t_env, loghandle); out_ctxt: llog_ctxt_put(ctxt); return rc; }
int llog_origin_handle_read_header(struct ptlrpc_request *req) { struct obd_export *exp = req->rq_export; struct obd_device *obd = exp->exp_obd; struct obd_device *disk_obd; struct llog_handle *loghandle; struct llogd_body *body; struct llog_log_hdr *hdr; struct lvfs_run_ctxt saved; struct llog_ctxt *ctxt; __u32 flags; int rc, rc2; ENTRY; body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY); if (body == NULL) RETURN(-EFAULT); ctxt = llog_get_context(obd, body->lgd_ctxt_idx); if (ctxt == NULL) RETURN(-ENODEV); disk_obd = ctxt->loc_exp->exp_obd; push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); rc = llog_create(ctxt, &loghandle, &body->lgd_logid, NULL); if (rc) GOTO(out_pop, rc); /* * llog_init_handle() reads the llog header */ flags = body->lgd_llh_flags; rc = llog_init_handle(loghandle, flags, NULL); if (rc) GOTO(out_close, rc); rc = req_capsule_server_pack(&req->rq_pill); if (rc) GOTO(out_close, rc = -ENOMEM); hdr = req_capsule_server_get(&req->rq_pill, &RMF_LLOG_LOG_HDR); *hdr = *loghandle->lgh_hdr; GOTO(out_close, rc); out_close: rc2 = llog_close(loghandle); if (!rc) rc = rc2; out_pop: pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); llog_ctxt_put(ctxt); return rc; }
int llog_origin_handle_destroy(struct ptlrpc_request *req) { struct obd_export *exp = req->rq_export; struct obd_device *obd = exp->exp_obd; struct obd_device *disk_obd; struct llog_handle *loghandle; struct llogd_body *body; struct lvfs_run_ctxt saved; struct llog_logid *logid = NULL; struct llog_ctxt *ctxt; int rc; ENTRY; body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY); if (body == NULL) RETURN(-EFAULT); if (body->lgd_logid.lgl_oid > 0) logid = &body->lgd_logid; ctxt = llog_get_context(obd, body->lgd_ctxt_idx); if (ctxt == NULL) RETURN(-ENODEV); disk_obd = ctxt->loc_exp->exp_obd; push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); rc = llog_create(ctxt, &loghandle, logid, NULL); if (rc) GOTO(out_pop, rc); rc = req_capsule_server_pack(&req->rq_pill); if (rc) GOTO(out_close, rc = -ENOMEM); body = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY); body->lgd_logid = loghandle->lgh_id; rc = llog_init_handle(loghandle, LLOG_F_IS_PLAIN, NULL); if (rc) GOTO(out_close, rc); rc = llog_destroy(loghandle); if (rc) GOTO(out_close, rc); llog_free_handle(loghandle); GOTO(out_close, rc); out_close: if (rc) llog_close(loghandle); out_pop: pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL); llog_ctxt_put(ctxt); return rc; }
/** Add a CL_MARK record to the changelog * \param mdd * \param markerflags - CLM_* * \retval 0 ok */ int mdd_changelog_write_header(const struct lu_env *env, struct mdd_device *mdd, int markerflags) { struct obd_device *obd = mdd2obd_dev(mdd); struct llog_changelog_rec *rec; struct lu_buf *buf; struct llog_ctxt *ctxt; int reclen; int len = strlen(obd->obd_name); int rc; ENTRY; if (mdd->mdd_cl.mc_mask & (1 << CL_MARK)) { mdd->mdd_cl.mc_starttime = cfs_time_current_64(); RETURN(0); } reclen = llog_data_len(sizeof(*rec) + len); buf = lu_buf_check_and_alloc(&mdd_env_info(env)->mti_big_buf, reclen); if (buf->lb_buf == NULL) RETURN(-ENOMEM); rec = buf->lb_buf; rec->cr.cr_flags = CLF_VERSION; rec->cr.cr_type = CL_MARK; rec->cr.cr_namelen = len; memcpy(changelog_rec_name(&rec->cr), obd->obd_name, rec->cr.cr_namelen); /* Status and action flags */ rec->cr.cr_markerflags = mdd->mdd_cl.mc_flags | markerflags; rec->cr_hdr.lrh_len = llog_data_len(changelog_rec_size(&rec->cr) + rec->cr.cr_namelen); rec->cr_hdr.lrh_type = CHANGELOG_REC; rec->cr.cr_time = cl_time(); spin_lock(&mdd->mdd_cl.mc_lock); rec->cr.cr_index = ++mdd->mdd_cl.mc_index; spin_unlock(&mdd->mdd_cl.mc_lock); ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT); LASSERT(ctxt); rc = llog_cat_add(env, ctxt->loc_handle, &rec->cr_hdr, NULL); if (rc > 0) rc = 0; llog_ctxt_put(ctxt); /* assume on or off event; reset repeat-access time */ mdd->mdd_cl.mc_starttime = cfs_time_current_64(); RETURN(rc); }
static int mds_llog_repl_cancel(struct llog_ctxt *ctxt, struct lov_stripe_md *lsm, int count, struct llog_cookie *cookies, int flags) { struct obd_device *obd = ctxt->loc_obd; struct obd_device *lov_obd = obd->u.mds.mds_lov_obd; struct llog_ctxt *lctxt; int rc; ENTRY; lctxt = llog_get_context(lov_obd, ctxt->loc_idx); rc = llog_cancel(lctxt, lsm, count, cookies, flags); llog_ctxt_put(lctxt); RETURN(rc); }
/* Test named-log reopen; returns opened log on success */ static int llog_test_2(struct obd_device *obd, char *name, struct llog_handle **llh) { struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT); int rc; ENTRY; CWARN("2a: re-open a log with name: %s\n", name); rc = llog_create(ctxt, llh, NULL, name); if (rc) { CERROR("2a: re-open log with name %s failed: %d\n", name, rc); GOTO(out, rc); } llog_init_handle(*llh, LLOG_F_IS_PLAIN, &uuid); if ((rc = verify_handle("2", *llh, 1))) GOTO(out, rc); #if 0 CWARN("2b: create a log without specified NAME & LOGID\n"); rc = llog_create(ctxt, &loghandle, NULL, NULL); if (rc) { CERROR("2b: create log failed\n"); GOTO(out, rc); } llog_init_handle(loghandle, LLOG_F_IS_PLAIN, &uuid); logid = loghandle->lgh_id; llog_close(loghandle); CWARN("2b: re-open the log by LOGID\n"); rc = llog_create(ctxt, &loghandle, &logid, NULL); if (rc) { CERROR("2b: re-open log by LOGID failed\n"); GOTO(out, rc); } llog_init_handle(loghandle, LLOG_F_IS_PLAIN, &uuid); CWARN("2b: destroy this log\n"); rc = llog_destroy(loghandle); if (rc) { CERROR("2b: destroy log failed\n"); GOTO(out, rc); } llog_free_handle(loghandle); #endif out: llog_ctxt_put(ctxt); RETURN(rc); }
static int mdd_changelog_size_ctxt(const struct lu_env *env, struct mdd_device *mdd, int index, __u64 *val) { struct llog_ctxt *ctxt; ctxt = llog_get_context(mdd2obd_dev(mdd), index); if (ctxt == NULL) return -ENXIO; if (!(ctxt->loc_handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT)) { CERROR("%s: ChangeLog has wrong flags: rc = %d\n", ctxt->loc_obd->obd_name, -EINVAL); llog_ctxt_put(ctxt); return -EINVAL; } *val += llog_cat_size(env, ctxt->loc_handle); llog_ctxt_put(ctxt); return 0; }
static int mds_llog_origin_connect(struct llog_ctxt *ctxt, struct llog_logid *logid, struct llog_gen *gen, struct obd_uuid *uuid) { struct obd_device *obd = ctxt->loc_obd; struct obd_device *lov_obd = obd->u.mds.mds_lov_obd; struct llog_ctxt *lctxt; int rc; ENTRY; lctxt = llog_get_context(lov_obd, ctxt->loc_idx); rc = llog_connect(lctxt, logid, gen, uuid); llog_ctxt_put(lctxt); RETURN(rc); }
static int mds_llog_origin_add(struct llog_ctxt *ctxt, struct llog_rec_hdr *rec, struct lov_stripe_md *lsm, struct llog_cookie *logcookies, int numcookies) { struct obd_device *obd = ctxt->loc_obd; struct obd_device *lov_obd = obd->u.mds.mds_lov_obd; struct llog_ctxt *lctxt; int rc; ENTRY; lctxt = llog_get_context(lov_obd, ctxt->loc_idx); rc = llog_add(lctxt, rec, lsm, logcookies, numcookies); llog_ctxt_put(lctxt); RETURN(rc); }
/** * set llog methods and create LLOG_AGENT_ORIG_CTXT llog * object in obd_device */ static int mdd_hsm_actions_llog_init(const struct lu_env *env, struct mdd_device *m) { struct obd_device *obd = mdd2obd_dev(m); struct llog_ctxt *ctxt = NULL; int rc; ENTRY; OBD_SET_CTXT_MAGIC(&obd->obd_lvfs_ctxt); obd->obd_lvfs_ctxt.dt = m->mdd_bottom; rc = llog_setup(env, obd, &obd->obd_olg, LLOG_AGENT_ORIG_CTXT, obd, &hsm_actions_logops); if (rc) { CERROR("%s: hsm actions llog setup failed: rc = %d\n", obd->obd_name, rc); RETURN(rc); } ctxt = llog_get_context(obd, LLOG_AGENT_ORIG_CTXT); LASSERT(ctxt); rc = llog_open_create(env, ctxt, &ctxt->loc_handle, NULL, HSM_ACTIONS); if (rc) { CERROR("%s: hsm actions llog open_create failed: rc = %d\n", obd->obd_name, rc); GOTO(out_cleanup, rc); } rc = llog_cat_init_and_process(env, ctxt->loc_handle); if (rc) GOTO(out_close, rc); llog_ctxt_put(ctxt); RETURN(0); out_close: llog_cat_close(env, ctxt->loc_handle); ctxt->loc_handle = NULL; out_cleanup: llog_cleanup(env, ctxt); return rc; }
static int mgc_llog_init(struct obd_device *obd, struct obd_llog_group *olg, struct obd_device *tgt, int *index) { struct llog_ctxt *ctxt; int rc; LASSERT(olg == &obd->obd_olg); rc = llog_setup(NULL, obd, olg, LLOG_CONFIG_REPL_CTXT, tgt, &llog_client_ops); if (rc < 0) return rc; ctxt = llog_group_get_ctxt(olg, LLOG_CONFIG_REPL_CTXT); llog_initiator_connect(ctxt); llog_ctxt_put(ctxt); return rc; }
/** Remove entries with indicies up to and including \a endrec from the * changelog * \param mdd * \param endrec * \retval 0 ok */ static int mdd_changelog_llog_cancel(const struct lu_env *env, struct mdd_device *mdd, long long endrec) { struct obd_device *obd = mdd2obd_dev(mdd); struct llog_ctxt *ctxt; long long unsigned cur; int rc; ctxt = llog_get_context(obd, LLOG_CHANGELOG_ORIG_CTXT); if (ctxt == NULL) return -ENXIO; spin_lock(&mdd->mdd_cl.mc_lock); cur = (long long)mdd->mdd_cl.mc_index; spin_unlock(&mdd->mdd_cl.mc_lock); if (endrec > cur) endrec = cur; /* purge to "0" is shorthand for everything */ if (endrec == 0) endrec = cur; /* If purging all records, write a header entry so we don't have an empty catalog and we're sure to have a valid starting index next time. In case of crash, we just restart with old log so we're allright. */ if (endrec == cur) { /* XXX: transaction is started by llog itself */ rc = mdd_changelog_write_header(env, mdd, CLM_PURGE); if (rc) goto out; } /* Some records were purged, so reset repeat-access time (so we record new mtime update records, so users can see a file has been changed since the last purge) */ mdd->mdd_cl.mc_starttime = cfs_time_current_64(); rc = llog_cancel(env, ctxt, (struct llog_cookie *)&endrec, 0); out: llog_ctxt_put(ctxt); return rc; }
/* the replicators commit callback */ static int lov_llog_repl_cancel(const struct lu_env *env, struct llog_ctxt *ctxt, struct lov_stripe_md *lsm, int count, struct llog_cookie *cookies, int flags) { struct lov_obd *lov; struct obd_device *obd = ctxt->loc_obd; int rc = 0, i; ENTRY; LASSERT(lsm != NULL); LASSERT(count == lsm->lsm_stripe_count); lov = &obd->u.lov; obd_getref(obd); for (i = 0; i < count; i++, cookies++) { struct lov_oinfo *loi = lsm->lsm_oinfo[i]; struct obd_device *child = lov->lov_tgts[loi->loi_ost_idx]->ltd_exp->exp_obd; struct llog_ctxt *cctxt = llog_get_context(child, ctxt->loc_idx); int err; err = llog_cancel(env, cctxt, NULL, 1, cookies, flags); llog_ctxt_put(cctxt); if (err && lov->lov_tgts[loi->loi_ost_idx]->ltd_active) { CERROR("%s: objid "DOSTID" subobj "DOSTID " on OST idx %d: rc = %d\n", obd->obd_name, POSTID(&lsm->lsm_oi), POSTID(&loi->loi_oi), loi->loi_ost_idx, err); if (!rc) rc = err; } } obd_putref(obd); RETURN(rc); }