block级锁的理解

1 block 里面的sem本质上是一个队列,是对action的排队
目前来说, action包括(io, unmap, remap, merge)
2 block 里面为什么一定要一把状态的锁, 因为在某些流程处理中, {检测状态 = >做相应操作} 后面的相应操作必须要依赖前面的状态。 如果不用状态锁的话, 其它上下文可能会改变该状态,从而使后面的操作没有意义。
3 put_block中为什么用atomic_dec_and_block。这是为了将{ref_cnt等于0, 拿树的锁}做成一个原子的事务。即: 拿树的锁是基于ref_cnt为0的情况。


这里可以对比理解一下: 引用计数可以使用原子变量, 而状态需要加锁(而不用原子变量)。 因为引用计数通过atomic_dec_and_block保证{检测, 操作}是放在一个原子操作中的。

struct block *search_and_get_block(struct sd *sd, sector_t blk)
{
        struct block_block *block = NULL;
 
find:
        read_lock_irqsave(&sd->tree_lock, flag);
        if ((block = radix_tree_lookup(&sd->active_blocks_tree, blk))) {
                get_block(block);
                read_unlock_irqrestore(&sd->tree_lock, flag);
                goto out;
        }
        read_unlock_irqrestore(&sd->tree_lock, flag);
 
        block = alloc_and_init_block(sd, blk);
 
        write_lock_irqsave(&sd->tree_lock, flag);
 
        ret = radix_tree_insert(&sd->active_blocks_tree, blk, block);
        if (ret == -EEXIST) { /* other ctx has inserted it */
                write_unlock_irqrestore(&sd->tree_lock, flag);
                free_block(block);
                goto find;
        } else if (ret == -ENOMEM) { /* NOMEM during insert */
                write_unlock_irqrestore(&sd->tree_lock, flag);
                free_block(block);
                goto out;
        }
 
        /* insert successfuly */

        get_block(block);
        write_unlock_irqrestore(&sd->tree_lock, flag);
out:
        return block;
}

void put_block(struct block *block)
{
        struct sd *sd = block->sd;
 
        lock_block(block);
        if (block->status == PART_IN_LOCAL) {
                atomic_dec(&block->ref);
                unlock_block(block);
                return;
        }
 
        if (atomic_dec_and_lock(&block->ref, &sd->tree_lock)) {
                radix_tree_delete(&sd->blk_tree, block->blk_no);
                set_bitmap(sd, block);
                spin_unlock(&sd->tree_lock);
 
                unlock_block(block);
                free_block(block);
                return;
        }
        unlock(block);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值