block: bdrv_invalidate_cache: invalidate children first
Current implementation invalidates firstly parent bds and then its children. This leads to the following bug: after incoming migration, in bdrv_invalidate_cache_all: 1. invalidate parent bds - reopen it with BDRV_O_INACTIVE cleared 2. child is not yet invalidated 3. parent check that its BDRV_O_INACTIVE is cleared 4. parent writes to child 5. assert in bdrv_co_pwritev, as BDRV_O_INACTIVE is set for child This patch fixes it by just changing invalidate sequence: invalidate children first. Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Message-id: 20170131112308.54189-1-vsementsov@virtuozzo.com Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
		
							parent
							
								
									a6baa60807
								
							
						
					
					
						commit
						16e977d506
					
				
							
								
								
									
										11
									
								
								block.c
								
								
								
								
							
							
						
						
									
										11
									
								
								block.c
								
								
								
								
							| 
						 | 
				
			
			@ -3248,19 +3248,18 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)
 | 
			
		|||
    if (!(bs->open_flags & BDRV_O_INACTIVE)) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    bs->open_flags &= ~BDRV_O_INACTIVE;
 | 
			
		||||
 | 
			
		||||
    if (bs->drv->bdrv_invalidate_cache) {
 | 
			
		||||
        bs->drv->bdrv_invalidate_cache(bs, &local_err);
 | 
			
		||||
    QLIST_FOREACH(child, &bs->children, next) {
 | 
			
		||||
        bdrv_invalidate_cache(child->bs, &local_err);
 | 
			
		||||
        if (local_err) {
 | 
			
		||||
            bs->open_flags |= BDRV_O_INACTIVE;
 | 
			
		||||
            error_propagate(errp, local_err);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QLIST_FOREACH(child, &bs->children, next) {
 | 
			
		||||
        bdrv_invalidate_cache(child->bs, &local_err);
 | 
			
		||||
    bs->open_flags &= ~BDRV_O_INACTIVE;
 | 
			
		||||
    if (bs->drv->bdrv_invalidate_cache) {
 | 
			
		||||
        bs->drv->bdrv_invalidate_cache(bs, &local_err);
 | 
			
		||||
        if (local_err) {
 | 
			
		||||
            bs->open_flags |= BDRV_O_INACTIVE;
 | 
			
		||||
            error_propagate(errp, local_err);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue