file-posix: Clear bs->bl.zoned on error

bs->bl.zoned is what indicates whether the zone information is present
and valid; it is the only thing that raw_refresh_zoned_limits() sets if
CONFIG_BLKZONED is not defined, and it is also the only thing that it
sets if CONFIG_BLKZONED is defined, but there are no zones.

Make sure that it is always set to BLK_Z_NONE if there is an error
anywhere in raw_refresh_zoned_limits() so that we do not accidentally
announce zones while our information is incomplete or invalid.

This also fixes a memory leak in the last error path in
raw_refresh_zoned_limits().

Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
Message-Id: <20230824155345.109765-2-hreitz@redhat.com>
Reviewed-by: Sam Li <faithilikerun@gmail.com>
(cherry picked from commit 56d1a022a7)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
This commit is contained in:
Hanna Czenczek 2023-08-24 17:53:40 +02:00 committed by Michael Tokarev
parent f59caeca76
commit c2e6a00b5f

View File

@ -1412,11 +1412,9 @@ static void raw_refresh_zoned_limits(BlockDriverState *bs, struct stat *st,
BlockZoneModel zoned;
int ret;
bs->bl.zoned = BLK_Z_NONE;
ret = get_sysfs_zoned_model(st, &zoned);
if (ret < 0 || zoned == BLK_Z_NONE) {
return;
goto no_zoned;
}
bs->bl.zoned = zoned;
@ -1437,10 +1435,10 @@ static void raw_refresh_zoned_limits(BlockDriverState *bs, struct stat *st,
if (ret < 0) {
error_setg_errno(errp, -ret, "Unable to read chunk_sectors "
"sysfs attribute");
return;
goto no_zoned;
} else if (!ret) {
error_setg(errp, "Read 0 from chunk_sectors sysfs attribute");
return;
goto no_zoned;
}
bs->bl.zone_size = ret << BDRV_SECTOR_BITS;
@ -1448,10 +1446,10 @@ static void raw_refresh_zoned_limits(BlockDriverState *bs, struct stat *st,
if (ret < 0) {
error_setg_errno(errp, -ret, "Unable to read nr_zones "
"sysfs attribute");
return;
goto no_zoned;
} else if (!ret) {
error_setg(errp, "Read 0 from nr_zones sysfs attribute");
return;
goto no_zoned;
}
bs->bl.nr_zones = ret;
@ -1472,10 +1470,15 @@ static void raw_refresh_zoned_limits(BlockDriverState *bs, struct stat *st,
ret = get_zones_wp(bs, s->fd, 0, bs->bl.nr_zones, 0);
if (ret < 0) {
error_setg_errno(errp, -ret, "report wps failed");
bs->wps = NULL;
return;
goto no_zoned;
}
qemu_co_mutex_init(&bs->wps->colock);
return;
no_zoned:
bs->bl.zoned = BLK_Z_NONE;
g_free(bs->wps);
bs->wps = NULL;
}
#else /* !defined(CONFIG_BLKZONED) */
static void raw_refresh_zoned_limits(BlockDriverState *bs, struct stat *st,