48 #define MAX_BLOCK_COUNT (200) 53 #define HSM_EXTENT_SCAN_BATCH 8 66 #define ERROR(_fmt, ...) if (options.trace_level >= LOG_ERROR) \ 67 fprintf(options.log_stream, _fmt, ##__VA_ARGS__) 68 #define INFO(_fmt, ...) if (options.trace_level >= LOG_INFO) \ 69 fprintf(options.log_stream, _fmt, ##__VA_ARGS__) 70 #define VERB(_fmt, ...) if (options.trace_level >= LOG_VERB) \ 71 fprintf(options.log_stream, _fmt, ##__VA_ARGS__) 72 #define DBG(_fmt, ...) if (options.trace_level >= LOG_DEBUG) \ 73 fprintf(options.log_stream, _fmt, ##__VA_ARGS__) 75 #define ENTRY DBG("> ENTERING %s()\n", __func__) 76 #define RETURN(_rc) do { DBG("< LEAVING %s() line %d, rc=%d\n", \ 77 __func__, __LINE__, (_rc)); \ 78 return (_rc); } while(0) 110 for (ln=1; max_params > 0 && fgets(
s,
MAX_LEN, in); ln++) {
111 if (sscanf(
s,
" %[#\n\r]",
p->name))
113 if (sscanf(
s,
" %[a-z_A-Z0-9] = %[^#\n\r]",
114 p->name,
p->value) < 2) {
115 ERROR(
"m0hsm: %s: error at line %d: %s\n", __func__,
119 DBG(
"%s: %d: name='%s' value='%s'\n", __func__,
120 ln,
p->name,
p->value);
121 p++, max_params--,
n++;
133 sprintf(pname,
"M0_POOL_TIER%d",
i + 1);
134 if (strcmp(
p->name, pname) == 0) {
136 ERROR(
"%s: failed to parse FID of %s\n",
151 for (
i = 0;
n > 0;
n--,
p++,
i +=
rc) {
153 DBG(
"%s: rc=%d\n", __func__,
rc);
159 ERROR(
"m0hsm: no pools configured\n");
178 ERROR(
"Missing instance or realm argument to %s()\n", __func__);
187 ERROR(
"%s: failed to read parameters\n", __func__);
191 DBG(
"%s: read %d params\n", __func__,
rc);
194 ERROR(
"%s: failed to configure pools\n", __func__);
202 #define HSM_ANY_TIER UINT8_MAX 205 #define HSM_ID_MASK_HI (1LL<<31) 221 static uint32_t
hsm_prio(uint32_t generation, uint8_t tier_idx)
229 gen_prio = 0x00FFFFFF - generation;
231 return (gen_prio << 8) | tier_idx;
254 return 0x00FFFFFF - (priority >> 8);
262 return priority & 0xFF;
271 if (tier_idx < 1 || tier_idx >
MAX_POOLS)
302 bool close_entity, uint8_t tier_idx)
320 }
else if (
rc != -ENOENT) {
330 ERROR(
"m0hsm: pool index %d is not configured\n", tier_idx);
447 memset(&parent_obj, 0,
sizeof(
struct m0_obj));
468 parent_layout, &
ops[1]);
580 memset(&
obj, 0,
sizeof(
obj));
599 ccr_tlink, ccr_tlink_magic,
605 ce_tlink, ce_tlink_magic,
616 int *rc_list, int32_t
flags)
623 keys, vals, rc_list,
flags, &
ops[0]);
646 struct m0_tl *ext_list,
684 cext_tlink_init_at_tail(ext, ext_list);
687 ext = cext_tlist_tail(ext_list);
724 struct m0_tl *ext_list)
726 struct m0_idx idx = {{0}};
735 if (!cext_tlist_is_empty(ext_list))
748 if (rc_list ==
NULL) {
793 bool is_first =
true;
820 fprintf(
stream,
"priority=%#x (gen=%u, tier=%hhu)\n",
825 fprintf(
stream,
"gen %u, tier %hhu, extents: ",
836 fprintf(
stream,
"R extents:\n");
840 fprintf(
stream,
"W extents:\n");
844 fprintf(
stream,
" (writable)\n");
857 clayout =
M0_AMB(clayout, layout, ccl_layout);
867 fprintf(
stream,
"==== layer #%d ====\n",
i);
906 bool write,
bool overwrite)
926 key.cek_layer_id = subobjid;
940 memset(&idx, 0,
sizeof idx);
949 overwrite ?
"Changing" :
"Adding",
950 write ?
"write" :
"read",
964 rc =
ops[0]->op_sm.sm_rc;
995 key.cek_layer_id = subobjid;
1003 memset(&idx, 0,
sizeof idx);
1011 " (if it exists)\n", write ?
"write" :
"read",
1012 subobjid.
u_hi, subobjid.
u_lo, off);
1023 rc =
ops[0]->op_sm.sm_rc;
1043 struct m0_uint128 *max_gen_id, uint8_t *top_tier)
1052 clayout =
M0_AMB(clayout, layout, ccl_layout);
1063 if (
gen > *max_gen) {
1067 if (top_tier !=
NULL && tier < *top_tier)
1140 clayout =
M0_AMB(clayout, layout, ccl_layout);
1160 struct m0_obj subobj = {};
1166 DBG(
"Adding new layer in tier %u to collect new writes\n", tier);
1170 ERROR(
"No layers in composite object\n");
1175 VERB(
"Creating new layer: gen=%d, tier=%hhu\n",
gen, tier);
1202 if (
rc != 0 &&
rc != -ENOENT &&
rc != -ENOTEMPTY)
1218 if (clayout ==
NULL)
1221 return clayer_tlist_head(&clayout->
ccl_layers);
1241 INFO(
"Writable layer is already in tier %u\n", tier_idx);
1264 #define MAX(_x, _y) ((_x) > (_y) ? (_x) : (_y)) 1265 #define MIN(_x, _y) ((_x) < (_y) ? (_x) : (_y)) 1268 struct m0_tl *ext_list,
1269 const struct extent *ext_in,
1276 off_t end = ext_in->
off + ext_in->
len - 1;
1277 bool is_merged =
false;
1305 (ext_end >= ext_in->
off && ext_end <= end)) {
1309 m_end =
MIN(ext_end, end);
1320 m_end =
MAX(ext_end, end);
1326 ext->
ce_off, is_write) != 0)
1328 cext_tlist_del(ext);
1345 DBG(
"Merge with previous extent " 1364 DBG(
"Merge with next extent starting " 1371 ext->
ce_off, is_write) != 0)
1373 cext_tlist_del(ext);
1391 struct m0_tl *ext_list,
1392 const struct extent *ext_in,
1409 int remaining_extent = 0;
1415 remaining_extent ++;
1433 cext_tlist_del(ext);
1435 remaining_extent --;
1439 if (ext_in->
off + ext_in->
len <
1441 new_ext.
off = ext_in->
off + ext_in->
len;
1449 remaining_extent ++;
1464 remaining_extent ++;
1467 if (ext_in->
off + ext_in->
len <
1469 new_ext.
off = ext_in->
off + ext_in->
len;
1470 new_ext.
len = ext_end - new_ext.
off + 1;
1478 remaining_extent ++;
1482 *layer_empty = (remaining_extent == 0);
1488 const struct extent *ext_in)
1491 struct extent ext_merge = {.
off = -1LL, .len = 0};
1504 ERROR(
"Failed to match/merge extent\n");
1514 DBG(
"Extent included to another. Nothing to do\n");
1519 DBG(
"Extent overlap detected: must merge\n");
1526 ERROR(
"ERROR: unexpected match type\n");
1538 const struct extent *ext)
1572 uint8_t tier_idx,
bool keep_open)
1577 struct m0_obj subobj = {};
1591 if (layout ==
NULL) {
1607 if (
rc != 0 && layout !=
NULL) {
1619 }
else if (
rc == 0) {
1628 if (
rc == 0 && !keep_open)
1632 INFO(
"Composite object successfully created with " 1700 for (j = 0; j < bsize; j++)
1715 if (blocks !=
ctx->curr_blocks || block_size !=
ctx->curr_bsize) {
1716 if (alloc_io_buff) {
1717 if (
ctx->curr_blocks != 0)
1725 if (
ctx->curr_blocks != 0)
1735 if (blocks !=
ctx->curr_blocks) {
1738 if (
ctx->curr_blocks > 0) {
1753 ctx->curr_blocks = blocks;
1754 ctx->curr_bsize = block_size;
1761 if (!
vec->ov_vec.v_count || !
vec->ov_buf)
1765 if (
vec->ov_vec.v_nr != blocks)
1776 off_t
offset,
char *buff)
1780 if (!
ctx || blocks == 0)
1786 for (
i = 0;
i < blocks;
i++) {
1791 ctx->ext.iv_index[
i],
ctx->ext.iv_vec.v_count[
i]);
1794 ctx->attr.ov_vec.v_count[
i] = 0;
1796 if (
ctx->data.ov_vec.v_count[
i] == 0)
1799 else if (
ctx->data.ov_vec.v_count[
i] !=
b_size)
1846 lid =
obj->ob_attr.oa_layout_id;
1848 &
obj->ob_attr.oa_pver);
1850 ERROR(
"Cannot find the object's pool version\n");
1854 pa = &
pver->pv_attr;
1855 gsz = usz * pa->
pa_N;
1859 VERB(
"usz=%lu pool="FID_F" (N,K,S,P)=(%u,%u,%u,%u) max_bs=%" PRId64 "\n", usz,
1862 if (obj_sz >= max_bs)
1864 else if (obj_sz <= gsz)
1896 ERROR(
"Could not get object's layout: rc=%d\n",
rc);
1901 if (layer ==
NULL) {
1902 ERROR(
"Could not get the object's top layer\n");
1914 if (block_size == 0) {
1915 ERROR(
"Could not get the optimal block size for the object\n");
1921 VERB(
"Using I/O block size of %zu bytes\n", block_size);
1923 for (; rest > 0; rest -= block_size, off += block_size) {
1924 if (rest < block_size)
1930 ERROR(
"prepare_io_ctx() failed: rc=%d\n",
rc);
1936 ERROR(
"map_io_ctx() failed: rc=%d\n",
rc);
1946 ERROR(
"write_blocks() failed: rc=%d\n",
rc);
1961 INFO(
"%zu bytes successfully written at offset %#" PRIx64 " " 1973 ssize_t rest = length;
1976 char *pad_buf =
NULL;
1987 VERB(
"using io_size of %zu bytes\n", io_size);
1991 blocks = rest / io_size;
1996 INFO(
"Padding last block of unaligned size %zd up to " 1997 "%zu\n", rest, io_size);
1998 pad_buf = calloc(1, io_size);
2003 memcpy(pad_buf,
buf, rest);
2005 wext.
len += io_size - rest;
2006 length += io_size - rest;
2017 buf += blocks * io_size;
2018 off += blocks * io_size;
2019 rest -= blocks * io_size;
2034 INFO(
"%zu bytes successfully written at offset %#" PRIx64 " " 2064 VERB(
"using io_size of %zu bytes\n", io_size);
2070 for (rest = len; rest > 0; rest -= blocks * io_size) {
2072 blocks = rest / io_size;
2090 start += blocks * io_size;
2099 INFO(
"%zu bytes successfully read at offset %#" PRIx64 " " 2109 const struct extent *range)
2111 struct m0_obj src_obj = {};
2112 struct m0_obj tgt_obj = {};
2115 size_t rest = range->
len;
2134 if (block_size == 0) {
2135 ERROR(
"Could not get the optimal block size for the object\n");
2140 VERB(
"Using I/O block size of %zu bytes\n", block_size);
2142 for (; rest > 0; rest -= block_size,
start += block_size) {
2143 if (rest < block_size)
2149 ERROR(
"prepare_io_ctx() failed: rc=%d\n",
rc);
2155 ERROR(
"map_io_ctx() failed: rc=%d\n",
rc);
2162 ERROR(
"read_blocks() failed: rc=%d\n",
rc);
2169 ERROR(
"write_blocks() failed: rc=%d\n",
rc);
2182 INFO(
"%zu bytes successfully copied from subobj " 2184 " at offset %#" PRIx64 "\n", range->
len,
2193 int max_prio,
int tier)
2229 const struct extent *ext,
2240 clayout =
M0_AMB(clayout, layout, ccl_layout);
2254 struct extent ext_curr = *ext;
2264 VERB(
"Found layer %s matching extent " 2267 m ==
EM_FULL ?
"fully" :
"partially",
2273 if (
rc && stop_on_error)
2299 clayout =
M0_AMB(clayout, layout, ccl_layout);
2336 DBG(
"%s: skip layer of lower generation %u\n", __func__,
2352 DBG(
"%s: partial match\n", __func__);
2375 "-%#" PRIx64 "] with generation >= %d: " 2376 "can't release it from tier %u\n",
2398 bool layer_empty =
false;
2405 if (
ctx->max_gen != -1) {
2411 if (
ctx->max_tier != -1) {
2429 if (
rc == -ENOENT) {
2438 false, &layer_empty);
2447 VERB(
"No remaining extent in layer: deleting " 2463 off_t
offset,
size_t len,
2484 ctx.max_gen = max_gen;
2485 ctx.max_tier = tier;
2488 if (
rc == 0 &&
ctx.found == 0 && user_display)
2489 ERROR(
"No matching extent found\n");
2520 ctx.max_tier = max_tier;
2524 if (
rc == 0 &&
ctx.found == 0)
2525 ERROR(
"No matching extent found\n");
2546 struct m0_obj subobj = {};
2548 int tgt_prio, w_prio;
2564 "tier %u to tier %u\n",
2565 ctx->src_tier >
ctx->tgt_tier ?
"Staging" :
"Archiving",
2573 w_tier =
ctx->tgt_tier;
2579 w_tier =
ctx->src_tier;
2582 if (
rc == -ENOENT) {
2600 struct extent already_ext;
2602 DBG(
"Target layer already exists\n");
2614 ERROR(
"Extent matching error\n");
2617 VERB(
"No previous copy of this extent\n");
2620 VERB(
"Extent already been partially copied to target tier\n");
2625 VERB(
"Extent has already been " 2626 "copied to target tier: nothing to do\n");
2634 ERROR(
"copy_extent_data() failed: rc=%d\n",
rc);
2639 if (tgt_layer ==
NULL) {
2643 ERROR(
"layer_extent_add() failed: rc=%d\n",
rc);
2650 DBG(
"Adding subobj <%" PRIx64 ":%" PRIx64 "> as layer with prio %#x\n",
2651 subobj_id.
u_hi, subobj_id.
u_lo, tgt_prio);
2656 ERROR(
"layout_set() failed: rc=%d\n",
rc);
2663 ERROR(
"add_merge_read_extent() failed: rc=%d\n",
rc);
2685 if (tgt_layer !=
NULL)
2689 ERROR(
"release_cb() failed: rc=%d\n",
rc);
2697 VERB(
"Releasing extents [%#" PRIx64 "-%#" PRIx64 "] in tier %d, with gen <= %d\n",
2704 ERROR(
"m0hsm_release_maxgen() failed: rc=%d\n",
rc);
2709 if (tgt_layer ==
NULL)
2733 ctx.src_tier = src_tier;
2734 ctx.tgt_tier = tgt_tier;
2743 if (
rc == 0 &&
ctx.found == 0)
2744 ERROR(
"No matching extent found\n");
2768 ctx->src_tier = tier;
2784 ctx.tgt_tier = tgt_tier;
2802 if (
rc == 0 &&
ctx.found == 0)
2803 ERROR(
"No matching extent found\n");
2821 if (tier >=
ctx->tgt_tier)
2826 ctx->src_tier = tier;
2842 ctx.tgt_tier = tgt_tier;
2860 if (
rc == 0 &&
ctx.found == 0)
2861 ERROR(
"No matching extent found\n");
M0_INTERNAL int m0_uint128_cmp(const struct m0_uint128 *u0, const struct m0_uint128 *u1)
static int match_layer_foreach(struct m0_client_layout *layout, uint8_t tier, const struct extent *ext, match_layer_cb_t cb, void *cb_arg, bool stop_on_error)
int m0hsm_archive(struct m0_uint128 id, uint8_t tgt_tier, off_t offset, size_t length, enum hsm_cp_flags flags)
static struct m0_addb2_philter p
static struct m0_be_active_record_domain dummy
#define M0_ALLOC_ARR(arr, nr)
void m0_entity_fini(struct m0_entity *entity)
static void layout_top_prio(struct m0_client_layout *layout, int32_t *max_gen, struct m0_uint128 *max_gen_id, uint8_t *top_tier)
M0_INTERNAL int m0_indexvec_alloc(struct m0_indexvec *ivec, uint32_t len)
static int prepare_io_ctx(struct io_ctx *ctx, int blocks, size_t block_size, bool alloc_io_buff)
static enum ext_match_code ext_match(struct m0_uint128 layer_id, struct m0_tl *ext_list, const struct extent *ext_in, struct extent *match, enum ext_match_type mode, bool is_write, bool del_prev)
static int check_min_gen_exists(struct m0_client_layout *layout, const struct extent *ext, int gen, struct m0_composite_layer *except_layer)
int const char const void size_t int flags
static int top_layer_add_read_extent(struct m0_obj *obj, const struct extent *ext)
uint64_t get_optimal_bs(struct m0_obj *obj, uint64_t obj_sz)
static struct m0_addb2_mach * m
int m0hsm_stage(struct m0_uint128 id, uint8_t tgt_tier, off_t offset, size_t length, enum hsm_cp_flags flags)
const m0_time_t M0_TIME_NEVER
void m0_op_fini(struct m0_op *op)
M0_INTERNAL struct m0_pool_version * m0_pool_version_find(struct m0_pools_common *pc, const struct m0_fid *id)
static uint32_t hsm_prio(uint32_t generation, uint8_t tier_idx)
M0_INTERNAL bool m0_uint128_eq(const struct m0_uint128 *u0, const struct m0_uint128 *u1)
static int read_extent_keys(struct m0_uint128 subobjid, struct m0_bufvec *keys, struct m0_bufvec *vals, int *rc_list, struct m0_tl *ext_list, struct m0_composite_layer_idx_key *last_key)
static int obj_layout_set(struct m0_obj *obj, struct m0_client_layout *layout)
static int layer_load_extent_list(struct m0_uint128 subobjid, bool write, struct m0_tl *ext_list)
struct m0hsm_options options
static void reset_bufvec(struct m0_bufvec *keys, int count)
int m0hsm_multi_release(struct m0_uint128 id, uint8_t max_tier, off_t offset, size_t length, enum hsm_rls_flags flags)
static uint32_t hsm_prio2gen(uint32_t priority)
static int check_vec(struct m0_bufvec *vec, int blocks)
static int do_io_op(struct m0_obj *obj, enum m0_obj_opcode opcode, struct io_ctx *ctx)
static int write_blocks(struct m0_obj *obj, struct io_ctx *ctx)
enum hsm_log_level trace_level
static struct m0_realm uber_realm
int32_t m0_rc(const struct m0_op *op)
static uint8_t hsm_prio2tier(uint32_t priority)
enum m0_md_lustre_logrec_type __attribute__
uint64_t m0_client_layout_id(const struct m0_client *instance)
M0_INTERNAL void m0_indexvec_free(struct m0_indexvec *ivec)
static int layout_layer_clean(struct m0_uint128 parent_id, struct m0_client_layout *layout, struct m0_uint128 subobj_id)
void m0_idx_fini(struct m0_idx *idx)
static int map_io_ctx(struct io_ctx *ctx, int blocks, size_t b_size, off_t offset, char *buff)
M0_INTERNAL bool m0_fid_is_set(const struct m0_fid *fid)
static int layer_extent_add(struct m0_uint128 subobjid, const struct extent *ext, bool write, bool overwrite)
void m0_composite_layer_idx_val_from_buf(struct m0_composite_layer_idx_val *val, void *vbuf)
static int hsm_pools_fids_set(struct param p[], int n)
static struct m0_fid hsm_pools[MAX_POOLS]
static int delete_obj_set_parent_layout(struct m0_uint128 id, struct m0_uint128 parent_id, struct m0_client_layout *parent_layout)
M0_INTERNAL int m0_bufvec_alloc(struct m0_bufvec *bufvec, uint32_t num_segs, m0_bcount_t seg_size)
static struct m0_composite_layer * layer_get_by_prio(struct m0_client_layout *layout, int prio)
int32_t m0_op_wait(struct m0_op *op, uint64_t bits, m0_time_t to)
int m0_idx_op(struct m0_idx *idx, enum m0_idx_opcode opcode, struct m0_bufvec *keys, struct m0_bufvec *vals, int32_t *rcs, uint32_t flags, struct m0_op **op)
static void free_io_ctx(struct io_ctx *ctx, bool alloc_io_buff)
static const struct m0_uint128 * tgt_id(const struct m0_dtm_history *history)
int m0hsm_dump(FILE *stream, struct m0_uint128 id, bool details)
int m0_obj_op(struct m0_obj *obj, enum m0_obj_opcode opcode, struct m0_indexvec *ext, struct m0_bufvec *data, struct m0_bufvec *attr, uint64_t mask, uint32_t flags, struct m0_op **op)
static struct m0_realm * m0_uber_realm
M0_INTERNAL void m0_bufvec_free(struct m0_bufvec *bufvec)
struct m0_entity in_entity
static struct param hsm_rc_params[128]
static const struct extent EXT_FULLRANGE
int m0_obj_layout_id_to_unit_size(uint64_t layout_id)
static int layer_clean(struct m0_uint128 parent_id, struct m0_client_layout *layout, struct m0_composite_layer *layer)
return M0_ERR(-EOPNOTSUPP)
struct m0_client_layout * m0_client_layout_alloc(enum m0_client_layout_type type)
#define M0_AMB(obj, ptr, field)
#define m0_tl_teardown(name, head, obj)
void m0_composite_layer_idx_key_from_buf(struct m0_composite_layer_idx_key *key, void *kbuf)
static int obj_layout_get(struct m0_obj *obj, struct m0_client_layout **layout)
void m0_client_layout_free(struct m0_client_layout *layout)
static int layout_add_top_layer(struct m0_uint128 id, struct m0_client_layout *layout, uint8_t tier)
int m0_composite_layer_idx(struct m0_uint128 layer_id, bool write, struct m0_idx *idx)
static int hsm_pool_fid_set(struct param *p)
int m0_composite_layer_idx_key_to_buf(struct m0_composite_layer_idx_key *key, void **out_kbuf, m0_bcount_t *out_klen)
static int read_blocks(struct m0_obj *obj, struct io_ctx *ctx)
struct m0_client_layout ccl_layout
static struct m0_uint128 hsm_subobj_id(struct m0_uint128 id, uint32_t gen, uint8_t tier)
void m0_op_launch(struct m0_op **op, uint32_t nr)
int m0hsm_test_write(struct m0_uint128 id, off_t offset, size_t len, int seed)
int m0hsm_pwrite(struct m0_obj *obj, void *buffer, size_t length, off_t offset)
static int ext_subtract(struct m0_uint128 layer_id, struct m0_tl *ext_list, const struct extent *ext_in, bool is_write, bool *layer_empty)
void m0_composite_layer_del(struct m0_client_layout *layout, struct m0_uint128 subobj_id)
int m0hsm_copy(struct m0_uint128 id, uint8_t src_tier, uint8_t tgt_tier, off_t offset, size_t len, enum hsm_cp_flags flags)
static int struct dentry int mode
const struct extent * orig_extent
static m0_bindex_t offset
static int archive_cb(void *cb_arg, struct m0_client_layout *layout, struct m0_composite_layer *src_layer, const struct extent *match, bool *stop)
static void print_layer(FILE *stream, struct m0_composite_layer *layer, bool details)
static void print_extents(FILE *stream, const struct m0_tl *ext_list, bool details)
static int get_next_extents(struct m0_idx *idx, struct m0_bufvec *keys, struct m0_bufvec *vals, int *rc_list, int32_t flags)
M0_INTERNAL int m0_fid_sscanf(const char *s, struct m0_fid *fid)
static void dump_data(struct m0_bufvec *data, size_t bsize)
static struct m0_fid * hsm_tier2pool(uint8_t tier_idx)
static int m0hsm_release_maxgen(struct m0_uint128 id, uint8_t tier, int max_gen, off_t offset, size_t len, enum hsm_rls_flags flags, bool user_display)
static uint64_t roundup_power2(uint64_t x)
static struct m0_client * m0_instance
static struct m0_pool pool
static int copy_cb(void *cb_arg, struct m0_client_layout *layout, struct m0_composite_layer *src_layer, const struct extent *match, bool *stop)
struct m0_uint128 cek_layer_id
int m0_entity_create(struct m0_fid *pool, struct m0_entity *entity, struct m0_op **op)
static int open_entity(struct m0_entity *entity)
static int check_top_layer_writable(struct m0_client_layout *layout, int max_prio, int tier)
static int copy_extent_data(struct m0_uint128 src_id, struct m0_uint128 tgt_id, const struct extent *range)
struct m0_uint128 ccr_subobj
static int add_merge_read_extent(struct m0_composite_layer *layer, const struct extent *ext_in)
static int min_gen_check_cb(void *cb_arg, struct m0_client_layout *layout, struct m0_composite_layer *layer, const struct extent *match, bool *stop)
static int layout_get(struct m0_uint128 id, struct m0_client_layout **layout)
#define M0_ALLOC_PTR(ptr)
int m0hsm_init(struct m0_client *instance, struct m0_realm *uber_realm, const struct m0hsm_options *in_options)
int(* match_layer_cb_t)(void *cb_arg, struct m0_client_layout *layout, struct m0_composite_layer *layer, const struct extent *match, bool *stop)
int m0_composite_layer_add(struct m0_client_layout *layout, struct m0_obj *sub_obj, int priority)
m0_time_t m0_time_from_now(uint64_t secs, long ns)
static void extent_list_free(struct m0_tl *ext_list)
int m0hsm_create(struct m0_uint128 id, struct m0_obj *obj, uint8_t tier_idx, bool keep_open)
struct m0_entity ob_entity
static int layer_check_clean(struct m0_uint128 parent_id, struct m0_client_layout *layout, struct m0_composite_layer *layer)
static int start(struct m0_fom *fom)
int m0_client_layout_op(struct m0_obj *obj, enum m0_entity_opcode opcode, struct m0_client_layout *layout, struct m0_op **op)
static int create_obj_with_layout(struct m0_uint128 id, struct m0_obj *obj, struct m0_client_layout *layout, bool close_entity)
static int stage_cb(void *cb_arg, struct m0_client_layout *layout, struct m0_composite_layer *src_layer, const struct extent *match, bool *stop)
int m0hsm_release(struct m0_uint128 id, uint8_t tier, off_t offset, size_t len, enum hsm_rls_flags flags)
M0_TL_DEFINE(clayer, static, struct m0_composite_layer)
static void print_layout(FILE *stream, const struct m0_client_layout *layout, bool details)
void m0_obj_init(struct m0_obj *obj, struct m0_realm *parent, const struct m0_uint128 *id, uint64_t layout_id)
static struct m0 instance
static const struct m0_uint128 * src_id(const struct m0_dtm_history *history)
#define HSM_EXTENT_SCAN_BATCH
int m0hsm_set_write_tier(struct m0_uint128 id, uint8_t tier_idx)
int fini(struct workload *w)
static int read_params(FILE *in, struct param *p, int max_params)
static bool is_hsm_reserved(struct m0_uint128 id)
int m0_entity_delete(struct m0_entity *entity, struct m0_op **op)
static int release_cb(void *cb_arg, struct m0_client_layout *layout, struct m0_composite_layer *layer, const struct extent *match, bool *stop)
static int create_obj(struct m0_uint128 id, struct m0_obj *obj, bool close_entity, uint8_t tier_idx)
void m0_op_free(struct m0_op *op)
int m0hsm_test_read(struct m0_uint128 id, off_t offset, size_t len)
int m0_entity_open(struct m0_entity *entity, struct m0_op **op)
static int delete_obj(struct m0_uint128 id) __attribute__((unused))
M0_TL_DESCR_DEFINE(clayer, "composite layout layers", static, struct m0_composite_layer, ccr_tlink, ccr_tlink_magic, M0_CLAYER_TL_MAGIC, M0_CLAYER_TL_MAGIC)
#define m0_tl_for(name, head, obj)
static struct m0_addb2_source * s
M0_INTERNAL void m0_bufvec_free2(struct m0_bufvec *bufvec)
int m0_composite_layer_idx_val_to_buf(struct m0_composite_layer_idx_val *val, void **out_vbuf, m0_bcount_t *out_vlen)
static void gen_data(struct m0_bufvec *data, size_t bsize, int seed)
static int layer_extent_del(struct m0_uint128 subobjid, off_t off, bool write)
int const char void * buffer
static int layout_set(struct m0_uint128 id, struct m0_client_layout *layout)
M0_INTERNAL int m0_bufvec_empty_alloc(struct m0_bufvec *bufvec, uint32_t num_segs)
struct m0_uint128 except_subobj
static struct m0_composite_layer * top_layer_get(struct m0_client_layout *layout)