reftable: propagate specific error codes in block_writer_add()

Previously, functions block_writer_add() and related functions returned -1 when the record did not fit, forcing the caller to assume that any failure meant the entry was too big. Replace these generic -1 returns with defined error codes. This prepares the codebase for finer-grained error handling so that callers can distinguish between a block-full condition and other errors. Signed-off-by: Meet Soni <meetsoni3017@gmail.com> Acked-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Meet Soni committed Mar 19, 2025 at 20:59 UTC 27571684ddca217d65c5f39947f20b9f5ec91863
3 files changed +32 -36
reftable/block.c
+7 -6
@@ -49,7 +49,7 @@ static int block_writer_register_restart(struct block_writer *w, int n,
49 if (is_restart)
50 rlen++;
51 if (2 + 3 * rlen + n > w->block_size - w->next)
52 - return -1;
52 + return REFTABLE_ENTRY_TOO_BIG_ERROR;
53 if (is_restart) {
54 REFTABLE_ALLOC_GROW_OR_NULL(w->restarts, w->restart_len + 1,
55 w->restart_cap);
@@ -97,9 +97,10 @@ uint8_t block_writer_type(struct block_writer *bw)
97 return bw->block[bw->header_off];
98 }
99
100 -/* Adds the reftable_record to the block. Returns -1 if it does not fit, 0 on
101 - success. Returns REFTABLE_API_ERROR if attempting to write a record with
102 - empty key. */
100 +/*
101 + * Adds the reftable_record to the block. Returns 0 on success and
102 + * appropriate error codes on failure.
103 + */
104 int block_writer_add(struct block_writer *w, struct reftable_record *rec)
105 {
106 struct reftable_buf empty = REFTABLE_BUF_INIT;
@@ -126,14 +127,14 @@ int block_writer_add(struct block_writer *w, struct reftable_record *rec)
127 n = reftable_encode_key(&is_restart, out, last, w->scratch,
128 reftable_record_val_type(rec));
129 if (n < 0) {
129 - err = -1;
130 + err = n;
131 goto done;
132 }
133 string_view_consume(&out, n);
134
135 n = reftable_record_encode(rec, out, w->hash_size);
136 if (n < 0) {
136 - err = -1;
137 + err = n;
138 goto done;
139 }
140 string_view_consume(&out, n);
reftable/block.h
+1 -1
@@ -53,7 +53,7 @@ int block_writer_init(struct block_writer *bw, uint8_t typ, uint8_t *block,
53 /* returns the block type (eg. 'r' for ref records. */
54 uint8_t block_writer_type(struct block_writer *bw);
55
56 -/* appends the record, or -1 if it doesn't fit. */
56 +/* Attempts to append the record. Returns 0 on success or error code on failure. */
57 int block_writer_add(struct block_writer *w, struct reftable_record *rec);
58
59 /* appends the key restarts, and compress the block if necessary. */
reftable/record.c
+24 -29
@@ -61,7 +61,7 @@ int put_var_int(struct string_view *dest, uint64_t value)
61 while (value >>= 7)
62 varint[--pos] = 0x80 | (--value & 0x7f);
63 if (dest->len < sizeof(varint) - pos)
64 - return -1;
64 + return REFTABLE_ENTRY_TOO_BIG_ERROR;
65 memcpy(dest->buf, varint + pos, sizeof(varint) - pos);
66 return sizeof(varint) - pos;
67 }
@@ -129,10 +129,10 @@ static int encode_string(const char *str, struct string_view s)
129 size_t l = strlen(str);
130 int n = put_var_int(&s, l);
131 if (n < 0)
132 - return -1;
132 + return n;
133 string_view_consume(&s, n);
134 if (s.len < l)
135 - return -1;
135 + return REFTABLE_ENTRY_TOO_BIG_ERROR;
136 memcpy(s.buf, str, l);
137 string_view_consume(&s, l);
138
@@ -148,18 +148,18 @@ int reftable_encode_key(int *restart, struct string_view dest,
148 uint64_t suffix_len = key.len - prefix_len;
149 int n = put_var_int(&dest, prefix_len);
150 if (n < 0)
151 - return -1;
151 + return n;
152 string_view_consume(&dest, n);
153
154 *restart = (prefix_len == 0);
155
156 n = put_var_int(&dest, suffix_len << 3 | (uint64_t)extra);
157 if (n < 0)
158 - return -1;
158 + return n;
159 string_view_consume(&dest, n);
160
161 if (dest.len < suffix_len)
162 - return -1;
162 + return REFTABLE_ENTRY_TOO_BIG_ERROR;
163 memcpy(dest.buf, key.buf + prefix_len, suffix_len);
164 string_view_consume(&dest, suffix_len);
165
@@ -324,30 +324,27 @@ static int reftable_ref_record_encode(const void *rec, struct string_view s,
324 struct string_view start = s;
325 int n = put_var_int(&s, r->update_index);
326 if (n < 0)
327 - return -1;
327 + return n;
328 string_view_consume(&s, n);
329
330 switch (r->value_type) {
331 case REFTABLE_REF_SYMREF:
332 n = encode_string(r->value.symref, s);
333 - if (n < 0) {
334 - return -1;
335 - }
333 + if (n < 0)
334 + return n;
335 string_view_consume(&s, n);
336 break;
337 case REFTABLE_REF_VAL2:
339 - if (s.len < 2 * hash_size) {
340 - return -1;
341 - }
338 + if (s.len < 2 * hash_size)
339 + return REFTABLE_ENTRY_TOO_BIG_ERROR;
340 memcpy(s.buf, r->value.val2.value, hash_size);
341 string_view_consume(&s, hash_size);
342 memcpy(s.buf, r->value.val2.target_value, hash_size);
343 string_view_consume(&s, hash_size);
344 break;
345 case REFTABLE_REF_VAL1:
348 - if (s.len < hash_size) {
349 - return -1;
350 - }
346 + if (s.len < hash_size)
347 + return REFTABLE_ENTRY_TOO_BIG_ERROR;
348 memcpy(s.buf, r->value.val1, hash_size);
349 string_view_consume(&s, hash_size);
350 break;
@@ -531,24 +528,22 @@ static int reftable_obj_record_encode(const void *rec, struct string_view s,
528 uint64_t last = 0;
529 if (r->offset_len == 0 || r->offset_len >= 8) {
530 n = put_var_int(&s, r->offset_len);
534 - if (n < 0) {
535 - return -1;
536 - }
531 + if (n < 0)
532 + return n;
533 string_view_consume(&s, n);
534 }
535 if (r->offset_len == 0)
536 return start.len - s.len;
537 n = put_var_int(&s, r->offsets[0]);
538 if (n < 0)
543 - return -1;
539 + return n;
540 string_view_consume(&s, n);
541
542 last = r->offsets[0];
543 for (i = 1; i < r->offset_len; i++) {
544 int n = put_var_int(&s, r->offsets[i] - last);
549 - if (n < 0) {
550 - return -1;
551 - }
545 + if (n < 0)
546 + return n;
547 string_view_consume(&s, n);
548 last = r->offsets[i];
549 }
@@ -783,7 +778,7 @@ static int reftable_log_record_encode(const void *rec, struct string_view s,
778 return 0;
779
780 if (s.len < 2 * hash_size)
786 - return -1;
781 + return REFTABLE_ENTRY_TOO_BIG_ERROR;
782
783 memcpy(s.buf, r->value.update.old_hash, hash_size);
784 memcpy(s.buf + hash_size, r->value.update.new_hash, hash_size);
@@ -791,22 +786,22 @@ static int reftable_log_record_encode(const void *rec, struct string_view s,
786
787 n = encode_string(r->value.update.name ? r->value.update.name : "", s);
788 if (n < 0)
794 - return -1;
789 + return n;
790 string_view_consume(&s, n);
791
792 n = encode_string(r->value.update.email ? r->value.update.email : "",
793 s);
794 if (n < 0)
800 - return -1;
795 + return n;
796 string_view_consume(&s, n);
797
798 n = put_var_int(&s, r->value.update.time);
799 if (n < 0)
805 - return -1;
800 + return n;
801 string_view_consume(&s, n);
802
803 if (s.len < 2)
809 - return -1;
804 + return REFTABLE_ENTRY_TOO_BIG_ERROR;
805
806 put_be16(s.buf, r->value.update.tz_offset);
807 string_view_consume(&s, 2);
@@ -814,7 +809,7 @@ static int reftable_log_record_encode(const void *rec, struct string_view s,
809 n = encode_string(
810 r->value.update.message ? r->value.update.message : "", s);
811 if (n < 0)
817 - return -1;
812 + return n;
813 string_view_consume(&s, n);
814
815 return start.len - s.len;