From 14b65c6360fda12f96afbf7c35535940a9cea25f Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Mon, 4 Mar 2024 14:53:34 -0800 Subject: [PATCH] Fix printing alloc list block extents The list alloc blocks have an array of blknos that are offset by a start field in the block header. The print code wasn't using that and was always referencing the beginning of the array, which could miss blocks. Signed-off-by: Zach Brown --- utils/src/print.c | 50 +++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/utils/src/print.c b/utils/src/print.c index fb8d60d1..c17eb425 100644 --- a/utils/src/print.c +++ b/utils/src/print.c @@ -645,6 +645,8 @@ static int print_alloc_list_block(int fd, char *str, struct scoutfs_block_ref *r u64 blkno; u64 start; u64 len; + u64 st; + u64 nr; int wid; int ret; int i; @@ -663,27 +665,37 @@ static int print_alloc_list_block(int fd, char *str, struct scoutfs_block_ref *r AL_REF_A(&lblk->next), le32_to_cpu(lblk->start), le32_to_cpu(lblk->nr)); - if (lblk->nr) { - wid = printf(" exts: "); - start = 0; - len = 0; - for (i = 0; i < le32_to_cpu(lblk->nr); i++) { - if (len == 0) - start = le64_to_cpu(lblk->blknos[i]); - len++; - - if (i == (le32_to_cpu(lblk->nr) - 1) || - start + len != le64_to_cpu(lblk->blknos[i + 1])) { - if (wid >= 72) - wid = printf("\n "); - - wid += printf("%llu,%llu ", start, len); - len = 0; - } - } - printf("\n"); + st = le32_to_cpu(lblk->start); + nr = le32_to_cpu(lblk->nr); + if (st >= SCOUTFS_ALLOC_LIST_MAX_BLOCKS || + nr > SCOUTFS_ALLOC_LIST_MAX_BLOCKS || + (st + nr) > SCOUTFS_ALLOC_LIST_MAX_BLOCKS) { + printf(" (invalid start and nr fields)\n"); + goto out; } + if (lblk->nr == 0) + goto out; + + wid = printf(" exts: "); + start = 0; + len = 0; + for (i = 0; i < nr; i++) { + if (len == 0) + start = le64_to_cpu(lblk->blknos[st + i]); + len++; + + if (i == (nr - 1) || (start + len) != le64_to_cpu(lblk->blknos[st + i + 1])) { + if (wid >= 72) + wid = printf("\n "); + + wid += printf("%llu,%llu ", start, len); + len = 0; + } + } + printf("\n"); + +out: next = lblk->next; free(lblk); return print_alloc_list_block(fd, str, &next);