From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> Coverity points out that xfs_btree_islastblock calls xfs_btree_check_block, but doesn't act on an error return. This predicate has no answer if the btree is corrupt, so tweak the helper to be able to return errors, and then modify the one call site. Coverity-id: 114069 Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> --- fs/xfs/libxfs/xfs_alloc.c | 6 +++++- fs/xfs/libxfs/xfs_btree.c | 17 +++++++++++------ fs/xfs/libxfs/xfs_btree.h | 5 +++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index f7a4b54c5bc2..f609e1ab14d4 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -1479,6 +1479,7 @@ xfs_alloc_ag_vextent_near( int i; /* result code, temporary */ xfs_agblock_t bno; xfs_extlen_t len; + bool is_last; #ifdef DEBUG /* * Randomly don't execute the first algorithm. @@ -1532,7 +1533,10 @@ xfs_alloc_ag_vextent_near( * This is written as a while loop so we can break out of it, * but we never loop back to the top. */ - while (xfs_btree_islastblock(acur.cnt, 0)) { + error = xfs_btree_islastblock(acur.cnt, 0, &is_last); + if (error) + goto out; + while (is_last) { #ifdef DEBUG if (dofirst) break; diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 98843f1258b8..098abfb50252 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -719,20 +719,25 @@ xfs_btree_get_bufs( /* * Check for the cursor referring to the last block at the given level. */ -int /* 1=is last block, 0=not last block */ +int xfs_btree_islastblock( xfs_btree_cur_t *cur, /* btree cursor */ - int level) /* level to check */ + int level, /* level to check */ + bool *last) { struct xfs_btree_block *block; /* generic btree block pointer */ - xfs_buf_t *bp; /* buffer containing block */ + struct xfs_buf *bp; /* buffer containing block */ + int error; block = xfs_btree_get_block(cur, level, &bp); - xfs_btree_check_block(cur, block, level, bp); + error = xfs_btree_check_block(cur, block, level, bp); + if (error) + return error; if (cur->bc_flags & XFS_BTREE_LONG_PTRS) - return block->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK); + *last = block->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK); else - return block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK); + *last = block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK); + return 0; } /* diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 6670120cd690..ff54e6c18c44 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -320,10 +320,11 @@ xfs_btree_get_bufs( /* * Check for the cursor referring to the last block at the given level. */ -int /* 1=is last block, 0=not last block */ +int xfs_btree_islastblock( xfs_btree_cur_t *cur, /* btree cursor */ - int level); /* level to check */ + int level, /* level to check */ + bool *last); /* * Compute first and last byte offsets for the fields given.