diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 6ac4dcd54588..d383063629dc 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c @@ -649,6 +649,16 @@ ocfs2_block_group_alloc_discontig(handle_t *handle, return status ? ERR_PTR(status) : bg_bh; } +static int ocfs2_check_chain_list(struct ocfs2_chain_list *cl, + struct super_block *sb) +{ + if (le16_to_cpu(cl->cl_count) != ocfs2_chain_recs_per_inode(sb)) + return -EINVAL; + if (le16_to_cpu(cl->cl_next_free_rec) >= le16_to_cpu(cl->cl_count)) + return -EINVAL; + return 0; +} + /* * We expect the block group allocator to already be locked. */ @@ -671,6 +681,10 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, BUG_ON(ocfs2_is_cluster_bitmap(alloc_inode)); cl = &fe->id2.i_chain; + status = ocfs2_check_chain_list(cl, alloc_inode->i_sb); + if (status) + goto bail; + status = ocfs2_reserve_clusters_with_limit(osb, le16_to_cpu(cl->cl_cpg), max_block, flags, &ac); @@ -1992,6 +2006,9 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, } cl = (struct ocfs2_chain_list *) &fe->id2.i_chain; + status = ocfs2_check_chain_list(cl, ac->ac_inode->i_sb); + if (status) + goto bail; victim = ocfs2_find_victim_chain(cl); ac->ac_chain = victim;