void as_namespace_get_bins_info(as_namespace *ns, cf_dyn_buf *db, bool show_ns) { if (show_ns) { cf_dyn_buf_append_string(db, ns->name); cf_dyn_buf_append_char(db, ':'); } if (ns->single_bin) { cf_dyn_buf_append_string(db, "[single-bin]"); } else { uint32_t bin_count = cf_vmapx_count(ns->p_bin_name_vmap); cf_dyn_buf_append_string(db, "num-bin-names="); cf_dyn_buf_append_uint32(db, bin_count); cf_dyn_buf_append_string(db, ",bin-names-quota="); cf_dyn_buf_append_uint32(db, BIN_NAMES_QUOTA); for (uint32_t i = 0; i < bin_count; i++) { cf_dyn_buf_append_char(db, ','); cf_dyn_buf_append_string(db, as_bin_get_name_from_id(ns, (uint16_t)i)); } } if (show_ns) { cf_dyn_buf_append_char(db, ';'); } }
// Does not check bin name length. // Checks bin name quota - use appropriately. as_bin * as_bin_get_or_create(as_storage_rd *rd, const char *name) { if (rd->ns->single_bin) { if (! as_bin_inuse_has(rd)) { as_bin_init_nameless(rd->bins); } return rd->bins; } uint32_t id = (uint32_t)-1; uint16_t i; as_bin *b; if (cf_vmapx_get_index(rd->ns->p_bin_name_vmap, name, &id) == CF_VMAPX_OK) { for (i = 0; i < rd->n_bins; i++) { b = &rd->bins[i]; if (! as_bin_inuse(b)) { break; } if ((uint32_t)b->id == id) { return b; } } } else { if (cf_vmapx_count(rd->ns->p_bin_name_vmap) >= BIN_NAMES_QUOTA) { cf_warning(AS_BIN, "{%s} bin-name quota full - can't add new bin-name %s", rd->ns->name, name); return NULL; } i = as_bin_inuse_count(rd); } if (i >= rd->n_bins) { cf_crash(AS_BIN, "ran out of allocated bins in rd"); } b = &rd->bins[i]; if (id == (uint32_t)-1) { as_bin_init(rd->ns, b, name); } else { as_bin_init_nameless(b); b->id = (uint16_t)id; } return b; }
as_bin * as_bin_get_and_reserve_name(as_storage_rd *rd, byte *name, size_t namesz, bool *p_reserved, uint32_t *p_idx) { *p_reserved = true; if (rd->ns->single_bin) { return as_bin_inuse_has(rd) ? rd->bins : NULL; } char zname[namesz + 1]; memcpy(zname, name, namesz); zname[namesz] = 0; if (cf_vmapx_get_index(rd->ns->p_bin_name_vmap, zname, p_idx) != CF_VMAPX_OK) { if (cf_vmapx_count(rd->ns->p_bin_name_vmap) >= BIN_NAMES_QUOTA) { cf_warning(AS_BIN, "{%s} bin-name quota full - can't add new bin-name %s", rd->ns->name, zname); *p_reserved = false; } else { cf_vmapx_err result = cf_vmapx_put_unique(rd->ns->p_bin_name_vmap, zname, p_idx); if (! (result == CF_VMAPX_OK || result == CF_VMAPX_ERR_NAME_EXISTS)) { cf_warning(AS_BIN, "{%s} can't add new bin name %s, vmap err %d", rd->ns->name, zname, result); *p_reserved = false; } } return NULL; } for (uint16_t i = 0; i < rd->n_bins; i++) { as_bin *b = &rd->bins[i]; if (! as_bin_inuse(b)) { break; } if ((uint32_t)b->id == *p_idx) { return b; } } return NULL; }
bool as_bin_name_within_quota(as_namespace *ns, const char *name) { // Won't exceed quota if single-bin or currently below quota. if (ns->single_bin || cf_vmapx_count(ns->p_bin_name_vmap) < BIN_NAMES_QUOTA) { return true; } // Won't exceed quota if name is found (and so would NOT be added to vmap). if (cf_vmapx_get_index(ns->p_bin_name_vmap, name, NULL) == CF_VMAPX_OK) { return true; } cf_warning(AS_BIN, "{%s} bin-name quota full - can't add new bin-name %s", ns->name, name); return false; }
void as_namespace_get_set_info(as_namespace *ns, const char *set_name, cf_dyn_buf *db) { as_set *p_set; if (set_name) { if (cf_vmapx_get_by_name(ns->p_sets_vmap, set_name, (void**)&p_set) == CF_VMAPX_OK) { append_set_props(p_set, db); } return; } for (uint32_t idx = 0; idx < cf_vmapx_count(ns->p_sets_vmap); idx++) { if (cf_vmapx_get_by_index(ns->p_sets_vmap, idx, (void**)&p_set) == CF_VMAPX_OK) { cf_dyn_buf_append_string(db, "ns_name="); cf_dyn_buf_append_string(db, ns->name); cf_dyn_buf_append_char(db, ':'); cf_dyn_buf_append_string(db, "set_name="); cf_dyn_buf_append_string(db, p_set->name); cf_dyn_buf_append_char(db, ':'); append_set_props(p_set, db); } } }
// Does not check bin name length. // Checks bin name quota and bin-level policy - use appropriately. as_bin * as_bin_get_or_create_from_buf(as_storage_rd *rd, byte *name, size_t namesz, bool create_only, bool replace_only, int *p_result) { if (rd->ns->single_bin) { if (! as_bin_inuse_has(rd)) { as_bin_init_nameless(rd->bins); } // Ignored bin-level policy - single-bin needs only record-level policy. return rd->bins; } uint32_t id = (uint32_t)-1; uint16_t i; as_bin *b; if (cf_vmapx_get_index_w_len(rd->ns->p_bin_name_vmap, (const char *)name, namesz, &id) == CF_VMAPX_OK) { for (i = 0; i < rd->n_bins; i++) { b = &rd->bins[i]; if (! as_bin_inuse(b)) { break; } if ((uint32_t)b->id == id) { if (as_bin_is_hidden(b)) { cf_warning(AS_BIN, "cannot manipulate hidden bin directly"); *p_result = AS_PROTO_RESULT_FAIL_INCOMPATIBLE_TYPE; return NULL; } if (create_only) { *p_result = AS_PROTO_RESULT_FAIL_BIN_EXISTS; return NULL; } return b; } } } else { if (cf_vmapx_count(rd->ns->p_bin_name_vmap) >= BIN_NAMES_QUOTA) { char zname[namesz + 1]; memcpy(zname, name, namesz); zname[namesz] = 0; cf_warning(AS_BIN, "{%s} bin-name quota full - can't add new bin-name %s", rd->ns->name, zname); *p_result = AS_PROTO_RESULT_FAIL_BIN_NAME; return NULL; } i = as_bin_inuse_count(rd); } if (replace_only) { *p_result = AS_PROTO_RESULT_FAIL_BIN_NOT_FOUND; return NULL; } if (i >= rd->n_bins) { cf_crash(AS_BIN, "ran out of allocated bins in rd"); } b = &rd->bins[i]; if (id == (uint32_t)-1) { as_bin_init_w_len(rd->ns, b, name, namesz); } else { as_bin_init_nameless(b); b->id = (uint16_t)id; } return b; }