From 66953686c05901277115e837bbaab4df4ffd63c6 Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Thu, 2 Feb 2023 17:30:39 -0500 Subject: [PATCH] Add assertion and make variables unsigned in abd_alloc_chunks() Clang's static analyzer pointed out that if alloc_pages >= nr_pages before the loop, the value of page will be undefined and will be used anyway. This should not be possible, but as cleanup, we add an assertion. We also recognize that the local variables should be unsigned in the first place, so we make them unsigned. This is not enough to avoid the need for the assertion, since there is still the case that alloc_pages == nr_pages and nr_pages == 0, which the assertion implicitly checks. Reviewed-by: Brian Behlendorf Reviewed-by: Brian Atkinson Signed-off-by: Richard Yao Closes #14456 --- module/os/linux/zfs/abd_os.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/module/os/linux/zfs/abd_os.c b/module/os/linux/zfs/abd_os.c index 16530d826..13150adbe 100644 --- a/module/os/linux/zfs/abd_os.c +++ b/module/os/linux/zfs/abd_os.c @@ -272,18 +272,20 @@ abd_alloc_chunks(abd_t *abd, size_t size) struct page *page, *tmp_page = NULL; gfp_t gfp = __GFP_NOWARN | GFP_NOIO; gfp_t gfp_comp = (gfp | __GFP_NORETRY | __GFP_COMP) & ~__GFP_RECLAIM; - int max_order = MIN(zfs_abd_scatter_max_order, MAX_ORDER - 1); - int nr_pages = abd_chunkcnt_for_bytes(size); - int chunks = 0, zones = 0; + unsigned int max_order = MIN(zfs_abd_scatter_max_order, MAX_ORDER - 1); + unsigned int nr_pages = abd_chunkcnt_for_bytes(size); + unsigned int chunks = 0, zones = 0; size_t remaining_size; int nid = NUMA_NO_NODE; - int alloc_pages = 0; + unsigned int alloc_pages = 0; INIT_LIST_HEAD(&pages); + ASSERT3U(alloc_pages, <, nr_pages); + while (alloc_pages < nr_pages) { - unsigned chunk_pages; - int order; + unsigned int chunk_pages; + unsigned int order; order = MIN(highbit64(nr_pages - alloc_pages) - 1, max_order); chunk_pages = (1U << order);