The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git after rh7-3.10.0-123.1.2.vz7.5.1 ------> commit e3b634ed036e618d74643faaa478dc3951c2f781 Author: Andrey Smetanin <asmeta...@virtuozzo.com> Date: Tue May 19 08:27:05 2015 +0400
ploop: bug on bad fiemap (v2) Based on crash analysis, one of extents from ploop em-tree is bad: ffff883fe6230ae0 start = 19380224 end = 19447808 block_start = 0 refs = { counter = 1 } ploop never calculates em->block_start other than by direct assigning: > em->block_start = fi_extent.fe_physical >> 9; The patch attempts to catch erroneous (zero) output immediately after fiemap call. Changed in v2: - WARN_ON (instead of BUG_ON) for delalloc extents https://jira.sw.ru/browse/PSBM-26762 Signed-off-by: Maxim Patlasov <mpatla...@parallels.com> --- drivers/block/ploop/io_direct_map.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/block/ploop/io_direct_map.c b/drivers/block/ploop/io_direct_map.c index b3cb04d..b9a0ce9 100644 --- a/drivers/block/ploop/io_direct_map.c +++ b/drivers/block/ploop/io_direct_map.c @@ -641,6 +641,7 @@ static struct extent_map *__map_extent_bmap(struct ploop_io *io, { struct extent_map_tree *tree = io->files.em_tree; struct inode *inode = mapping->host; + loff_t start_off = (loff_t)start << 9; struct extent_map *em; struct fiemap_extent_info fieinfo; struct fiemap_extent fi_extent; @@ -681,6 +682,25 @@ again: old_fs = get_fs(); set_fs(KERNEL_DS); ret = inode->i_op->fiemap(inode, &fieinfo, start << 9, 1); + + /* chase for PSBM-26762: em->block_start == 0 */ + if (!ret && fieinfo.fi_extents_mapped == 1 && + !(fi_extent.fe_flags & FIEMAP_EXTENT_UNWRITTEN) && + (fi_extent.fe_physical >> 9) == 0) { + /* see how ext4_fill_fiemap_extents() implemented */ + if (!(fi_extent.fe_flags & FIEMAP_EXTENT_DELALLOC)) { + printk("bad fiemap(%ld,%ld) on inode=%p &fieinfo=%p" + " i_size=%lld\n", start, len, inode, &fieinfo, + i_size_read(inode)); + BUG(); + } + /* complain about delalloc case -- ploop always fallocate + * before buffered write */ + WARN(1, "ploop%d: delalloc extent [%lld,%lld] for [%lld,%ld];" + " i_size=%lld\n", io->plo->index, fi_extent.fe_logical, + fi_extent.fe_length, start_off, len << 9, i_size_read(inode)); + ret = -ENOENT; + } set_fs(old_fs); if (ret) { @@ -808,9 +828,10 @@ void trim_extent_mappings(struct extent_map_tree *tree, sector_t start) while ((em = lookup_extent_mapping(tree, start, ((sector_t)(-1ULL)) - start))) { remove_extent_mapping(tree, em); + WARN_ON(atomic_read(&em->refs) != 2); /* once for us */ extent_put(em); - /* _XXX_ This cannot be correct in the case of concurrent lookups */ + /* No concurrent lookups due to ploop_quiesce(). See WARN_ON above */ /* once for the tree */ extent_put(em); } _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel