There was a complain about intersecting extents:

> [123825.298494] ploop_fb_add_free_extent(): intersected 
> extentsploop_fb_add_free_extent(): intersected extents

Next time it happens, we'll have more info to chase root cause.

v2: added WARN_ONCE to taint kernel

Signed-off-by: Maxim Patlasov <mpatla...@virtuozzo.com>
---
 drivers/block/ploop/dev.c      |   32 +++++++++++++++++++++++++++++++-
 drivers/block/ploop/freeblks.c |   18 ++++++++++++++----
 2 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c
index 2f9a571..d2f3b2d 100644
--- a/drivers/block/ploop/dev.c
+++ b/drivers/block/ploop/dev.c
@@ -2113,8 +2113,17 @@ static int ploop_entry_discard_req(struct ploop_request 
*preq)
                                                        preq->dst_cluster,
                                                        preq->dst_iblock, len);
                        preq->dst_iblock = 0;
-                       if (err)
+                       if (err) {
+                               if (err == -EINVAL) {
+                                       printk("ploop_entry_discard_req1: "
+                                              "(%lu %u; %u %u; %u %u)\n",
+                                              preq->req_sector, preq->req_size,
+                                              preq->req_cluster, preq->iblock,
+                                              preq->dst_cluster, 
preq->dst_iblock);
+                                       WARN_ONCE(1, "add_free_extent 
failed\n");
+                               }
                                goto err;
+                       }
                }
 
                if (!preq->dst_iblock && preq->iblock) {
@@ -2127,6 +2136,14 @@ static int ploop_entry_discard_req(struct ploop_request 
*preq)
                len = preq->req_cluster - preq->dst_cluster;
                err = ploop_fb_add_free_extent(plo->fbd, preq->dst_cluster,
                                                preq->dst_iblock, len);
+               if (err == -EINVAL) {
+                       printk("ploop_entry_discard_req2: "
+                              "(%lu %u; %u %u; %u %u)\n",
+                              preq->req_sector, preq->req_size,
+                              preq->req_cluster, preq->iblock,
+                              preq->dst_cluster, preq->dst_iblock);
+                       WARN_ONCE(1, "add_free_extent failed\n");
+               }
        }
 
 err:
@@ -4527,6 +4544,19 @@ static int ploop_freeblks_ioc(struct ploop_device *plo, 
unsigned long arg)
                rc = ploop_fb_add_free_extent(fbd, extent.clu,
                                        extent.iblk, extent.len);
                if (rc) {
+                       if (rc == -EINVAL) {
+                               printk("ploop_freeblks_ioc: n=%d\n", 
ctl.n_extents);
+                               for (i = 0; i < ctl.n_extents; i++) {
+                                       if (copy_from_user(&extent, &extents[i],
+                                                          sizeof(extent))) {
+                                               printk("copy failed: i=%d\n", 
i);
+                                               break;
+                                       }
+                                       printk("ploop_freeblks_ioc: i=%d: %u %u 
%u\n",
+                                              i, extent.clu, extent.iblk, 
extent.len);
+                               }
+                               WARN_ONCE(1, "add_free_extent failed\n");
+                       }
                        ploop_fb_fini(fbd, rc);
                        goto exit;
                }
diff --git a/drivers/block/ploop/freeblks.c b/drivers/block/ploop/freeblks.c
index bc045a4..cf2fb54 100644
--- a/drivers/block/ploop/freeblks.c
+++ b/drivers/block/ploop/freeblks.c
@@ -873,14 +873,24 @@ int ploop_fb_add_free_extent(struct ploop_freeblks_desc 
*fbd,
                tmp = list_entry(ex->list.next, struct ploop_freeblks_extent, 
list);
 
                if (iblk + len > tmp->iblk) {
-                       printk("ploop_fb_add_free_extent(): intersected 
extents");
+                       int c = &ex->list != &fbd->fbd_free_list;
+                       printk("ploop_fb_add_free_extent(): next (%u %u %u) "
+                              "intersects with (%u %u %u); ex (%u %u %d)\n",
+                              tmp->clu, tmp->iblk, tmp->len, clu, iblk, len,
+                              c ? ex->clu : 0, c ? ex->iblk : 0, c ? ex->len : 
-1);
                        return -EINVAL;
                }
        }
 
        if (&ex->list != &fbd->fbd_free_list) {
                if (ex->iblk + ex->len > iblk) {
-                       printk("ploop_fb_add_free_extent(): intersected 
extents");
+                       struct ploop_freeblks_extent *t = NULL;
+                       if (ex->list.next != &fbd->fbd_free_list)
+                               t = list_entry(ex->list.next, struct 
ploop_freeblks_extent, list);
+                       printk("ploop_fb_add_free_extent(): ex (%u %u %u) "
+                              "intersects with (%u %u %u); next (%u %u %d)\n",
+                              ex->clu, ex->iblk, ex->len, clu, iblk, len,
+                              t ? t->clu : 0, t ? t->iblk : 0, t ? t->len : 
-1);
                        return -EINVAL;
                }
        }
@@ -918,7 +928,7 @@ int ploop_fb_add_reloc_extent(struct ploop_freeblks_desc 
*fbd,
                rblk_extent = list_entry(fbd->fbd_reloc_list.prev,
                                         struct ploop_relocblks_extent, list);
                if (rblk_extent->iblk + rblk_extent->len > iblk) {
-                       printk("ploop_fb_add_reloc_extent(): extents should be 
sorted");
+                       printk("ploop_fb_add_reloc_extent(): extents should be 
sorted\n");
                        return -EINVAL;
                }
 
@@ -926,7 +936,7 @@ int ploop_fb_add_reloc_extent(struct ploop_freeblks_desc 
*fbd,
                        rblk_extent = list_entry(rblk_extent->list.next,
                                         struct ploop_relocblks_extent, list);
                        if (iblk + len > rblk_extent->iblk) {
-                               printk("ploop_fb_add_reloc_extent(): 
intersected extents");
+                               printk("ploop_fb_add_reloc_extent(): 
intersected extents\n");
                                return -EINVAL;
                        }
                }

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to