diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 395e23920..926ffeed8 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -4843,6 +4843,13 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, } block = ocfs2_clusters_to_blocks(osb->sb, bit_off); + if (block == 0) { + mlog(ML_ERROR, "Conversion resulted in zero block number"); + status = -EIO; + need_free = 1; + goto bail; + } + trace_ocfs2_add_clusters_in_btree( (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci), bit_off, num_bits); diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index 70a768b62..f83d0a3b6 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c @@ -12,6 +12,7 @@ #include #include #include +#include #include @@ -961,6 +962,8 @@ int ocfs2_read_virt_blocks(struct inode *inode, u64 v_block, int nr, int rc = 0; u64 p_block, p_count; int i, count, done = 0; + int retries, max_retries = 5; + int retry_delay_ms = 30; trace_ocfs2_read_virt_blocks( inode, (unsigned long long)v_block, nr, bhs, flags, @@ -973,7 +976,18 @@ int ocfs2_read_virt_blocks(struct inode *inode, u64 v_block, int nr, } while (done < nr) { - down_read(&OCFS2_I(inode)->ip_alloc_sem); + retries = 0; + while (retries < max_retries) { + if (down_read_trylock(&OCFS2_I(inode)->ip_alloc_sem)) + break; // Lock acquired + msleep(retry_delay_ms); + retries++; + } + if (retries == max_retries) { + rc = -EAGAIN; + mlog(ML_ERROR, "Cannot acquire lock\n"); + break; + } rc = ocfs2_extent_map_get_blocks(inode, v_block + done, &p_block, &p_count, NULL); up_read(&OCFS2_I(inode)->ip_alloc_sem);