/** * Implementation of the llog_operations::lop_create * * This function creates the llog according with llog_handle::lgh_obj * and llog_handle::lgh_name. * * \param[in] env execution environment * \param[in] res llog handle of the current llog * \param[in] th current transaction handle * * \retval 0 on successful create * \retval negative value on error */ static int llog_osd_create(const struct lu_env *env, struct llog_handle *res, struct thandle *th) { struct llog_thread_info *lgi = llog_info(env); struct dt_insert_rec *rec = &lgi->lgi_dt_rec; struct local_oid_storage *los; struct dt_object *o; int rc = 0; ENTRY; LASSERT(env); o = res->lgh_obj; LASSERT(o); /* llog can be already created */ if (dt_object_exists(o)) RETURN(-EEXIST); los = res->private_data; LASSERT(los); dt_write_lock(env, o, 0); if (!dt_object_exists(o)) rc = llog_osd_create_new_object(env, los, o, th); else rc = -EEXIST; dt_write_unlock(env, o); if (rc) RETURN(rc); if (res->lgh_name) { struct dt_object *llog_dir; llog_dir = llog_osd_dir_get(env, res->lgh_ctxt); if (IS_ERR(llog_dir)) RETURN(PTR_ERR(llog_dir)); logid_to_fid(&res->lgh_id, &lgi->lgi_fid); rec->rec_fid = &lgi->lgi_fid; rec->rec_type = S_IFREG; dt_read_lock(env, llog_dir, 0); rc = dt_insert(env, llog_dir, (struct dt_rec *)rec, (struct dt_key *)res->lgh_name, th, BYPASS_CAPA, 1); dt_read_unlock(env, llog_dir); lu_object_put(env, &llog_dir->do_lu); if (rc) CERROR("%s: can't create named llog %s: rc = %d\n", o->do_lu.lo_dev->ld_obd->obd_name, res->lgh_name, rc); } RETURN(rc); }
static int test_7_print_cb(const struct lu_env *env, struct llog_handle *llh, struct llog_rec_hdr *rec, void *data) { struct lu_fid fid = {0}; logid_to_fid(&llh->lgh_id, &fid); CDEBUG(D_OTHER, "record type %#x at index %d in log "DFID"\n", rec->lrh_type, rec->lrh_index, PFID(&fid)); plain_counter++; return 0; }
/** * Implementation of the llog_operations::lop_declare_create * * This function declares the llog create. It declares also name insert * into llog directory in case of named llog. * * \param[in] env execution environment * \param[in] res llog handle of the current llog * \param[in] th current transaction handle * * \retval 0 on successful create declaration * \retval negative value on error */ static int llog_osd_declare_create(const struct lu_env *env, struct llog_handle *res, struct thandle *th) { struct llog_thread_info *lgi = llog_info(env); struct dt_insert_rec *rec = &lgi->lgi_dt_rec; struct local_oid_storage *los; struct dt_object *o; int rc; ENTRY; LASSERT(res->lgh_obj); LASSERT(th); /* object can be created by another thread */ o = res->lgh_obj; if (dt_object_exists(o)) RETURN(0); los = res->private_data; LASSERT(los); rc = llog_osd_declare_new_object(env, los, o, th); if (rc) RETURN(rc); /* do not declare header initialization here as it's declared * in llog_osd_declare_write_rec() which is always called */ if (res->lgh_name) { struct dt_object *llog_dir; llog_dir = llog_osd_dir_get(env, res->lgh_ctxt); if (IS_ERR(llog_dir)) RETURN(PTR_ERR(llog_dir)); logid_to_fid(&res->lgh_id, &lgi->lgi_fid); rec->rec_fid = &lgi->lgi_fid; rec->rec_type = S_IFREG; rc = dt_declare_insert(env, llog_dir, (struct dt_rec *)rec, (struct dt_key *)res->lgh_name, th); lu_object_put(env, &llog_dir->do_lu); if (rc) CERROR("%s: can't declare named llog %s: rc = %d\n", o->do_lu.lo_dev->ld_obd->obd_name, res->lgh_name, rc); } RETURN(rc); }
static int llog_osd_declare_create(const struct lu_env *env, struct llog_handle *res, struct thandle *th) { struct llog_thread_info *lgi = llog_info(env); struct local_oid_storage *los; struct dt_object *o; int rc; ENTRY; LASSERT(res->lgh_obj); LASSERT(th); /* object can be created by another thread */ o = res->lgh_obj; if (dt_object_exists(o)) RETURN(0); los = res->private_data; LASSERT(los); rc = llog_osd_declare_new_object(env, los, o, th); if (rc) RETURN(rc); rc = dt_declare_record_write(env, o, LLOG_CHUNK_SIZE, 0, th); if (rc) RETURN(rc); if (res->lgh_name) { struct dt_object *llog_dir; llog_dir = llog_osd_dir_get(env, res->lgh_ctxt); if (IS_ERR(llog_dir)) RETURN(PTR_ERR(llog_dir)); dt_declare_ref_add(env, o, th); logid_to_fid(&res->lgh_id, &lgi->lgi_fid); rc = dt_declare_insert(env, llog_dir, (struct dt_rec *)&lgi->lgi_fid, (struct dt_key *)res->lgh_name, th); lu_object_put(env, &llog_dir->do_lu); if (rc) CERROR("%s: can't declare named llog %s: rc = %d\n", o->do_lu.lo_dev->ld_obd->obd_name, res->lgh_name, rc); } RETURN(rc); }
static int plain_print_cb(const struct lu_env *env, struct llog_handle *llh, struct llog_rec_hdr *rec, void *data) { struct lu_fid fid = {0}; if (!(llh->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN)) { CERROR("log is not plain\n"); return -EINVAL; } logid_to_fid(&llh->lgh_id, &fid); CDEBUG(D_INFO, "seeing record at index %d in log "DFID"\n", rec->lrh_index, PFID(&fid)); plain_counter++; return 0; }
static int cat_print_cb(const struct lu_env *env, struct llog_handle *llh, struct llog_rec_hdr *rec, void *data) { struct llog_logid_rec *lir = (struct llog_logid_rec *)rec; struct lu_fid fid = {0}; if (rec->lrh_type != LLOG_LOGID_MAGIC) { CERROR("invalid record in catalog\n"); return -EINVAL; } logid_to_fid(&lir->lid_id, &fid); CWARN("seeing record at index %d - "DFID" in log "DFID"\n", rec->lrh_index, PFID(&fid), PFID(lu_object_fid(&llh->lgh_obj->do_lu))); cat_counter++; return 0; }
/** * Implementation of the llog_operations::lop_open * * This function opens the llog by its logid or by name, it may open also * non existent llog and assing then new id to it. * The llog_open/llog_close pair works similar to lu_object_find/put, * the object may not exist prior open. The result of open is just dt_object * in the llog header. * * \param[in] env execution environment * \param[in] handle llog handle of the current llog * \param[in] logid logid of llog to open (nameless llog) * \param[in] name name of llog to open (named llog) * \param[in] open_param * LLOG_OPEN_NEW - new llog, may not exist * LLOG_OPEN_EXIST - old llog, must exist * * \retval 0 on successful open, llog_handle::lgh_obj * contains the dt_object of the llog. * \retval negative value on error */ static int llog_osd_open(const struct lu_env *env, struct llog_handle *handle, struct llog_logid *logid, char *name, enum llog_open_param open_param) { struct llog_thread_info *lgi = llog_info(env); struct llog_ctxt *ctxt = handle->lgh_ctxt; struct dt_object *o; struct dt_device *dt; struct ls_device *ls; struct local_oid_storage *los; int rc = 0; ENTRY; LASSERT(env); LASSERT(ctxt); LASSERT(ctxt->loc_exp); LASSERT(ctxt->loc_exp->exp_obd); dt = ctxt->loc_exp->exp_obd->obd_lvfs_ctxt.dt; LASSERT(dt); ls = ls_device_get(dt); if (IS_ERR(ls)) RETURN(PTR_ERR(ls)); mutex_lock(&ls->ls_los_mutex); los = dt_los_find(ls, name != NULL ? FID_SEQ_LLOG_NAME : FID_SEQ_LLOG); mutex_unlock(&ls->ls_los_mutex); LASSERT(los); ls_device_put(env, ls); LASSERT(handle); if (logid != NULL) { logid_to_fid(logid, &lgi->lgi_fid); } else if (name) { struct dt_object *llog_dir; llog_dir = llog_osd_dir_get(env, ctxt); if (IS_ERR(llog_dir)) GOTO(out, rc = PTR_ERR(llog_dir)); dt_read_lock(env, llog_dir, 0); rc = dt_lookup_dir(env, llog_dir, name, &lgi->lgi_fid); dt_read_unlock(env, llog_dir); lu_object_put(env, &llog_dir->do_lu); if (rc == -ENOENT && open_param == LLOG_OPEN_NEW) { /* generate fid for new llog */ rc = local_object_fid_generate(env, los, &lgi->lgi_fid); } if (rc < 0) GOTO(out, rc); OBD_ALLOC(handle->lgh_name, strlen(name) + 1); if (handle->lgh_name) strcpy(handle->lgh_name, name); else GOTO(out, rc = -ENOMEM); } else { LASSERTF(open_param & LLOG_OPEN_NEW, "%#x\n", open_param); /* generate fid for new llog */ rc = local_object_fid_generate(env, los, &lgi->lgi_fid); if (rc < 0) GOTO(out, rc); } o = ls_locate(env, ls, &lgi->lgi_fid, NULL); if (IS_ERR(o)) GOTO(out_name, rc = PTR_ERR(o)); /* No new llog is expected but doesn't exist */ if (open_param != LLOG_OPEN_NEW && !dt_object_exists(o)) GOTO(out_put, rc = -ENOENT); fid_to_logid(&lgi->lgi_fid, &handle->lgh_id); handle->lgh_obj = o; handle->private_data = los; LASSERT(handle->lgh_ctxt); RETURN(rc); out_put: lu_object_put(env, &o->do_lu); out_name: if (handle->lgh_name != NULL) OBD_FREE(handle->lgh_name, strlen(name) + 1); out: dt_los_put(los); RETURN(rc); }