[Devel] [RFC PATCH vz9 v6 39/62] dm-ploop: prepare bat updates under bat_lock

Alexander Atanasov alexander.atanasov at virtuozzo.com
Mon Jan 20 16:36:05 MSK 2025


On 17.01.25 9:10, Pavel Tikhomirov wrote:
> Here is possible scenario of double-unlock of bat_lock:
>

fixed. also removed the goto out without cleanup.

> On 12/6/24 05:56, Alexander Atanasov wrote:
>> @@ -1758,23 +1789,29 @@ static void 
>> ploop_process_one_discard_pio(struct ploop *ploop, struct pio *pio)
>>       struct ploop_index_wb *piwb;
>>       struct md_page *md;
>>       map_index_t *to;
>> +    unsigned long flags;
>>       WARN_ON(ploop->nr_deltas != 1 ||
>>           pio->queue_list_id != PLOOP_LIST_DISCARD);
>>       page_id = ploop_bat_clu_to_page_nr(clu);
>>       md = ploop_md_page_find(ploop, page_id);
>> -    if (ploop_delay_if_md_busy(ploop, md, PIWB_TYPE_DISCARD, pio))
> 
> take bat_lock:
> 
>> +    spin_lock_irqsave(&ploop->bat_lock, flags);
>> +    if (ploop_delay_if_md_busy(ploop, md, PIWB_TYPE_DISCARD, pio)) {
>> +        spin_unlock_irqrestore(&ploop->bat_lock, flags);
>>           goto out;
>> +    }
>> +
>>       if (!test_bit(MD_DIRTY, &md->status)) {
>> -         /* Unlocked since MD_DIRTY is set and cleared from this work */
>>           if (ploop_prepare_bat_update(ploop, md, PIWB_TYPE_DISCARD) < 
>> 0) {
>>               pio->bi_status = BLK_STS_RESOURCE;
>>               goto err;
>>           }
>>           bat_update_prepared = true;
>> +        ploop_md_make_dirty(ploop, md);
>>       }
> 
> release bat_lock:
> 
>> +    spin_unlock_irqrestore(&ploop->bat_lock, flags);
>>       piwb = md->piwb;
>> @@ -1784,18 +1821,20 @@ static void 
>> ploop_process_one_discard_pio(struct ploop *ploop, struct pio *pio)
>>       to = piwb->kmpage;
>>       if (WARN_ON_ONCE(!to[clu])) {
>>           pio->bi_status = BLK_STS_IOERR;
>> +        clear_bit(MD_DIRTY, &md->status);
> 
> goto err:
> 
>>           goto err;
>>       } else {
>>           WRITE_ONCE(to[clu], 0);
>> +        spin_lock_irqsave(&piwb->lock, flags);
>>           list_add_tail(&pio->list, &piwb->ready_data_pios);
>> +        spin_unlock_irqrestore(&piwb->lock, flags);
>>       }
>> -    if (bat_update_prepared)
>> -        ploop_md_make_dirty(ploop, md);
>>       ploop_md_up_prio(ploop, md);
>>   out:
>>       return;
>>   err:
> 
> release bat lock again:
> 
>> +    spin_unlock_irqrestore(&ploop->bat_lock, flags);
>>       if (bat_update_prepared)
>>           ploop_break_bat_update(ploop, md);
>>       ploop_pio_endio(pio);
> 

-- 
Regards,
Alexander Atanasov



More information about the Devel mailing list