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

Reply via email to