[PATCH 4/7] odb/source-loose: distinguish missing and corrupt objects
Patrick Steinhardt <[email protected]>
| Newsgroups | org.kernel.vger.git |
|---|---|
| Message-ID | <20260818-pks-odb-generic-corrupt-objects-v1-4-ec234567510f@pks.im> |
The loose source returns a negative value from its `read_object_info()` callback both when the object is missing and when the object exists but cannot be read. Consequently, callers cannot tell apart whether the object does not exist in this source at all or whether it is corrupt. Adapt the code to return a positive value for missing objects according to the new calling convention. This also allows us to get rid of the separate `corrupt:` label, as we can now clearly distinguish between corrupt and missing objects in the function ourselves. This makes us handle failures to read loose objects more consistently, as not all failure cases were jumping that label. Note that there's one call to `die()` when the object type is invalid that should arguably be converted to an error, too. But adapting that call results in quite a lot of broken tests, so this is left as-is for now. Signed-off-by: Patrick Steinhardt <[email protected]> --- odb/source-loose.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/odb/source-loose.c b/odb/source-loose.c index ef0e919277..e786560ad1 100644 --- a/odb/source-loose.c +++ b/odb/source-loose.c @@ -91,11 +91,16 @@ static int read_object_info_from_path(struct odb_source_loose *loose, struct stat st; if ((!oi || (!oi->disk_sizep && !oi->mtimep)) && (flags & OBJECT_INFO_QUICK)) { - ret = quick_has_loose(loose, oid) ? 0 : -1; + ret = quick_has_loose(loose, oid) ? 0 : 1; goto out; } if (lstat(path, &st) < 0) { + if (errno == ENOENT) { + ret = 1; + goto out; + } + ret = -1; goto out; } @@ -113,9 +118,12 @@ static int read_object_info_from_path(struct odb_source_loose *loose, fd = git_open(path); if (fd < 0) { - if (errno != ENOENT) - error_errno(_("unable to open loose object %s"), oid_to_hex(oid)); - ret = -1; + if (errno == ENOENT) { + ret = 1; + goto out; + } + + ret = error_errno(_("unable to open loose object %s"), oid_to_hex(oid)); goto out; } @@ -155,7 +163,7 @@ static int read_object_info_from_path(struct odb_source_loose *loose, if (parse_loose_header(hdr, oi) < 0) { ret = error(_("unable to parse %s header"), oid_to_hex(oid)); - goto corrupt; + goto out; } if (*oi->typep < 0) @@ -165,7 +173,7 @@ static int read_object_info_from_path(struct odb_source_loose *loose, *oi->contentp = unpack_loose_rest(&stream, hdr, *oi->sizep, oid); if (!*oi->contentp) { ret = -1; - goto corrupt; + goto out; } } @@ -173,21 +181,20 @@ static int read_object_info_from_path(struct odb_source_loose *loose, case ULHR_BAD: ret = error(_("unable to unpack %s header"), oid_to_hex(oid)); - goto corrupt; + goto out; case ULHR_TOO_LONG: ret = error(_("header for %s too long, exceeds %d bytes"), oid_to_hex(oid), MAX_HEADER_LEN); - goto corrupt; + goto out; } ret = 0; -corrupt: - if (ret && (flags & OBJECT_INFO_DIE_IF_CORRUPT)) +out: + if (ret < 0 && (flags & OBJECT_INFO_DIE_IF_CORRUPT)) die(_("loose object %s (stored in %s) is corrupt"), oid_to_hex(oid), path); -out: if (stream_to_end) git_inflate_end(stream_to_end); if (map) @@ -221,7 +228,7 @@ static int odb_source_loose_read_object_info(struct odb_source *source, * second time. */ if (flags & OBJECT_INFO_SECOND_READ) - return -1; + return 1; odb_loose_path(loose, &buf, oid); return read_object_info_from_path(loose, buf.buf, oid, oi, flags); @@ -421,7 +428,7 @@ static int for_each_object_wrapper_cb(const struct object_id *oid, if (data->request) { struct object_info oi = *data->request; - if (read_object_info_from_path(data->loose, path, oid, &oi, 0) < 0) + if (read_object_info_from_path(data->loose, path, oid, &oi, 0)) return -1; return data->cb(oid, &oi, data->cb_data); @@ -439,7 +446,7 @@ static int for_each_prefixed_object_wrapper_cb(const struct object_id *oid, struct object_info oi = *data->request; if (odb_source_read_object_info(&data->loose->base, - oid, &oi, 0) < 0) + oid, &oi, 0)) return -1; return data->cb(oid, &oi, data->cb_data); -- 2.55.0.822.g20453c30eb.dirty