reftable/record: adapt `reftable_record_key()` to handle allocation failures

The `reftable_record_key()` function cannot pass any errors to the
caller as it has a `void` return type. Adapt it and its callers such
that we can handle errors and start handling allocation failures.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
maint
Patrick Steinhardt 2024-10-17 06:54:08 +02:00 committed by Taylor Blau
parent e693ccf2c9
commit 4abc8022ff
5 changed files with 47 additions and 22 deletions

View File

@ -111,9 +111,12 @@ int block_writer_add(struct block_writer *w, struct reftable_record *rec)
int is_restart = 0; int is_restart = 0;
struct reftable_buf key = REFTABLE_BUF_INIT; struct reftable_buf key = REFTABLE_BUF_INIT;
int n = 0; int n = 0;
int err = -1; int err;

err = reftable_record_key(rec, &key);
if (err < 0)
goto done;


reftable_record_key(rec, &key);
if (!key.len) { if (!key.len) {
err = REFTABLE_API_ERROR; err = REFTABLE_API_ERROR;
goto done; goto done;
@ -121,13 +124,17 @@ int block_writer_add(struct block_writer *w, struct reftable_record *rec)


n = reftable_encode_key(&is_restart, out, last, key, n = reftable_encode_key(&is_restart, out, last, key,
reftable_record_val_type(rec)); reftable_record_val_type(rec));
if (n < 0) if (n < 0) {
err = -1;
goto done; goto done;
}
string_view_consume(&out, n); string_view_consume(&out, n);


n = reftable_record_encode(rec, out, w->hash_size); n = reftable_record_encode(rec, out, w->hash_size);
if (n < 0) if (n < 0) {
err = -1;
goto done; goto done;
}
string_view_consume(&out, n); string_view_consume(&out, n);


err = block_writer_register_restart(w, start.len - out.len, is_restart, err = block_writer_register_restart(w, start.len - out.len, is_restart,
@ -522,6 +529,10 @@ int block_iter_seek_key(struct block_iter *it, const struct block_reader *br,
goto done; goto done;
} }


err = reftable_record_key(&rec, &it->last_key);
if (err < 0)
goto done;

/* /*
* Check whether the current key is greater or equal to the * Check whether the current key is greater or equal to the
* sought-after key. In case it is greater we know that the * sought-after key. In case it is greater we know that the
@ -536,7 +547,6 @@ int block_iter_seek_key(struct block_iter *it, const struct block_reader *br,
* to `last_key` now, and naturally all keys share a prefix * to `last_key` now, and naturally all keys share a prefix
* with themselves. * with themselves.
*/ */
reftable_record_key(&rec, &it->last_key);
if (reftable_buf_cmp(&it->last_key, want) >= 0) { if (reftable_buf_cmp(&it->last_key, want) >= 0) {
it->next_off = prev_off; it->next_off = prev_off;
goto done; goto done;

View File

@ -356,7 +356,9 @@ static int table_iter_seek_linear(struct table_iter *ti,
int err; int err;


reftable_record_init(&rec, reftable_record_type(want)); reftable_record_init(&rec, reftable_record_type(want));
reftable_record_key(want, &want_key); err = reftable_record_key(want, &want_key);
if (err < 0)
goto done;


/* /*
* First we need to locate the block that must contain our record. To * First we need to locate the block that must contain our record. To
@ -439,7 +441,9 @@ static int table_iter_seek_indexed(struct table_iter *ti,
}; };
int err; int err;


reftable_record_key(rec, &want_index.u.idx.last_key); err = reftable_record_key(rec, &want_index.u.idx.last_key);
if (err < 0)
goto done;


/* /*
* The index may consist of multiple levels, where each level may have * The index may consist of multiple levels, where each level may have

View File

@ -207,12 +207,12 @@ int reftable_decode_key(struct reftable_buf *last_key, uint8_t *extra,
return start_len - in.len; return start_len - in.len;
} }


static void reftable_ref_record_key(const void *r, struct reftable_buf *dest) static int reftable_ref_record_key(const void *r, struct reftable_buf *dest)
{ {
const struct reftable_ref_record *rec = const struct reftable_ref_record *rec =
(const struct reftable_ref_record *)r; (const struct reftable_ref_record *)r;
reftable_buf_reset(dest); reftable_buf_reset(dest);
reftable_buf_addstr(dest, rec->refname); return reftable_buf_addstr(dest, rec->refname);
} }


static int reftable_ref_record_copy_from(void *rec, const void *src_rec, static int reftable_ref_record_copy_from(void *rec, const void *src_rec,
@ -465,12 +465,12 @@ static struct reftable_record_vtable reftable_ref_record_vtable = {
.cmp = &reftable_ref_record_cmp_void, .cmp = &reftable_ref_record_cmp_void,
}; };


static void reftable_obj_record_key(const void *r, struct reftable_buf *dest) static int reftable_obj_record_key(const void *r, struct reftable_buf *dest)
{ {
const struct reftable_obj_record *rec = const struct reftable_obj_record *rec =
(const struct reftable_obj_record *)r; (const struct reftable_obj_record *)r;
reftable_buf_reset(dest); reftable_buf_reset(dest);
reftable_buf_add(dest, rec->hash_prefix, rec->hash_prefix_len); return reftable_buf_add(dest, rec->hash_prefix, rec->hash_prefix_len);
} }


static void reftable_obj_record_release(void *rec) static void reftable_obj_record_release(void *rec)
@ -664,19 +664,27 @@ static struct reftable_record_vtable reftable_obj_record_vtable = {
.cmp = &reftable_obj_record_cmp_void, .cmp = &reftable_obj_record_cmp_void,
}; };


static void reftable_log_record_key(const void *r, struct reftable_buf *dest) static int reftable_log_record_key(const void *r, struct reftable_buf *dest)
{ {
const struct reftable_log_record *rec = const struct reftable_log_record *rec =
(const struct reftable_log_record *)r; (const struct reftable_log_record *)r;
int len = strlen(rec->refname); int len = strlen(rec->refname), err;
uint8_t i64[8]; uint8_t i64[8];
uint64_t ts = 0; uint64_t ts = 0;

reftable_buf_reset(dest); reftable_buf_reset(dest);
reftable_buf_add(dest, (uint8_t *)rec->refname, len + 1); err = reftable_buf_add(dest, (uint8_t *)rec->refname, len + 1);
if (err < 0)
return err;


ts = (~ts) - rec->update_index; ts = (~ts) - rec->update_index;
put_be64(&i64[0], ts); put_be64(&i64[0], ts);
reftable_buf_add(dest, i64, sizeof(i64));
err = reftable_buf_add(dest, i64, sizeof(i64));
if (err < 0)
return err;

return 0;
} }


static int reftable_log_record_copy_from(void *rec, const void *src_rec, static int reftable_log_record_copy_from(void *rec, const void *src_rec,
@ -1027,11 +1035,11 @@ static struct reftable_record_vtable reftable_log_record_vtable = {
.cmp = &reftable_log_record_cmp_void, .cmp = &reftable_log_record_cmp_void,
}; };


static void reftable_index_record_key(const void *r, struct reftable_buf *dest) static int reftable_index_record_key(const void *r, struct reftable_buf *dest)
{ {
const struct reftable_index_record *rec = r; const struct reftable_index_record *rec = r;
reftable_buf_reset(dest); reftable_buf_reset(dest);
reftable_buf_add(dest, rec->last_key.buf, rec->last_key.len); return reftable_buf_add(dest, rec->last_key.buf, rec->last_key.len);
} }


static int reftable_index_record_copy_from(void *rec, const void *src_rec, static int reftable_index_record_copy_from(void *rec, const void *src_rec,
@ -1124,9 +1132,9 @@ static struct reftable_record_vtable reftable_index_record_vtable = {
.cmp = &reftable_index_record_cmp, .cmp = &reftable_index_record_cmp,
}; };


void reftable_record_key(struct reftable_record *rec, struct reftable_buf *dest) int reftable_record_key(struct reftable_record *rec, struct reftable_buf *dest)
{ {
reftable_record_vtable(rec)->key(reftable_record_data(rec), dest); return reftable_record_vtable(rec)->key(reftable_record_data(rec), dest);
} }


int reftable_record_encode(struct reftable_record *rec, struct string_view dest, int reftable_record_encode(struct reftable_record *rec, struct string_view dest,

View File

@ -40,7 +40,7 @@ int put_var_int(struct string_view *dest, uint64_t val);
/* Methods for records. */ /* Methods for records. */
struct reftable_record_vtable { struct reftable_record_vtable {
/* encode the key of to a uint8_t reftable_buf. */ /* encode the key of to a uint8_t reftable_buf. */
void (*key)(const void *rec, struct reftable_buf *dest); int (*key)(const void *rec, struct reftable_buf *dest);


/* The record type of ('r' for ref). */ /* The record type of ('r' for ref). */
uint8_t type; uint8_t type;
@ -137,7 +137,7 @@ void reftable_record_init(struct reftable_record *rec, uint8_t typ);
/* see struct record_vtable */ /* see struct record_vtable */
int reftable_record_cmp(struct reftable_record *a, struct reftable_record *b); int reftable_record_cmp(struct reftable_record *a, struct reftable_record *b);
int reftable_record_equal(struct reftable_record *a, struct reftable_record *b, int hash_size); int reftable_record_equal(struct reftable_record *a, struct reftable_record *b, int hash_size);
void reftable_record_key(struct reftable_record *rec, struct reftable_buf *dest); int reftable_record_key(struct reftable_record *rec, struct reftable_buf *dest);
int reftable_record_copy_from(struct reftable_record *rec, int reftable_record_copy_from(struct reftable_record *rec,
struct reftable_record *src, int hash_size); struct reftable_record *src, int hash_size);
uint8_t reftable_record_val_type(struct reftable_record *rec); uint8_t reftable_record_val_type(struct reftable_record *rec);

View File

@ -249,7 +249,10 @@ static int writer_add_record(struct reftable_writer *w,
struct reftable_buf key = REFTABLE_BUF_INIT; struct reftable_buf key = REFTABLE_BUF_INIT;
int err; int err;


reftable_record_key(rec, &key); err = reftable_record_key(rec, &key);
if (err < 0)
goto done;

if (reftable_buf_cmp(&w->last_key, &key) >= 0) { if (reftable_buf_cmp(&w->last_key, &key) >= 0) {
err = REFTABLE_API_ERROR; err = REFTABLE_API_ERROR;
goto done; goto done;