Skip to content
  • Zhiqiang Liu's avatar
    bcache: fix potential deadlock problem in btree_gc_coalesce · be23e837
    Zhiqiang Liu authored
    coccicheck reports:
      drivers/md//bcache/btree.c:1538:1-7: preceding lock on line 1417
    
    In btree_gc_coalesce func, if the coalescing process fails, we will goto
    to out_nocoalesce tag directly without releasing new_nodes[i]->write_lock.
    Then, it will cause a deadlock when trying to acquire new_nodes[i]->
    write_lock for freeing new_nodes[i] before return.
    
    btree_gc_coalesce func details as follows:
    	if alloc new_nodes[i] fails:
    		goto out_nocoalesce;
    	// obtain new_nodes[i]->write_lock
    	mutex_lock(&new_nodes[i]->write_lock)
    	// main coalescing process
    	for (i = nodes - 1; i > 0; --i)
    		[snipped]
    		if coalescing process fails:
    			// Here, directly goto out_nocoalesce
    			 // tag will cause a deadlock
    			goto out_nocoalesce;
    		[snipped]
    	// release new_nodes[i]->write_lock
    	mutex_unlock(&new_nodes[i]->write_lock)
    	// coalesing succ, return
    	return;
    out_nocoalesce:
    	btree_node_free(new_nodes[i])	// free new_nodes[i]
    	// obtain new_nodes[i]->write_lock
    	mutex_lock(&new_nodes[i]->write_lock);
    	// set flag for reuse
    	clear_bit(BTREE_NODE_dirty, &ew_nodes[i]->flags);
    	// release new_nodes[i]->write_lock
    	mutex_unlock(&new_nodes[i]->write_lock);
    
    To fix the problem, we add a new tag 'out_unlock_nocoalesce' for
    releasing new_nodes[i]->write_lock before out_nocoalesce tag. If
    coalescing process fails, we will go to out_unlock_nocoalesce tag
    for releasing new_nodes[i]->write_lock before free new_nodes[i] in
    out_nocoalesce tag.
    
    (Coly Li helps to clean up commit log format.)
    
    Fixes: 2a285686
    
     ("bcache: btree locking rework")
    Signed-off-by: default avatarZhiqiang Liu <liuzhiqiang26@huawei.com>
    Signed-off-by: default avatarColy Li <colyli@suse.de>
    Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
    be23e837