Thread (19 messages) 19 messages, 2 authors, 2025-03-19

Re: [PATCH v3 2/2] reftable: adapt writer code to propagate block_writer_add() errors

From: Patrick Steinhardt <hidden>
Date: 2025-03-19 13:18:19
Subsystem: the rest · Maintainer: Linus Torvalds

On Thu, Mar 13, 2025 at 08:59:51PM +0530, Meet Soni wrote:
On Wed, 12 Mar 2025 at 18:19, Patrick Steinhardt [off-list ref] wrote:
quoted
quoted
+     /*
+      * The current block is full, so we need to flush and reinitialize the
+      * writer to start writing the next block.
+      */
      arg->err = writer_flush_block(arg->w);
      if (arg->err < 0)
              goto done;
But there is another case further down where we do `block_writer_add()`
and then re-try in case the write fails. This one is a bit more curious:
if the write fails, we don't create a new block -- after all we have
just created one. Instead, we reset the record's offset length to zero
before retrying.

I _think_ that this is done because we know that when resetting the
offset we would write less data to the block, as can be seen in
`reftable_obj_record_encode()`. But I'm honestly not quite sure here as
I haven't yet done a deep dive into object records -- after all, we
don't even really use them in Git.

In any case, I think that this callsite also needs adjustment and
warrants a comment. And if so, all changes to `write_object_record()`
should probably go into a separate commit, as well.
Sorry for taking so long to respond.
Regarding the callsite in write_object_record() where we reset the
record's offset length to zero before retrying: my changes currently
follow the same principle.

    - If block_writer_add() returns an error other than
      REFTABLE_ENTRY_TOO_BIG_ERROR, we simply return.

    - For REFTABLE_ENTRY_TOO_BIG_ERROR, we flush the block and retry.

    - If that fails, we reset the record's offset length to zero and
      then retry.
It's this last step that also needs to be adapted to check for
REFTABLE_ENTRY_TOO_BIG_ERROR, because the intent here is the exact same:
if writing the object record failed even in a completely new block then
we reset the object's offset and try a third time. But same as for the
first time, we don't check whether we get REFTABLE_ENTRY_TOO_BIG_ERROR
here and thus we might be failing and retrying even in unintended cases.
I'm not sure what adjustments or additional comments you are referring to.
Could you please clarify what changes you expect at this callsite?
So overall we'd add the check to both callsites, like in the below
patch.

Patrick
diff --git a/reftable/writer.c b/reftable/writer.c
index f3ab1035d61..63629e00a37 100644
--- a/reftable/writer.c
+++ b/reftable/writer.c
@@ -628,6 +628,8 @@ static void write_object_record(void *void_arg, void *key)
 	arg->err = block_writer_add(arg->w->block_writer, &rec);
 	if (arg->err == 0)
 		goto done;
+	if (arg->err != REFTABLE_ENTRY_TOO_BIG_ERROR)
+		goto done;
 
 	arg->err = writer_flush_block(arg->w);
 	if (arg->err < 0)
@@ -640,6 +642,8 @@ static void write_object_record(void *void_arg, void *key)
 	arg->err = block_writer_add(arg->w->block_writer, &rec);
 	if (arg->err == 0)
 		goto done;
+	if (arg->err != REFTABLE_ENTRY_TOO_BIG_ERROR)
+		goto done;
 
 	rec.u.obj.offset_len = 0;
 	arg->err = block_writer_add(arg->w->block_writer, &rec);
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help