--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -893,35 +893,47 @@ static void ploop_bat_write_complete(struct pio *pio, 
void *piwb_ptr,
        struct ploop_cow *cow;
        struct pio *data_pio;
        unsigned long flags;
-
-       if (!bi_status) {
-               /*
-                * Success: now update local BAT copy. We could do this
-                * from our delayed work, but we want to publish new
-                * mapping in the fastest way. This must be done before
-                * data bios completion, since right after we complete
-                * a bio, subsequent read wants to see written data
-                * (ploop_map() wants to see not zero bat_entries[.]).
-                */
-               ploop_advance_local_after_bat_wb(ploop, piwb, true);
+       LIST_HEAD(lready_pios);
+       LIST_HEAD(lcow_pios);
+       int completed = atomic_read(&piwb->count) == 1;

Maybe we can use this construct:

if (atomic_dec_and_test(&piwb->count)) {do}

+
+       if (completed) {
+               /* We are the last count so it is safe to advance bat */
+               if (!bi_status) {
+                       /*
+                        * Success: now update local BAT copy. We could do this
+                        * from our delayed work, but we want to publish new
+                        * mapping in the fastest way. This must be done before
+                        * data bios completion, since right after we complete
+                        * a bio, subsequent read wants to see written data
+                        * (ploop_map() wants to see not zero bat_entries[.]).
+                        */
+                       ploop_advance_local_after_bat_wb(ploop, piwb, true);
+               }
        }
spin_lock_irqsave(&piwb->lock, flags);
-       piwb->completed = true;
+       if (completed)
+               piwb->completed = completed;
        piwb->bi_status = bi_status;
+       list_splice_init(&piwb->ready_data_pios, &lready_pios);
        spin_unlock_irqrestore(&piwb->lock, flags);
+ spin_lock_irqsave(&ploop->deferred_lock, flags);
+       list_splice_init(&piwb->cow_list, &lcow_pios);
+       spin_unlock_irqrestore(&ploop->deferred_lock, flags);
+
        /*
-        * End pending data bios. Unlocked, as nobody can
-        * add a new element after piwc->completed is true.
+        * End pending data bios.
         */
-       while ((data_pio = ploop_pio_list_pop(&piwb->ready_data_pios)) != NULL) 
{
+
+       while ((data_pio = ploop_pio_list_pop(&lready_pios)) != NULL) {
                if (bi_status)
                        data_pio->bi_status = bi_status;
                ploop_pio_endio(data_pio);
        }
- while ((aux_pio = ploop_pio_list_pop(&piwb->cow_list))) {
+       while ((aux_pio = ploop_pio_list_pop(&lcow_pios))) {
                cow = aux_pio->endio_cb_data;
                ploop_complete_cow(cow, bi_status);
        }

--
Best regards, Tikhomirov Pavel
Senior Software Developer, Virtuozzo.

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

Reply via email to