static int cont_open(struct rdb_tx *tx, struct ds_pool_hdl *pool_hdl, struct cont *cont, crt_rpc_t *rpc) { struct cont_open_in *in = crt_req_get(rpc); daos_iov_t key; daos_iov_t value; struct container_hdl chdl; int rc; D_DEBUG(DF_DSMS, DF_CONT": processing rpc %p: hdl="DF_UUID" capas="******"\n", DP_CONT(pool_hdl->sph_pool->sp_uuid, in->coi_op.ci_uuid), rpc, DP_UUID(in->coi_op.ci_hdl), in->coi_capas); /* Verify the pool handle capabilities. */ if ((in->coi_capas & DAOS_COO_RW) && !(pool_hdl->sph_capas & DAOS_PC_RW) && !(pool_hdl->sph_capas & DAOS_PC_EX)) D_GOTO(out, rc = -DER_NO_PERM); /* See if this container handle already exists. */ daos_iov_set(&key, in->coi_op.ci_hdl, sizeof(uuid_t)); daos_iov_set(&value, &chdl, sizeof(chdl)); rc = rdb_tx_lookup(tx, &cont->c_svc->cs_hdls, &key, &value); if (rc != -DER_NONEXIST) { if (rc == 0 && chdl.ch_capas != in->coi_capas) { D_ERROR(DF_CONT": found conflicting container handle\n", DP_CONT(cont->c_svc->cs_pool_uuid, cont->c_uuid)); rc = -DER_EXIST; } D_GOTO(out, rc); } rc = cont_open_bcast(rpc->cr_ctx, cont, in->coi_op.ci_pool_hdl, in->coi_op.ci_hdl, in->coi_capas); if (rc != 0) D_GOTO(out, rc); /* TODO: Rollback cont_open_bcast() on errors from now on. */ uuid_copy(chdl.ch_pool_hdl, pool_hdl->sph_uuid); uuid_copy(chdl.ch_cont, cont->c_uuid); chdl.ch_capas = in->coi_capas; rc = ds_cont_epoch_init_hdl(tx, cont, in->coi_op.ci_hdl, &chdl); if (rc != 0) D_GOTO(out, rc); rc = rdb_tx_update(tx, &cont->c_svc->cs_hdls, &key, &value); out: D_DEBUG(DF_DSMS, DF_CONT": replying rpc %p: %d\n", DP_CONT(pool_hdl->sph_pool->sp_uuid, in->coi_op.ci_uuid), rpc, rc); return rc; }
/* Look up the pool handle and the matching container service. */ void ds_cont_op_handler(crt_rpc_t *rpc) { struct cont_op_in *in = crt_req_get(rpc); struct cont_op_out *out = crt_reply_get(rpc); struct ds_pool_hdl *pool_hdl; crt_opcode_t opc = opc_get(rpc->cr_opc); daos_prop_t *prop = NULL; struct cont_svc *svc; int rc; pool_hdl = ds_pool_hdl_lookup(in->ci_pool_hdl); if (pool_hdl == NULL) D_GOTO(out, rc = -DER_NO_HDL); D_DEBUG(DF_DSMS, DF_CONT": processing rpc %p: hdl="DF_UUID" opc=%u\n", DP_CONT(pool_hdl->sph_pool->sp_uuid, in->ci_uuid), rpc, DP_UUID(in->ci_hdl), opc); /* * TODO: How to map to the correct container service among those * running of this storage node? (Currently, there is only one, with ID * 0, colocated with the pool service.) */ rc = cont_svc_lookup_leader(pool_hdl->sph_pool->sp_uuid, 0 /* id */, &svc, &out->co_hint); if (rc != 0) D_GOTO(out_pool_hdl, rc); rc = cont_op_with_svc(pool_hdl, svc, rpc); ds_rsvc_set_hint(svc->cs_rsvc, &out->co_hint); cont_svc_put_leader(svc); out_pool_hdl: D_DEBUG(DF_DSMS, DF_CONT": replying rpc %p: hdl="DF_UUID " opc=%u rc=%d\n", DP_CONT(pool_hdl->sph_pool->sp_uuid, in->ci_uuid), rpc, DP_UUID(in->ci_hdl), opc, rc); ds_pool_hdl_put(pool_hdl); out: /* cleanup the properties for cont_query */ if (opc == CONT_QUERY) { struct cont_query_out *cqo = crt_reply_get(rpc); prop = cqo->cqo_prop; } out->co_rc = rc; crt_reply_send(rpc); daos_prop_free(prop); return; }
static int cont_close(struct rdb_tx *tx, struct ds_pool_hdl *pool_hdl, struct cont *cont, crt_rpc_t *rpc) { struct cont_close_in *in = crt_req_get(rpc); daos_iov_t key; daos_iov_t value; struct container_hdl chdl; struct cont_tgt_close_rec rec; int rc; D_DEBUG(DF_DSMS, DF_CONT": processing rpc %p: hdl="DF_UUID"\n", DP_CONT(pool_hdl->sph_pool->sp_uuid, in->cci_op.ci_uuid), rpc, DP_UUID(in->cci_op.ci_hdl)); /* See if this container handle is already closed. */ daos_iov_set(&key, in->cci_op.ci_hdl, sizeof(uuid_t)); daos_iov_set(&value, &chdl, sizeof(chdl)); rc = rdb_tx_lookup(tx, &cont->c_svc->cs_hdls, &key, &value); if (rc != 0) { if (rc == -DER_NONEXIST) { D_DEBUG(DF_DSMS, DF_CONT": already closed: "DF_UUID"\n", DP_CONT(cont->c_svc->cs_pool->sp_uuid, cont->c_uuid), DP_UUID(in->cci_op.ci_hdl)); rc = 0; } D_GOTO(out, rc); } uuid_copy(rec.tcr_hdl, in->cci_op.ci_hdl); rec.tcr_hce = chdl.ch_hce; D_DEBUG(DF_DSMS, DF_CONT": closing: hdl="DF_UUID" hce="DF_U64"\n", DP_CONT(cont->c_svc->cs_pool_uuid, in->cci_op.ci_uuid), DP_UUID(rec.tcr_hdl), rec.tcr_hce); rc = cont_close_bcast(rpc->cr_ctx, cont->c_svc, &rec, 1 /* nrecs */); if (rc != 0) D_GOTO(out, rc); rc = cont_close_one_hdl(tx, cont->c_svc, rpc->cr_ctx, rec.tcr_hdl); out: D_DEBUG(DF_DSMS, DF_CONT": replying rpc %p: %d\n", DP_CONT(pool_hdl->sph_pool->sp_uuid, in->cci_op.ci_uuid), rpc, rc); return rc; }
/* Close an array of handles, possibly belonging to different containers. */ static int cont_close_hdls(struct cont_svc *svc, struct cont_tgt_close_rec *recs, int nrecs, crt_context_t ctx) { int i; int rc; D_ASSERTF(nrecs > 0, "%d\n", nrecs); D_DEBUG(DF_DSMS, DF_CONT": closing %d recs: recs[0].hdl="DF_UUID " recs[0].hce="DF_U64"\n", DP_CONT(svc->cs_pool_uuid, NULL), nrecs, DP_UUID(recs[0].tcr_hdl), recs[0].tcr_hce); rc = cont_close_bcast(ctx, svc, recs, nrecs); if (rc != 0) D_GOTO(out, rc); /* * Use one TX per handle to avoid calling ds_cont_epoch_fini_hdl() more * than once in a TX, in which case we would be attempting to query * uncommitted updates. This could be optimized by adding container * UUIDs into recs[i] and sorting recs[] by container UUIDs. Then we * could maintain a list of deleted LREs and a list of deleted LHEs for * each container while looping, and use the lists to update the GHCE * once for each container. This approach enables us to commit only * once (or when a TX becomes too big). */ for (i = 0; i < nrecs; i++) { struct rdb_tx tx; rc = rdb_tx_begin(svc->cs_rsvc->s_db, svc->cs_rsvc->s_term, &tx); if (rc != 0) break; rc = cont_close_one_hdl(&tx, svc, ctx, recs[i].tcr_hdl); if (rc != 0) { rdb_tx_end(&tx); break; } rc = rdb_tx_commit(&tx); rdb_tx_end(&tx); if (rc != 0) break; } out: D_DEBUG(DF_DSMS, DF_CONT": leaving: %d\n", DP_CONT(svc->cs_pool_uuid, NULL), rc); return rc; }
static int cont_query(struct rdb_tx *tx, struct ds_pool_hdl *pool_hdl, struct cont *cont, struct container_hdl *hdl, crt_rpc_t *rpc) { struct cont_query_in *in = crt_req_get(rpc); struct cont_query_out *out = crt_reply_get(rpc); daos_prop_t *prop = NULL; int rc = 0; D_DEBUG(DF_DSMS, DF_CONT": processing rpc %p: hdl="DF_UUID"\n", DP_CONT(pool_hdl->sph_pool->sp_uuid, in->cqi_op.ci_uuid), rpc, DP_UUID(in->cqi_op.ci_hdl)); rc = cont_query_bcast(rpc->cr_ctx, cont, in->cqi_op.ci_pool_hdl, in->cqi_op.ci_hdl, out); if (rc) return rc; /* the allocated prop will be freed after rpc replied in * ds_cont_op_handler. */ rc = cont_prop_read(tx, cont, in->cqi_bits, &prop); out->cqo_prop = prop; return rc; }
static int cont_open_bcast(crt_context_t ctx, struct cont *cont, const uuid_t pool_hdl, const uuid_t cont_hdl, uint64_t capas) { struct cont_tgt_open_in *in; struct cont_tgt_open_out *out; crt_rpc_t *rpc; int rc; D_DEBUG(DF_DSMS, DF_CONT": bcasting: pool_hdl="DF_UUID" cont_hdl=" DF_UUID" capas="******"\n", DP_CONT(cont->c_svc->cs_pool_uuid, cont->c_uuid), DP_UUID(pool_hdl), DP_UUID(cont_hdl), capas); rc = ds_cont_bcast_create(ctx, cont->c_svc, CONT_TGT_OPEN, &rpc); if (rc != 0) D_GOTO(out, rc); in = crt_req_get(rpc); uuid_copy(in->toi_pool_uuid, cont->c_svc->cs_pool_uuid); uuid_copy(in->toi_pool_hdl, pool_hdl); uuid_copy(in->toi_uuid, cont->c_uuid); uuid_copy(in->toi_hdl, cont_hdl); in->toi_capas = capas; rc = dss_rpc_send(rpc); if (rc != 0) D_GOTO(out_rpc, rc); out = crt_reply_get(rpc); rc = out->too_rc; if (rc != 0) { D_ERROR(DF_CONT": failed to open %d targets\n", DP_CONT(cont->c_svc->cs_pool_uuid, cont->c_uuid), rc); rc = -DER_IO; } out_rpc: crt_req_decref(rpc); out: D_DEBUG(DF_DSMS, DF_CONT": bcasted: pool_hdl="DF_UUID" cont_hdl="DF_UUID " capas="******": %d\n", DP_CONT(cont->c_svc->cs_pool_uuid, cont->c_uuid), DP_UUID(pool_hdl), DP_UUID(cont_hdl), capas, rc); return rc; }
/* * Look up the container handle, or if the RPC does not need this, call the * final handler. */ static int cont_op_with_cont(struct rdb_tx *tx, struct ds_pool_hdl *pool_hdl, struct cont *cont, crt_rpc_t *rpc) { struct cont_op_in *in = crt_req_get(rpc); daos_iov_t key; daos_iov_t value; struct container_hdl hdl; int rc; switch (opc_get(rpc->cr_opc)) { case CONT_OPEN: rc = cont_open(tx, pool_hdl, cont, rpc); break; case CONT_CLOSE: rc = cont_close(tx, pool_hdl, cont, rpc); break; default: /* Look up the container handle. */ daos_iov_set(&key, in->ci_hdl, sizeof(uuid_t)); daos_iov_set(&value, &hdl, sizeof(hdl)); rc = rdb_tx_lookup(tx, &cont->c_svc->cs_hdls, &key, &value); if (rc != 0) { if (rc == -DER_NONEXIST) { D_ERROR(DF_CONT": rejecting unauthorized " "operation: "DF_UUID"\n", DP_CONT(cont->c_svc->cs_pool_uuid, cont->c_uuid), DP_UUID(in->ci_hdl)); rc = -DER_NO_HDL; } else { D_ERROR(DF_CONT": failed to look up container" "handle "DF_UUID": %d\n", DP_CONT(cont->c_svc->cs_pool_uuid, cont->c_uuid), DP_UUID(in->ci_hdl), rc); } D_GOTO(out, rc); } rc = cont_op_with_hdl(tx, pool_hdl, cont, &hdl, rpc); } out: return rc; }
/* TODO: Use bulk bcast to support large recs[]. */ static int cont_close_bcast(crt_context_t ctx, struct cont_svc *svc, struct cont_tgt_close_rec recs[], int nrecs) { struct cont_tgt_close_in *in; struct cont_tgt_close_out *out; crt_rpc_t *rpc; int rc; D_DEBUG(DF_DSMS, DF_CONT": bcasting: recs[0].hdl="DF_UUID " recs[0].hce="DF_U64" nrecs=%d\n", DP_CONT(svc->cs_pool_uuid, NULL), DP_UUID(recs[0].tcr_hdl), recs[0].tcr_hce, nrecs); rc = ds_cont_bcast_create(ctx, svc, CONT_TGT_CLOSE, &rpc); if (rc != 0) D_GOTO(out, rc); in = crt_req_get(rpc); in->tci_recs.ca_arrays = recs; in->tci_recs.ca_count = nrecs; rc = dss_rpc_send(rpc); if (rc != 0) D_GOTO(out_rpc, rc); out = crt_reply_get(rpc); rc = out->tco_rc; if (rc != 0) { D_ERROR(DF_CONT": failed to close %d targets\n", DP_CONT(svc->cs_pool_uuid, NULL), rc); rc = -DER_IO; } out_rpc: crt_req_decref(rpc); out: D_DEBUG(DF_DSMS, DF_CONT": bcasted: hdls[0]="DF_UUID" nhdls=%d: %d\n", DP_CONT(svc->cs_pool_uuid, NULL), DP_UUID(recs[0].tcr_hdl), nrecs, rc); return rc; }
static int cont_query_bcast(crt_context_t ctx, struct cont *cont, const uuid_t pool_hdl, const uuid_t cont_hdl, struct cont_query_out *query_out) { struct cont_tgt_query_in *in; struct cont_tgt_query_out *out; crt_rpc_t *rpc; int rc; D_DEBUG(DF_DSMS, DF_CONT"bcasting pool_hld="DF_UUID" cont_hdl ="DF_UUID"\n", DP_CONT(cont->c_svc->cs_pool_uuid, cont->c_uuid), DP_UUID(pool_hdl), DP_UUID(cont_hdl)); rc = ds_cont_bcast_create(ctx, cont->c_svc, CONT_TGT_QUERY, &rpc); if (rc != 0) D_GOTO(out, rc); in = crt_req_get(rpc); uuid_copy(in->tqi_pool_uuid, pool_hdl); uuid_copy(in->tqi_cont_uuid, cont->c_uuid); out = crt_reply_get(rpc); out->tqo_min_purged_epoch = DAOS_EPOCH_MAX; rc = dss_rpc_send(rpc); if (rc != 0) D_GOTO(out_rpc, rc); out = crt_reply_get(rpc); rc = out->tqo_rc; if (rc != 0) { D_DEBUG(DF_DSMS, DF_CONT": failed to query %d targets\n", DP_CONT(cont->c_svc->cs_pool_uuid, cont->c_uuid), rc); D_GOTO(out_rpc, rc = -DER_IO); } out_rpc: crt_req_decref(rpc); out: return rc; }
static int cont_attr_set(struct rdb_tx *tx, struct ds_pool_hdl *pool_hdl, struct cont *cont, struct container_hdl *hdl, crt_rpc_t *rpc) { struct cont_attr_set_in *in = crt_req_get(rpc); D_DEBUG(DF_DSMS, DF_CONT": processing rpc %p: hdl="DF_UUID"\n", DP_CONT(pool_hdl->sph_pool->sp_uuid, in->casi_op.ci_uuid), rpc, DP_UUID(in->casi_op.ci_hdl)); return ds_rsvc_set_attr(cont->c_svc->cs_rsvc, tx, &cont->c_user, in->casi_bulk, rpc, in->casi_count); }
static int cont_destroy_bcast(crt_context_t ctx, struct cont_svc *svc, const uuid_t cont_uuid) { struct cont_tgt_destroy_in *in; struct cont_tgt_destroy_out *out; crt_rpc_t *rpc; int rc; D_DEBUG(DF_DSMS, DF_CONT": bcasting\n", DP_CONT(svc->cs_pool_uuid, cont_uuid)); rc = ds_cont_bcast_create(ctx, svc, CONT_TGT_DESTROY, &rpc); if (rc != 0) D_GOTO(out, rc); in = crt_req_get(rpc); uuid_copy(in->tdi_pool_uuid, svc->cs_pool_uuid); uuid_copy(in->tdi_uuid, cont_uuid); rc = dss_rpc_send(rpc); if (rc != 0) D_GOTO(out_rpc, rc); out = crt_reply_get(rpc); rc = out->tdo_rc; if (rc != 0) { D_ERROR(DF_CONT": failed to destroy %d targets\n", DP_CONT(svc->cs_pool_uuid, cont_uuid), rc); rc = -DER_IO; } out_rpc: crt_req_decref(rpc); out: D_DEBUG(DF_DSMS, DF_CONT": bcasted: %d\n", DP_CONT(svc->cs_pool_uuid, cont_uuid), rc); return rc; }
/* * Close container handles that are associated with "pool_hdls[n_pool_hdls]" * and managed by local container services. */ int ds_cont_close_by_pool_hdls(uuid_t pool_uuid, uuid_t *pool_hdls, int n_pool_hdls, crt_context_t ctx) { struct cont_svc *svc; struct rdb_tx tx; struct cont_tgt_close_rec *recs; size_t recs_size; int nrecs; int rc; D_DEBUG(DF_DSMS, DF_CONT": closing by %d pool hdls: pool_hdls[0]=" DF_UUID"\n", DP_CONT(pool_uuid, NULL), n_pool_hdls, DP_UUID(pool_hdls[0])); /* TODO: Do the following for all local container services. */ rc = cont_svc_lookup_leader(pool_uuid, 0 /* id */, &svc, NULL /* hint */); if (rc != 0) return rc; rc = rdb_tx_begin(svc->cs_rsvc->s_db, svc->cs_rsvc->s_term, &tx); if (rc != 0) D_GOTO(out_svc, rc); ABT_rwlock_wrlock(svc->cs_lock); rc = find_hdls_to_close(&tx, svc, pool_hdls, n_pool_hdls, &recs, &recs_size, &nrecs); if (rc != 0) D_GOTO(out_lock, rc); if (nrecs > 0) rc = cont_close_hdls(svc, recs, nrecs, ctx); D_FREE(recs); out_lock: ABT_rwlock_unlock(svc->cs_lock); rdb_tx_end(&tx); out_svc: cont_svc_put_leader(svc); return rc; }
static int bnx2x_send_msg2pf(struct bnx2x *bp, u8 *done, dma_addr_t msg_mapping) { struct cstorm_vf_zone_data __iomem *zone_data = REG_ADDR(bp, PXP_VF_ADDR_CSDM_GLOBAL_START); int tout = 600, interval = 100; /* wait for 60 seconds */ if (*done) { BNX2X_ERR("done was non zero before message to pf was sent\n"); WARN_ON(true); return -EINVAL; } /* Write message address */ writel(U64_LO(msg_mapping), &zone_data->non_trigger.vf_pf_channel.msg_addr_lo); writel(U64_HI(msg_mapping), &zone_data->non_trigger.vf_pf_channel.msg_addr_hi); /* make sure the address is written before FW accesses it */ wmb(); /* Trigger the PF FW */ writeb(1, &zone_data->trigger.vf_pf_channel.addr_valid); /* Wait for PF to complete */ while ((tout >= 0) && (!*done)) { msleep(interval); tout -= 1; /* progress indicator - HV can take its own sweet time in * answering VFs... */ DP_CONT(BNX2X_MSG_IOV, "."); } if (!*done) { BNX2X_ERR("PF response has timed out\n"); return -EAGAIN; } DP(BNX2X_MSG_SP, "Got a response from PF\n"); return 0; }
static int cont_destroy(struct rdb_tx *tx, struct ds_pool_hdl *pool_hdl, struct cont_svc *svc, crt_rpc_t *rpc) { struct cont_destroy_in *in = crt_req_get(rpc); daos_iov_t key; daos_iov_t value; rdb_path_t kvs; int rc; D_DEBUG(DF_DSMS, DF_CONT": processing rpc %p: force=%u\n", DP_CONT(pool_hdl->sph_pool->sp_uuid, in->cdi_op.ci_uuid), rpc, in->cdi_force); /* Verify the pool handle capabilities. */ if (!(pool_hdl->sph_capas & DAOS_PC_RW) && !(pool_hdl->sph_capas & DAOS_PC_EX)) D_GOTO(out, rc = -DER_NO_PERM); /* Check if the container attribute KVS exists. */ daos_iov_set(&key, in->cdi_op.ci_uuid, sizeof(uuid_t)); daos_iov_set(&value, NULL /* buf */, 0 /* size */); rc = rdb_tx_lookup(tx, &svc->cs_conts, &key, &value); if (rc != 0) { if (rc == -DER_NONEXIST) rc = 0; D_GOTO(out, rc); } /* Create a path to the container attribute KVS. */ rc = rdb_path_clone(&svc->cs_conts, &kvs); if (rc != 0) D_GOTO(out, rc); rc = rdb_path_push(&kvs, &key); if (rc != 0) D_GOTO(out_kvs, rc); rc = cont_destroy_bcast(rpc->cr_ctx, svc, in->cdi_op.ci_uuid); if (rc != 0) D_GOTO(out_kvs, rc); /* Destroy the user attributes KVS. */ rc = rdb_tx_destroy_kvs(tx, &kvs, &ds_cont_attr_user); if (rc != 0) D_GOTO(out_kvs, rc); /* Destroy the snapshot KVS. */ rc = rdb_tx_destroy_kvs(tx, &kvs, &ds_cont_prop_snapshots); if (rc != 0) D_GOTO(out_kvs, rc); /* Destroy the LHE and LRE KVSs. */ rc = rdb_tx_destroy_kvs(tx, &kvs, &ds_cont_prop_lhes); if (rc != 0) D_GOTO(out_kvs, rc); rc = rdb_tx_destroy_kvs(tx, &kvs, &ds_cont_prop_lres); if (rc != 0) D_GOTO(out_kvs, rc); /* Destroy the container attribute KVS. */ rc = rdb_tx_destroy_kvs(tx, &svc->cs_conts, &key); out_kvs: rdb_path_fini(&kvs); out: D_DEBUG(DF_DSMS, DF_CONT": replying rpc %p: %d\n", DP_CONT(pool_hdl->sph_pool->sp_uuid, in->cdi_op.ci_uuid), rpc, rc); return rc; }
static int cont_create(struct rdb_tx *tx, struct ds_pool_hdl *pool_hdl, struct cont_svc *svc, crt_rpc_t *rpc) { struct cont_create_in *in = crt_req_get(rpc); daos_prop_t *prop_dup = NULL; daos_iov_t key; daos_iov_t value; struct rdb_kvs_attr attr; rdb_path_t kvs; uint64_t ghce = 0; uint64_t ghpce = 0; uint64_t max_oid = 0; int rc; D_DEBUG(DF_DSMS, DF_CONT": processing rpc %p\n", DP_CONT(pool_hdl->sph_pool->sp_uuid, in->cci_op.ci_uuid), rpc); /* Verify the pool handle capabilities. */ if (!(pool_hdl->sph_capas & DAOS_PC_RW) && !(pool_hdl->sph_capas & DAOS_PC_EX)) D_GOTO(out, rc = -DER_NO_PERM); /* Check if a container with this UUID already exists. */ daos_iov_set(&key, in->cci_op.ci_uuid, sizeof(uuid_t)); daos_iov_set(&value, NULL /* buf */, 0 /* size */); rc = rdb_tx_lookup(tx, &svc->cs_conts, &key, &value); if (rc != -DER_NONEXIST) { if (rc == 0) D_DEBUG(DF_DSMS, DF_CONT": container already exists\n", DP_CONT(pool_hdl->sph_pool->sp_uuid, in->cci_op.ci_uuid)); D_GOTO(out, rc); } /* * Target-side creations (i.e., vos_cont_create() calls) are * deferred to the time when the container is first successfully * opened. */ /* Create the container attribute KVS under the container KVS. */ daos_iov_set(&key, in->cci_op.ci_uuid, sizeof(uuid_t)); attr.dsa_class = RDB_KVS_GENERIC; attr.dsa_order = 16; rc = rdb_tx_create_kvs(tx, &svc->cs_conts, &key, &attr); if (rc != 0) { D_ERROR("failed to create container attribute KVS: " "%d\n", rc); D_GOTO(out, rc); } /* Create a path to the container attribute KVS. */ rc = rdb_path_clone(&svc->cs_conts, &kvs); if (rc != 0) D_GOTO(out, rc); rc = rdb_path_push(&kvs, &key); if (rc != 0) D_GOTO(out_kvs, rc); /* Create the GHCE and GHPCE properties. */ daos_iov_set(&value, &ghce, sizeof(ghce)); rc = rdb_tx_update(tx, &kvs, &ds_cont_prop_ghce, &value); if (rc != 0) D_GOTO(out_kvs, rc); daos_iov_set(&value, &ghpce, sizeof(ghpce)); rc = rdb_tx_update(tx, &kvs, &ds_cont_prop_ghpce, &value); if (rc != 0) D_GOTO(out_kvs, rc); daos_iov_set(&value, &max_oid, sizeof(max_oid)); rc = rdb_tx_update(tx, &kvs, &ds_cont_prop_max_oid, &value); if (rc != 0) D_GOTO(out_kvs, rc); /* duplicate the default properties, overwrite it with cont create * parameter and then write to rdb. */ prop_dup = daos_prop_dup(&cont_prop_default, false); if (prop_dup == NULL) { D_ERROR("daos_prop_dup failed.\n"); D_GOTO(out_kvs, rc = -DER_NOMEM); } rc = cont_prop_default_copy(prop_dup, in->cci_prop); if (rc != 0) D_GOTO(out_kvs, rc); rc = cont_prop_write(tx, &kvs, prop_dup); if (rc != 0) D_GOTO(out_kvs, rc); /* Create the LRE and LHE KVSs. */ attr.dsa_class = RDB_KVS_INTEGER; attr.dsa_order = 16; rc = rdb_tx_create_kvs(tx, &kvs, &ds_cont_prop_lres, &attr); if (rc != 0) D_GOTO(out_kvs, rc); rc = rdb_tx_create_kvs(tx, &kvs, &ds_cont_prop_lhes, &attr); if (rc != 0) D_GOTO(out_kvs, rc); /* Create the snapshot KVS. */ attr.dsa_class = RDB_KVS_INTEGER; attr.dsa_order = 16; rc = rdb_tx_create_kvs(tx, &kvs, &ds_cont_prop_snapshots, &attr); /* Create the user attribute KVS. */ attr.dsa_class = RDB_KVS_GENERIC; attr.dsa_order = 16; rc = rdb_tx_create_kvs(tx, &kvs, &ds_cont_attr_user, &attr); out_kvs: daos_prop_free(prop_dup); rdb_path_fini(&kvs); out: return rc; }
int ds_cont_oid_fetch_add(uuid_t poh_uuid, uuid_t co_uuid, uuid_t coh_uuid, uint64_t num_oids, uint64_t *oid) { struct ds_pool_hdl *pool_hdl; struct cont_svc *svc; struct rdb_tx tx; struct cont *cont = NULL; daos_iov_t key; daos_iov_t value; struct container_hdl hdl; uint64_t max_oid; int rc; pool_hdl = ds_pool_hdl_lookup(poh_uuid); if (pool_hdl == NULL) D_GOTO(out, rc = -DER_NO_HDL); /* * TODO: How to map to the correct container service among those * running of this storage node? (Currently, there is only one, with ID * 0, colocated with the pool service.) */ rc = cont_svc_lookup_leader(pool_hdl->sph_pool->sp_uuid, 0, &svc, NULL); if (rc != 0) D_GOTO(out_pool_hdl, rc); rc = rdb_tx_begin(svc->cs_rsvc->s_db, svc->cs_rsvc->s_term, &tx); if (rc != 0) D_GOTO(out_svc, rc); ABT_rwlock_wrlock(svc->cs_lock); rc = cont_lookup(&tx, svc, co_uuid, &cont); if (rc != 0) D_GOTO(out_lock, rc); /* Look up the container handle. */ daos_iov_set(&key, coh_uuid, sizeof(uuid_t)); daos_iov_set(&value, &hdl, sizeof(hdl)); rc = rdb_tx_lookup(&tx, &cont->c_svc->cs_hdls, &key, &value); if (rc != 0) { if (rc == -DER_NONEXIST) rc = -DER_NO_HDL; D_GOTO(out_cont, rc); } /* Read the max OID from the container metadata */ daos_iov_set(&value, &max_oid, sizeof(max_oid)); rc = rdb_tx_lookup(&tx, &cont->c_prop, &ds_cont_prop_max_oid, &value); if (rc != 0) { D_ERROR(DF_CONT": failed to lookup max_oid: %d\n", DP_CONT(cont->c_svc->cs_pool_uuid, cont->c_uuid), rc); D_GOTO(out_cont, rc); } /** Set the oid for the caller */ *oid = max_oid; /** Increment the max_oid by how many oids user requested */ max_oid += num_oids; /* Update the max OID */ rc = rdb_tx_update(&tx, &cont->c_prop, &ds_cont_prop_max_oid, &value); if (rc != 0) { D_ERROR(DF_CONT": failed to update max_oid: %d\n", DP_CONT(cont->c_svc->cs_pool_uuid, cont->c_uuid), rc); D_GOTO(out_cont, rc); } rc = rdb_tx_commit(&tx); out_cont: cont_put(cont); out_lock: ABT_rwlock_unlock(svc->cs_lock); rdb_tx_end(&tx); out_svc: cont_svc_put_leader(svc); out_pool_hdl: ds_pool_hdl_put(pool_hdl); out: return rc; }