file-posix: fix over-writing of returning zone_append offset
raw_co_zone_append() sets "s->offset" where "BDRVRawState *s". This pointer
is used later at raw_co_prw() to save the block address where the data is
written.
When multiple IOs are on-going at the same time, a later IO's
raw_co_zone_append() call over-writes a former IO's offset address before
raw_co_prw() completes. As a result, the former zone append IO returns the
initial value (= the start address of the writing zone), instead of the
proper address.
Fix the issue by passing the offset pointer to raw_co_prw() instead of
passing it through s->offset. Also, remove "offset" from BDRVRawState as
there is no usage anymore.
Fixes: 4751d09adc ("block: introduce zone append write for zoned devices")
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Message-Id: <20231030073853.2601162-1-naohiro.aota@wdc.com>
Reviewed-by: Sam Li <faithilikerun@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
			
			
This commit is contained in:
		
				
					committed by
					
						 Hanna Czenczek
						Hanna Czenczek
					
				
			
			
				
	
			
			
			
						parent
						
							10b9e0802a
						
					
				
				
					commit
					ad4feaca61
				
			| @@ -160,7 +160,6 @@ typedef struct BDRVRawState { | |||||||
|     bool has_write_zeroes:1; |     bool has_write_zeroes:1; | ||||||
|     bool use_linux_aio:1; |     bool use_linux_aio:1; | ||||||
|     bool use_linux_io_uring:1; |     bool use_linux_io_uring:1; | ||||||
|     int64_t *offset; /* offset of zone append operation */ |  | ||||||
|     int page_cache_inconsistent; /* errno from fdatasync failure */ |     int page_cache_inconsistent; /* errno from fdatasync failure */ | ||||||
|     bool has_fallocate; |     bool has_fallocate; | ||||||
|     bool needs_alignment; |     bool needs_alignment; | ||||||
| @@ -2445,12 +2444,13 @@ static bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov) | |||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| static int coroutine_fn raw_co_prw(BlockDriverState *bs, uint64_t offset, | static int coroutine_fn raw_co_prw(BlockDriverState *bs, int64_t *offset_ptr, | ||||||
|                                    uint64_t bytes, QEMUIOVector *qiov, int type) |                                    uint64_t bytes, QEMUIOVector *qiov, int type) | ||||||
| { | { | ||||||
|     BDRVRawState *s = bs->opaque; |     BDRVRawState *s = bs->opaque; | ||||||
|     RawPosixAIOData acb; |     RawPosixAIOData acb; | ||||||
|     int ret; |     int ret; | ||||||
|  |     uint64_t offset = *offset_ptr; | ||||||
|  |  | ||||||
|     if (fd_open(bs) < 0) |     if (fd_open(bs) < 0) | ||||||
|         return -EIO; |         return -EIO; | ||||||
| @@ -2513,8 +2513,8 @@ out: | |||||||
|             uint64_t *wp = &wps->wp[offset / bs->bl.zone_size]; |             uint64_t *wp = &wps->wp[offset / bs->bl.zone_size]; | ||||||
|             if (!BDRV_ZT_IS_CONV(*wp)) { |             if (!BDRV_ZT_IS_CONV(*wp)) { | ||||||
|                 if (type & QEMU_AIO_ZONE_APPEND) { |                 if (type & QEMU_AIO_ZONE_APPEND) { | ||||||
|                     *s->offset = *wp; |                     *offset_ptr = *wp; | ||||||
|                     trace_zbd_zone_append_complete(bs, *s->offset |                     trace_zbd_zone_append_complete(bs, *offset_ptr | ||||||
|                         >> BDRV_SECTOR_BITS); |                         >> BDRV_SECTOR_BITS); | ||||||
|                 } |                 } | ||||||
|                 /* Advance the wp if needed */ |                 /* Advance the wp if needed */ | ||||||
| @@ -2539,14 +2539,14 @@ static int coroutine_fn raw_co_preadv(BlockDriverState *bs, int64_t offset, | |||||||
|                                       int64_t bytes, QEMUIOVector *qiov, |                                       int64_t bytes, QEMUIOVector *qiov, | ||||||
|                                       BdrvRequestFlags flags) |                                       BdrvRequestFlags flags) | ||||||
| { | { | ||||||
|     return raw_co_prw(bs, offset, bytes, qiov, QEMU_AIO_READ); |     return raw_co_prw(bs, &offset, bytes, qiov, QEMU_AIO_READ); | ||||||
| } | } | ||||||
|  |  | ||||||
| static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, int64_t offset, | static int coroutine_fn raw_co_pwritev(BlockDriverState *bs, int64_t offset, | ||||||
|                                        int64_t bytes, QEMUIOVector *qiov, |                                        int64_t bytes, QEMUIOVector *qiov, | ||||||
|                                        BdrvRequestFlags flags) |                                        BdrvRequestFlags flags) | ||||||
| { | { | ||||||
|     return raw_co_prw(bs, offset, bytes, qiov, QEMU_AIO_WRITE); |     return raw_co_prw(bs, &offset, bytes, qiov, QEMU_AIO_WRITE); | ||||||
| } | } | ||||||
|  |  | ||||||
| static int coroutine_fn raw_co_flush_to_disk(BlockDriverState *bs) | static int coroutine_fn raw_co_flush_to_disk(BlockDriverState *bs) | ||||||
| @@ -3509,8 +3509,6 @@ static int coroutine_fn raw_co_zone_append(BlockDriverState *bs, | |||||||
|     int64_t zone_size_mask = bs->bl.zone_size - 1; |     int64_t zone_size_mask = bs->bl.zone_size - 1; | ||||||
|     int64_t iov_len = 0; |     int64_t iov_len = 0; | ||||||
|     int64_t len = 0; |     int64_t len = 0; | ||||||
|     BDRVRawState *s = bs->opaque; |  | ||||||
|     s->offset = offset; |  | ||||||
|  |  | ||||||
|     if (*offset & zone_size_mask) { |     if (*offset & zone_size_mask) { | ||||||
|         error_report("sector offset %" PRId64 " is not aligned to zone size " |         error_report("sector offset %" PRId64 " is not aligned to zone size " | ||||||
| @@ -3531,7 +3529,7 @@ static int coroutine_fn raw_co_zone_append(BlockDriverState *bs, | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     trace_zbd_zone_append(bs, *offset >> BDRV_SECTOR_BITS); |     trace_zbd_zone_append(bs, *offset >> BDRV_SECTOR_BITS); | ||||||
|     return raw_co_prw(bs, *offset, len, qiov, QEMU_AIO_ZONE_APPEND); |     return raw_co_prw(bs, offset, len, qiov, QEMU_AIO_ZONE_APPEND); | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user