block: Improve get_allocated_file_size's default
There are two practical problems with bdrv_get_allocated_file_size()'s
default right now:
(1) For drivers with children, we should generally sum all their sizes
    instead of just passing the request through to bs->file.  The latter
    is good for filters, but not so much for format drivers.
(2) Filters need not have bs->file, so we should actually go to the
    filtered child instead of hard-coding bs->file.
Fix this by splitting the default implementation into three branches:
(1) For filter drivers: Return the size of the filtered child
(2) For protocol drivers: Return -ENOTSUP, because the default
    implementation cannot make a guess
(3) For other drivers: Sum all data-bearing children's sizes
Signed-off-by: Max Reitz <mreitz@redhat.com>
			
			
This commit is contained in:
		
							parent
							
								
									f706a92f24
								
							
						
					
					
						commit
						081e465026
					
				
							
								
								
									
										42
									
								
								block.c
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								block.c
									
									
									
									
									
								
							| @ -5005,6 +5005,31 @@ exit: | |||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * Implementation of BlockDriver.bdrv_get_allocated_file_size() that | ||||||
|  |  * sums the size of all data-bearing children.  (This excludes backing | ||||||
|  |  * children.) | ||||||
|  |  */ | ||||||
|  | static int64_t bdrv_sum_allocated_file_size(BlockDriverState *bs) | ||||||
|  | { | ||||||
|  |     BdrvChild *child; | ||||||
|  |     int64_t child_size, sum = 0; | ||||||
|  | 
 | ||||||
|  |     QLIST_FOREACH(child, &bs->children, next) { | ||||||
|  |         if (child->role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA | | ||||||
|  |                            BDRV_CHILD_FILTERED)) | ||||||
|  |         { | ||||||
|  |             child_size = bdrv_get_allocated_file_size(child->bs); | ||||||
|  |             if (child_size < 0) { | ||||||
|  |                 return child_size; | ||||||
|  |             } | ||||||
|  |             sum += child_size; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return sum; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Length of a allocated file in bytes. Sparse files are counted by actual |  * Length of a allocated file in bytes. Sparse files are counted by actual | ||||||
|  * allocated space. Return < 0 if error or unknown. |  * allocated space. Return < 0 if error or unknown. | ||||||
| @ -5018,10 +5043,21 @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs) | |||||||
|     if (drv->bdrv_get_allocated_file_size) { |     if (drv->bdrv_get_allocated_file_size) { | ||||||
|         return drv->bdrv_get_allocated_file_size(bs); |         return drv->bdrv_get_allocated_file_size(bs); | ||||||
|     } |     } | ||||||
|     if (bs->file) { | 
 | ||||||
|         return bdrv_get_allocated_file_size(bs->file->bs); |     if (drv->bdrv_file_open) { | ||||||
|     } |         /*
 | ||||||
|  |          * Protocol drivers default to -ENOTSUP (most of their data is | ||||||
|  |          * not stored in any of their children (if they even have any), | ||||||
|  |          * so there is no generic way to figure it out). | ||||||
|  |          */ | ||||||
|         return -ENOTSUP; |         return -ENOTSUP; | ||||||
|  |     } else if (drv->is_filter) { | ||||||
|  |         /* Filter drivers default to the size of their filtered child */ | ||||||
|  |         return bdrv_get_allocated_file_size(bdrv_filter_bs(bs)); | ||||||
|  |     } else { | ||||||
|  |         /* Other drivers default to summing their children's sizes */ | ||||||
|  |         return bdrv_sum_allocated_file_size(bs); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Max Reitz
						Max Reitz