z->wp + required > z->start + f->zbd_info->zone_size;
}
-static void zone_lock(struct thread_data *td, struct fio_zone_info *z)
+static void zone_lock(struct thread_data *td, struct fio_file *f, struct fio_zone_info *z)
{
+ struct zoned_block_device_info *zbd = f->zbd_info;
+ uint32_t nz = z - zbd->zone_info;
+
+ /* A thread should never lock zones outside its working area. */
+ assert(f->min_zone <= nz && nz < f->max_zone);
+
/*
* Lock the io_u target zone. The zone will be unlocked if io_u offset
* is changed or when io_u completes and zbd_put_io() executed.
(unsigned long long) new_end - f->file_offset);
f->io_size = new_end - f->file_offset;
}
+
+ f->min_zone = zbd_zone_idx(f, f->file_offset);
+ f->max_zone = zbd_zone_idx(f, f->file_offset + f->io_size);
}
}
if (!zbd_zone_swr(z))
continue;
- zone_lock(td, z);
+ zone_lock(td, f, z);
if (all_zones) {
unsigned int i;
void zbd_file_reset(struct thread_data *td, struct fio_file *f)
{
struct fio_zone_info *zb, *ze;
- uint32_t zone_idx_e;
if (!f->zbd_info || !td_write(td))
return;
- zb = &f->zbd_info->zone_info[zbd_zone_idx(f, f->file_offset)];
- zone_idx_e = zbd_zone_idx(f, f->file_offset + f->io_size);
- ze = &f->zbd_info->zone_info[zone_idx_e];
+ zb = &f->zbd_info->zone_info[f->min_zone];
+ ze = &f->zbd_info->zone_info[f->max_zone];
zbd_init_swd(f);
/*
* If data verification is enabled reset the affected zones before
struct io_u *io_u)
{
const uint32_t min_bs = td->o.min_bs[io_u->ddir];
- const struct fio_file *f = io_u->file;
+ struct fio_file *f = io_u->file;
struct fio_zone_info *z;
unsigned int open_zone_idx = -1;
uint32_t zone_idx, new_zone_idx;
} else {
zone_idx = zbd_zone_idx(f, io_u->offset);
}
+ if (zone_idx < f->min_zone)
+ zone_idx = f->min_zone;
+ else if (zone_idx >= f->max_zone)
+ zone_idx = f->max_zone - 1;
dprint(FD_ZBD, "%s(%s): starting from zone %d (offset %lld, buflen %lld)\n",
__func__, f->file_name, zone_idx, io_u->offset, io_u->buflen);
z = &f->zbd_info->zone_info[zone_idx];
- zone_lock(td, z);
+ zone_lock(td, f, z);
pthread_mutex_lock(&f->zbd_info->mutex);
if (td->o.max_open_zones == 0)
goto examine_zone;
if (tmp_idx >= f->zbd_info->num_open_zones)
tmp_idx = 0;
tmpz = f->zbd_info->open_zones[tmp_idx];
-
- if (is_valid_offset(f, f->zbd_info->zone_info[tmpz].start)) {
+ if (f->min_zone <= tmpz && tmpz < f->max_zone) {
open_zone_idx = tmp_idx;
goto found_candidate_zone;
}
z++;
if (!is_valid_offset(f, z->start)) {
/* Wrap-around. */
- zone_idx = zbd_zone_idx(f, f->file_offset);
+ zone_idx = f->min_zone;
z = &f->zbd_info->zone_info[zone_idx];
}
assert(is_valid_offset(f, z->start));
- zone_lock(td, z);
+ zone_lock(td, f, z);
if (z->open)
continue;
if (zbd_open_zone(td, io_u, zone_idx))
pthread_mutex_lock(&f->zbd_info->mutex);
for (i = 0; i < f->zbd_info->num_open_zones; i++) {
zone_idx = f->zbd_info->open_zones[i];
+ if (zone_idx < f->min_zone || zone_idx >= f->max_zone)
+ continue;
pthread_mutex_unlock(&f->zbd_info->mutex);
pthread_mutex_unlock(&z->mutex);
z = &f->zbd_info->zone_info[zone_idx];
- zone_lock(td, z);
+ zone_lock(td, f, z);
if (z->wp + min_bs <= (z+1)->start)
goto out;
pthread_mutex_lock(&f->zbd_info->mutex);
struct fio_zone_info *zb, struct fio_zone_info *zl)
{
const uint32_t min_bs = td->o.min_bs[io_u->ddir];
- const struct fio_file *f = io_u->file;
+ struct fio_file *f = io_u->file;
struct fio_zone_info *z1, *z2;
const struct fio_zone_info *const zf =
&f->zbd_info->zone_info[zbd_zone_idx(f, f->file_offset)];
*/
for (z1 = zb + 1, z2 = zb - 1; z1 < zl || z2 >= zf; z1++, z2--) {
if (z1 < zl && z1->cond != ZBD_ZONE_COND_OFFLINE) {
- zone_lock(td, z1);
+ zone_lock(td, f, z1);
if (z1->start + min_bs <= z1->wp)
return z1;
pthread_mutex_unlock(&z1->mutex);
}
if (td_random(td) && z2 >= zf &&
z2->cond != ZBD_ZONE_COND_OFFLINE) {
- zone_lock(td, z2);
+ zone_lock(td, f, z2);
if (z2->start + min_bs <= z2->wp)
return z2;
pthread_mutex_unlock(&z2->mutex);
zbd_check_swd(f);
- zone_lock(td, zb);
+ zone_lock(td, f, zb);
switch (io_u->ddir) {
case DDIR_READ: