zbd: handle conventional start zone in zbd_convert_to_open_zone()
authorDmitry Fomichev <dmitry.fomichev@wdc.com>
Wed, 27 Jan 2021 04:19:25 +0000 (13:19 +0900)
committerJens Axboe <axboe@kernel.dk>
Fri, 29 Jan 2021 15:14:00 +0000 (08:14 -0700)
At the beginning of zbd_convert_to_open_zone() function, a zone
is picked in semi-random manner to become a candidate zone for
redirecting the incoming write. In some circumstances, such as
unlimited MaxOpen or i/o range that spans the boundary between
conventional and sequential zones, a conventional zone may be
selected.

This may create problems in the subsequent for (;;) loop in the
same function. Failed assertions were observed during the execution
of newly introduced test #51 that showed that the code in that loop
was trying to lock and unlock conventional zones.

Check if the zone which has been initially picked is conventional.
If yes, force the zone selection to be re-tried until a sequential
zone is selected for further processing.

Signed-off-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
Reviewed-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
zbd.c

diff --git a/zbd.c b/zbd.c
index 634ee8f6289ba260232ce1d738357cab92551365..44ecb9e0b8c99b81ecc1bf2c817b6bf0ffd8613a 100644 (file)
--- a/zbd.c
+++ b/zbd.c
@@ -1087,16 +1087,18 @@ static struct fio_zone_info *zbd_convert_to_open_zone(struct thread_data *td,
                uint32_t tmp_idx;
 
                z = get_zone(f, zone_idx);
-
-               zone_lock(td, f, z);
+               if (z->has_wp)
+                       zone_lock(td, f, z);
                pthread_mutex_lock(&f->zbd_info->mutex);
-               if (z->cond != ZBD_ZONE_COND_OFFLINE &&
-                   td->o.max_open_zones == 0 && td->o.job_max_open_zones == 0)
-                       goto examine_zone;
-               if (f->zbd_info->num_open_zones == 0) {
-                       dprint(FD_ZBD, "%s(%s): no zones are open\n",
-                              __func__, f->file_name);
-                       goto open_other_zone;
+               if (z->has_wp) {
+                       if (z->cond != ZBD_ZONE_COND_OFFLINE &&
+                           td->o.max_open_zones == 0 && td->o.job_max_open_zones == 0)
+                               goto examine_zone;
+                       if (f->zbd_info->num_open_zones == 0) {
+                               dprint(FD_ZBD, "%s(%s): no zones are open\n",
+                                      __func__, f->file_name);
+                               goto open_other_zone;
+                       }
                }
 
                /*
@@ -1124,7 +1126,8 @@ static struct fio_zone_info *zbd_convert_to_open_zone(struct thread_data *td,
                dprint(FD_ZBD, "%s(%s): no candidate zone\n",
                        __func__, f->file_name);
                pthread_mutex_unlock(&f->zbd_info->mutex);
-               zone_unlock(z);
+               if (z->has_wp)
+                       zone_unlock(z);
                return NULL;
 
 found_candidate_zone:
@@ -1133,7 +1136,8 @@ found_candidate_zone:
                        break;
                zone_idx = new_zone_idx;
                pthread_mutex_unlock(&f->zbd_info->mutex);
-               zone_unlock(z);
+               if (z->has_wp)
+                       zone_unlock(z);
        }
 
        /* Both z->mutex and f->zbd_info->mutex are held. */