The commit is pushed to "branch-rh8-4.18.0-305.3.1.vz8.7.x-ovz" and will appear 
at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-305.3.1.vz8.7.2
------>
commit 02f2cfce786858a24b8be2a2034472897999ffd0
Author: Kirill Tkhai <[email protected]>
Date:   Thu Aug 5 18:28:22 2021 +0300

    ploop: Handle ENOSPC in prq_endio()
    
    prq_endio() is final place for all handled requests.
    There are no splitted pios, there are only original
    requests came from upper level. So, it's a good place
    to handle any ENOSPC instead of doing this in many
    places of code.
    
    Next patch will make allocate_cluster() care about
    ENOSPC, and that will already picked by update in this
    patch.
    
    https://jira.sw.ru/browse/PSBM-131771
    
    Signed-off-by: Kirill Tkhai <[email protected]>
    
    ====================
    Patchset descrition:
    
    ploop: Handle falloc ENOSPC
    
     #PSBM-106554 added fallocation of whole cluster.
    This case also may fail with -ENOSPC. We need
    to resubmit pio after that in the same way as
    it's done in #PSBM-127225.
    
    https://jira.sw.ru/browse/PSBM-131771
    
    Kirill Tkhai (3):
          ploop: Introduce init_prq_and_embedded_pio()
          ploop: Handle ENOSPC in prq_endio()
          ploop: Pass actual error from allocate_cluster()
---
 drivers/md/dm-ploop-map.c | 107 +++++++++++++++++++++++++---------------------
 1 file changed, 59 insertions(+), 48 deletions(-)

diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index 4ef07f2d3fbb..7d1e6538615d 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -128,6 +128,52 @@ static void init_prq_and_embedded_pio(struct ploop *ploop, 
struct request *rq,
        pio->endio_cb_data = prq;
 }
 
+void ploop_enospc_timer(struct timer_list *timer)
+{
+       struct ploop *ploop = from_timer(ploop, timer, enospc_timer);
+       unsigned long flags;
+       LIST_HEAD(list);
+
+       spin_lock_irqsave(&ploop->deferred_lock, flags);
+       list_splice_init(&ploop->enospc_pios, &list);
+       spin_unlock_irqrestore(&ploop->deferred_lock, flags);
+
+       submit_embedded_pios(ploop, &list);
+}
+
+void ploop_event_work(struct work_struct *ws)
+{
+       struct ploop *ploop = container_of(ws, struct ploop, event_work);
+
+       dm_table_event(ploop->ti->table);
+}
+
+static bool ploop_try_delay_enospc(struct ploop_rq *prq, struct pio *pio)
+{
+       struct ploop *ploop = pio->ploop;
+       bool delayed = true;
+       unsigned long flags;
+
+       spin_lock_irqsave(&ploop->deferred_lock, flags);
+       if (unlikely(ploop->wants_suspend)) {
+               delayed = false;
+               goto unlock;
+       }
+
+       init_prq_and_embedded_pio(ploop, prq->rq, prq, pio);
+
+       ploop->event_enospc = true;
+       list_add_tail(&pio->list, &ploop->enospc_pios);
+unlock:
+       spin_unlock_irqrestore(&ploop->deferred_lock, flags);
+
+       if (delayed)
+               mod_timer(&ploop->enospc_timer, jiffies + PLOOP_ENOSPC_TIMEOUT);
+       schedule_work(&ploop->event_work);
+
+       return delayed;
+}
+
 void prq_endio(struct pio *pio, void *prq_ptr, blk_status_t bi_status)
 {
         struct ploop_rq *prq = prq_ptr;
@@ -137,6 +183,19 @@ void prq_endio(struct pio *pio, void *prq_ptr, 
blk_status_t bi_status)
                kfree(prq->bvec);
        if (prq->css)
                css_put(prq->css);
+       /*
+        * Here is exit point for rq, and here we handle ENOSPC.
+        * Embedded pios will be reinitialized like they've just
+        * came from upper dm level, and later resubmitted after
+        * timeout. Note, that we do not handle merge here: merge
+        * callers receive -ENOSPC synchronous without intermediaries.
+        */
+       if (unlikely(bi_status == BLK_STS_NOSPC)) {
+               WARN_ON_ONCE(!op_is_write(pio->bi_op));
+               if (ploop_try_delay_enospc(prq, pio))
+                       return;
+       }
+
        dm_complete_request(rq, bi_status);
 }
 
@@ -1119,49 +1178,6 @@ static void ploop_queue_resubmit(struct pio *pio)
        queue_work(ploop->wq, &ploop->worker);
 }
 
-void ploop_enospc_timer(struct timer_list *timer)
-{
-       struct ploop *ploop = from_timer(ploop, timer, enospc_timer);
-       unsigned long flags;
-
-       spin_lock_irqsave(&ploop->deferred_lock, flags);
-       list_splice_init(&ploop->enospc_pios, &ploop->resubmit_pios);
-       spin_unlock_irqrestore(&ploop->deferred_lock, flags);
-
-       queue_work(ploop->wq, &ploop->worker);
-}
-
-void ploop_event_work(struct work_struct *ws)
-{
-       struct ploop *ploop = container_of(ws, struct ploop, event_work);
-
-       dm_table_event(ploop->ti->table);
-}
-
-static bool ploop_try_delay_enospc(struct pio *pio)
-{
-       struct ploop *ploop = pio->ploop;
-       bool delayed = true;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ploop->deferred_lock, flags);
-       if (unlikely(ploop->wants_suspend)) {
-               delayed = false;
-               goto unlock;
-       }
-
-       ploop->event_enospc = true;
-       list_add_tail(&pio->list, &ploop->enospc_pios);
-unlock:
-       spin_unlock_irqrestore(&ploop->deferred_lock, flags);
-
-       if (delayed)
-               mod_timer(&ploop->enospc_timer, jiffies + PLOOP_ENOSPC_TIMEOUT);
-       schedule_work(&ploop->event_work);
-
-       return delayed;
-}
-
 static void data_rw_complete(struct pio *pio)
 {
        bool completed;
@@ -1174,11 +1190,6 @@ static void data_rw_complete(struct pio *pio)
                        ploop_queue_resubmit(pio);
                        return;
                }
-               if (pio->ret == -ENOSPC) {
-                       WARN_ON_ONCE(!op_is_write(pio->bi_op));
-                       if (ploop_try_delay_enospc(pio))
-                               return;
-               }
                pio->bi_status = errno_to_blk_status(pio->ret);
        }
 
_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to