int llog_open(const struct lu_env *env, struct llog_ctxt *ctxt, struct llog_handle **lgh, struct llog_logid *logid, char *name, enum llog_open_param open_param) { int raised; int rc; LASSERT(ctxt); LASSERT(ctxt->loc_logops); if (ctxt->loc_logops->lop_open == NULL) { *lgh = NULL; return -EOPNOTSUPP; } *lgh = llog_alloc_handle(); if (*lgh == NULL) return -ENOMEM; (*lgh)->lgh_ctxt = ctxt; (*lgh)->lgh_logops = ctxt->loc_logops; raised = cfs_cap_raised(CFS_CAP_SYS_RESOURCE); if (!raised) cfs_cap_raise(CFS_CAP_SYS_RESOURCE); rc = ctxt->loc_logops->lop_open(env, *lgh, logid, name, open_param); if (!raised) cfs_cap_lower(CFS_CAP_SYS_RESOURCE); if (rc) { llog_free_handle(*lgh); *lgh = NULL; } return rc; }
static int llog_remove_log(struct llog_handle *cat, struct llog_logid *logid) { struct llog_handle *log; int rc, index = 0; ENTRY; cfs_down_write(&cat->lgh_lock); rc = llog_cat_id2handle(cat, &log, logid); if (rc) { CDEBUG(D_IOCTL, "cannot find log #"LPX64"#"LPX64"#%08x\n", logid->lgl_oid, logid->lgl_oseq, logid->lgl_ogen); GOTO(out, rc = -ENOENT); } index = log->u.phd.phd_cookie.lgc_index; LASSERT(index); rc = llog_destroy(log); if (rc) { CDEBUG(D_IOCTL, "cannot destroy log\n"); GOTO(out, rc); } llog_cat_set_first_idx(cat, index); rc = llog_cancel_rec(cat, index); out: llog_free_handle(log); cfs_up_write(&cat->lgh_lock); 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; }
/* 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 llog_test_7(struct obd_device *obd) { struct llog_ctxt *ctxt = llog_get_context(obd, LLOG_TEST_ORIG_CTXT); struct llog_handle *llh; struct llog_create_rec lcr; char name[10]; int rc; ENTRY; sprintf(name, "%x", llog_test_rand+2); CWARN("7: create a log with name: %s\n", name); LASSERT(ctxt); rc = llog_create(ctxt, &llh, NULL, name); if (rc) { CERROR("7: llog_create with name %s failed: %d\n", name, rc); GOTO(ctxt_release, rc); } llog_init_handle(llh, LLOG_F_IS_PLAIN, &uuid); lcr.lcr_hdr.lrh_len = lcr.lcr_tail.lrt_len = sizeof(lcr); lcr.lcr_hdr.lrh_type = OST_SZ_REC; rc = llog_write_rec(llh, &lcr.lcr_hdr, NULL, 0, NULL, -1); if (rc) { CERROR("7: write one log record failed: %d\n", rc); GOTO(ctxt_release, rc); } rc = llog_destroy(llh); if (rc) CERROR("7: llog_destroy failed: %d\n", rc); else llog_free_handle(llh); ctxt_release: llog_ctxt_put(ctxt); RETURN(rc); }
void llog_handle_put(struct llog_handle *loghandle) { LASSERT(atomic_read(&loghandle->lgh_refcount) > 0); if (atomic_dec_and_test(&loghandle->lgh_refcount)) llog_free_handle(loghandle); }
int llog_ioctl(struct llog_ctxt *ctxt, int cmd, struct obd_ioctl_data *data) { struct llog_logid logid; int err = 0; struct llog_handle *handle = NULL; ENTRY; if (*data->ioc_inlbuf1 == '#') { err = str2logid(&logid, data->ioc_inlbuf1, data->ioc_inllen1); if (err) GOTO(out, err); err = llog_create(ctxt, &handle, &logid, NULL); if (err) GOTO(out, err); } else if (*data->ioc_inlbuf1 == '$') { char *name = data->ioc_inlbuf1 + 1; err = llog_create(ctxt, &handle, NULL, name); if (err) GOTO(out, err); } else { GOTO(out, err = -EINVAL); } err = llog_init_handle(handle, 0, NULL); if (err) GOTO(out_close, err = -ENOENT); switch (cmd) { case OBD_IOC_LLOG_INFO: { int l; int remains = data->ioc_inllen2 + cfs_size_round(data->ioc_inllen1); char *out = data->ioc_bulk; l = snprintf(out, remains, "logid: #"LPX64"#"LPX64"#%08x\n" "flags: %x (%s)\n" "records count: %d\n" "last index: %d\n", handle->lgh_id.lgl_oid, handle->lgh_id.lgl_oseq, handle->lgh_id.lgl_ogen, handle->lgh_hdr->llh_flags, handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT ? "cat" : "plain", handle->lgh_hdr->llh_count, handle->lgh_last_idx); out += l; remains -= l; if (remains <= 0) CERROR("not enough space for log header info\n"); GOTO(out_close, err); } case OBD_IOC_LLOG_CHECK: { LASSERT(data->ioc_inllen1); err = llog_process(handle, llog_check_cb, data, NULL); if (err == -LLOG_EEMPTY) err = 0; GOTO(out_close, err); } case OBD_IOC_LLOG_PRINT: { LASSERT(data->ioc_inllen1); err = llog_process(handle, class_config_dump_handler,data,NULL); if (err == -LLOG_EEMPTY) err = 0; else err = llog_process(handle, llog_print_cb, data, NULL); GOTO(out_close, err); } case OBD_IOC_LLOG_CANCEL: { struct llog_cookie cookie; struct llog_logid plain; char *endp; cookie.lgc_index = simple_strtoul(data->ioc_inlbuf3, &endp, 0); if (*endp != '\0') GOTO(out_close, err = -EINVAL); if (handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT) { cfs_down_write(&handle->lgh_lock); err = llog_cancel_rec(handle, cookie.lgc_index); cfs_up_write(&handle->lgh_lock); GOTO(out_close, err); } err = str2logid(&plain, data->ioc_inlbuf2, data->ioc_inllen2); if (err) GOTO(out_close, err); cookie.lgc_lgl = plain; if (!(handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT)) GOTO(out_close, err = -EINVAL); err = llog_cat_cancel_records(handle, 1, &cookie); GOTO(out_close, err); } case OBD_IOC_LLOG_REMOVE: { struct llog_logid plain; if (handle->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN) { err = llog_destroy(handle); if (!err) llog_free_handle(handle); GOTO(out, err); } if (!(handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT)) GOTO(out_close, err = -EINVAL); if (data->ioc_inlbuf2) { /*remove indicate log from the catalog*/ err = str2logid(&plain, data->ioc_inlbuf2, data->ioc_inllen2); if (err) GOTO(out_close, err); err = llog_remove_log(handle, &plain); } else { /*remove all the log of the catalog*/ llog_process(handle, llog_delete_cb, NULL, NULL); } GOTO(out_close, err); } } out_close: if (handle->lgh_hdr && handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT) llog_cat_put(handle); else llog_close(handle); out: RETURN(err); }
/* This is a callback from the llog_* functions. * Assumes caller has already pushed us into the kernel context. */ static int llog_lvfs_create(struct llog_ctxt *ctxt, struct llog_handle **res, struct llog_logid *logid, char *name) { struct llog_handle *handle; struct obd_device *obd; struct l_dentry *dchild = NULL; struct obdo *oa = NULL; int rc = 0; int open_flags = O_RDWR | O_CREAT | O_LARGEFILE; ENTRY; handle = llog_alloc_handle(); if (handle == NULL) RETURN(-ENOMEM); *res = handle; LASSERT(ctxt); LASSERT(ctxt->loc_exp); obd = ctxt->loc_exp->exp_obd; if (logid != NULL) { dchild = obd_lvfs_fid2dentry(ctxt->loc_exp, logid->lgl_oid, logid->lgl_ogen, logid->lgl_oseq); if (IS_ERR(dchild)) { rc = PTR_ERR(dchild); CERROR("error looking up logfile "LPX64":0x%x: rc %d\n", logid->lgl_oid, logid->lgl_ogen, rc); GOTO(out, rc); } if (dchild->d_inode == NULL) { l_dput(dchild); rc = -ENOENT; CERROR("nonexistent log file "LPX64":"LPX64": rc %d\n", logid->lgl_oid, logid->lgl_oseq, rc); GOTO(out, rc); } /* l_dentry_open will call dput(dchild) if there is an error */ handle->lgh_file = l_dentry_open(&obd->obd_lvfs_ctxt, dchild, O_RDWR | O_LARGEFILE); if (IS_ERR(handle->lgh_file)) { rc = PTR_ERR(handle->lgh_file); CERROR("error opening logfile "LPX64"0x%x: rc %d\n", logid->lgl_oid, logid->lgl_ogen, rc); GOTO(out, rc); } /* assign the value of lgh_id for handle directly */ handle->lgh_id = *logid; } else if (name) { handle->lgh_file = llog_filp_open(MOUNT_CONFIGS_DIR, name, open_flags, 0644); if (IS_ERR(handle->lgh_file)) GOTO(out, rc = PTR_ERR(handle->lgh_file)); handle->lgh_id.lgl_oseq = 1; handle->lgh_id.lgl_oid = handle->lgh_file->f_dentry->d_inode->i_ino; handle->lgh_id.lgl_ogen = handle->lgh_file->f_dentry->d_inode->i_generation; } else { OBDO_ALLOC(oa); if (oa == NULL) GOTO(out, rc = -ENOMEM); oa->o_seq = FID_SEQ_LLOG; oa->o_valid = OBD_MD_FLGENER | OBD_MD_FLGROUP; rc = obd_create(ctxt->loc_exp, oa, NULL, NULL); if (rc) GOTO(out, rc); /* FIXME: rationalize the misuse of o_generation in * this API along with mds_obd_{create,destroy}. * Hopefully it is only an internal API issue. */ #define o_generation o_parent_oid dchild = obd_lvfs_fid2dentry(ctxt->loc_exp, oa->o_id, oa->o_generation, oa->o_seq); if (IS_ERR(dchild)) GOTO(out, rc = PTR_ERR(dchild)); handle->lgh_file = l_dentry_open(&obd->obd_lvfs_ctxt, dchild, open_flags); if (IS_ERR(handle->lgh_file)) GOTO(out, rc = PTR_ERR(handle->lgh_file)); handle->lgh_id.lgl_oseq = oa->o_seq; handle->lgh_id.lgl_oid = oa->o_id; handle->lgh_id.lgl_ogen = oa->o_generation; } handle->lgh_ctxt = ctxt; out: if (rc) llog_free_handle(handle); if (oa) OBDO_FREE(oa); RETURN(rc); }