summaryrefslogtreecommitdiff
path: root/lib/buildid.c
diff options
context:
space:
mode:
authorMykyta Yatsenko <yatsenko@meta.com>2025-10-26 20:38:47 +0000
committerAlexei Starovoitov <ast@kernel.org>2025-10-27 09:56:27 -0700
commit5a5fff604fa30a581197dca4204c35539fbedddb (patch)
tree4775d0d03cc26e0a1e62f58f46172cab4d958af0 /lib/buildid.c
parent76e4fed847124690f7344a43d01dbcd7b2925353 (diff)
lib/freader: support reading more than 2 folios
freader_fetch currently reads from at most two folios. When a read spans into a third folio, the overflow bytes are copied adjacent to the second folio’s data instead of being handled as a separate folio. This patch modifies fetch algorithm to support reading from many folios. Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com> Reviewed-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/r/20251026203853.135105-5-mykyta.yatsenko5@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'lib/buildid.c')
-rw-r--r--lib/buildid.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/lib/buildid.c b/lib/buildid.c
index df06e492810d..aaf61dfc0919 100644
--- a/lib/buildid.c
+++ b/lib/buildid.c
@@ -108,18 +108,21 @@ const void *freader_fetch(struct freader *r, loff_t file_off, size_t sz)
*/
folio_sz = folio_size(r->folio);
if (file_off + sz > r->folio_off + folio_sz) {
- int part_sz = r->folio_off + folio_sz - file_off;
-
- /* copy the part that resides in the current folio */
- memcpy(r->buf, r->addr + (file_off - r->folio_off), part_sz);
-
- /* fetch next folio */
- r->err = freader_get_folio(r, r->folio_off + folio_sz);
- if (r->err)
- return NULL;
-
- /* copy the rest of requested data */
- memcpy(r->buf + part_sz, r->addr, sz - part_sz);
+ u64 part_sz = r->folio_off + folio_sz - file_off, off;
+
+ memcpy(r->buf, r->addr + file_off - r->folio_off, part_sz);
+ off = part_sz;
+
+ while (off < sz) {
+ /* fetch next folio */
+ r->err = freader_get_folio(r, r->folio_off + folio_sz);
+ if (r->err)
+ return NULL;
+ folio_sz = folio_size(r->folio);
+ part_sz = min_t(u64, sz - off, folio_sz);
+ memcpy(r->buf + off, r->addr, part_sz);
+ off += part_sz;
+ }
return r->buf;
}