qemu-file: Fix qemu_put_compression_data flaw
Current qemu_put_compression_data can only work with no writable QEMUFile, and can't work with the writable QEMUFile. But it does not provide any measure to prevent users from using it with a writable QEMUFile. We should fix this flaw to make it works with writable QEMUFile. Signed-off-by: Liang Li <liang.z.li@intel.com> Suggested-by: Juan Quintela <quintela@redhat.com> Message-Id: <1462433579-13691-5-git-send-email-liang.z.li@intel.com> Signed-off-by: Amit Shah <amit.shah@redhat.com>
This commit is contained in:
		
							parent
							
								
									e7bb92e21a
								
							
						
					
					
						commit
						b3be28969b
					
				| @ -615,8 +615,14 @@ uint64_t qemu_get_be64(QEMUFile *f) | ||||
|     return v; | ||||
| } | ||||
| 
 | ||||
| /* compress size bytes of data start at p with specific compression
 | ||||
| /* Compress size bytes of data start at p with specific compression
 | ||||
|  * level and store the compressed data to the buffer of f. | ||||
|  * | ||||
|  * When f is not writable, return -1 if f has no space to save the | ||||
|  * compressed data. | ||||
|  * When f is wirtable and it has no space to save the compressed data, | ||||
|  * do fflush first, if f still has no space to save the compressed | ||||
|  * data, return -1. | ||||
|  */ | ||||
| 
 | ||||
| ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size, | ||||
| @ -625,7 +631,14 @@ ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size, | ||||
|     ssize_t blen = IO_BUF_SIZE - f->buf_index - sizeof(int32_t); | ||||
| 
 | ||||
|     if (blen < compressBound(size)) { | ||||
|         return 0; | ||||
|         if (!qemu_file_is_writable(f)) { | ||||
|             return -1; | ||||
|         } | ||||
|         qemu_fflush(f); | ||||
|         blen = IO_BUF_SIZE - sizeof(int32_t); | ||||
|         if (blen < compressBound(size)) { | ||||
|             return -1; | ||||
|         } | ||||
|     } | ||||
|     if (compress2(f->buf + f->buf_index + sizeof(int32_t), (uLongf *)&blen, | ||||
|                   (Bytef *)p, size, level) != Z_OK) { | ||||
| @ -633,7 +646,13 @@ ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size, | ||||
|         return 0; | ||||
|     } | ||||
|     qemu_put_be32(f, blen); | ||||
|     if (f->ops->writev_buffer) { | ||||
|         add_to_iovec(f, f->buf + f->buf_index, blen); | ||||
|     } | ||||
|     f->buf_index += blen; | ||||
|     if (f->buf_index == IO_BUF_SIZE) { | ||||
|         qemu_fflush(f); | ||||
|     } | ||||
|     return blen + sizeof(int32_t); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -821,7 +821,13 @@ static int do_compress_ram_page(CompressParam *param) | ||||
|                                   RAM_SAVE_FLAG_COMPRESS_PAGE); | ||||
|     blen = qemu_put_compression_data(param->file, p, TARGET_PAGE_SIZE, | ||||
|                                      migrate_compress_level()); | ||||
|     bytes_sent += blen; | ||||
|     if (blen < 0) { | ||||
|         bytes_sent = 0; | ||||
|         qemu_file_set_error(migrate_get_current()->to_dst_file, blen); | ||||
|         error_report("compressed data failed!"); | ||||
|     } else { | ||||
|         bytes_sent += blen; | ||||
|     } | ||||
| 
 | ||||
|     return bytes_sent; | ||||
| } | ||||
| @ -965,10 +971,12 @@ static int ram_save_compressed_page(QEMUFile *f, PageSearchStatus *pss, | ||||
|                  * first page is sent out before other pages | ||||
|                  */ | ||||
|                 bytes_xmit = do_compress_ram_page(&comp_param[0]); | ||||
|                 acct_info.norm_pages++; | ||||
|                 qemu_put_qemu_file(f, comp_param[0].file); | ||||
|                 *bytes_transferred += bytes_xmit; | ||||
|                 pages = 1; | ||||
|                 if (bytes_xmit > 0) { | ||||
|                     acct_info.norm_pages++; | ||||
|                     qemu_put_qemu_file(f, comp_param[0].file); | ||||
|                     *bytes_transferred += bytes_xmit; | ||||
|                     pages = 1; | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             pages = save_zero_page(f, block, offset, p, bytes_transferred); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Liang Li
						Liang Li