diff --git a/cmd/zrepl/zrepl.c b/cmd/zrepl/zrepl.c index 80ddfa0f52e9..3f0e7ecbd6c4 100644 --- a/cmd/zrepl/zrepl.c +++ b/cmd/zrepl/zrepl.c @@ -130,7 +130,7 @@ open_zvol(int fd, zvol_info_t **zinfopp) thrd_arg = kmem_alloc(sizeof (thread_args_t), KM_SLEEP); thrd_arg->fd = fd; thrd_arg->zinfo = zinfo; - uzfs_zinfo_take_refcnt(zinfo, B_FALSE); + uzfs_zinfo_take_refcnt(zinfo); thrd_info = zk_thread_create(NULL, 0, (thread_func_t)uzfs_zvol_io_ack_sender, (void *)thrd_arg, 0, NULL, TS_RUN, 0, @@ -148,8 +148,9 @@ open_zvol(int fd, zvol_info_t **zinfopp) if (rc == -1) LOG_ERR("Failed to send reply for open request"); if (hdr.status != ZVOL_OP_STATUS_OK) { + ASSERT3P(*zinfopp, ==, NULL); if (zinfo != NULL) - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); return (-1); } return (rc); @@ -173,6 +174,9 @@ uzfs_zvol_io_receiver(void *arg) /* First command should be OPEN */ while (zinfo == NULL) { if (open_zvol(fd, &zinfo) != 0) { + if ((zinfo != NULL) && + (zinfo->is_io_ack_sender_created)) + goto exit; shutdown(fd, SHUT_RDWR); (void) close(fd); LOG_INFO("Data connection closed"); @@ -180,10 +184,13 @@ uzfs_zvol_io_receiver(void *arg) return; } } + LOG_INFO("Data connection associated with zvol %s", zinfo->name); while ((rc = uzfs_zvol_socket_read(fd, (char *)&hdr, sizeof (hdr))) == 0) { + if ((zinfo->state == ZVOL_INFO_STATE_OFFLINE)) + break; if (hdr.opcode != ZVOL_OPCODE_WRITE && hdr.opcode != ZVOL_OPCODE_READ && @@ -211,13 +218,17 @@ uzfs_zvol_io_receiver(void *arg) } } + if (zinfo->state == ZVOL_INFO_STATE_OFFLINE) { + zio_cmd_free(&zio_cmd); + break; + } /* Take refcount for uzfs_zvol_worker to work on it */ - uzfs_zinfo_take_refcnt(zinfo, B_FALSE); + uzfs_zinfo_take_refcnt(zinfo); zio_cmd->zv = zinfo; taskq_dispatch(zinfo->uzfs_zvol_taskq, uzfs_zvol_worker, zio_cmd, TQ_SLEEP); } - +exit: (void) pthread_mutex_lock(&zinfo->zinfo_mutex); zinfo->conn_closed = B_TRUE; /* @@ -237,7 +248,9 @@ uzfs_zvol_io_receiver(void *arg) (void) pthread_mutex_lock(&zinfo->zinfo_mutex); } (void) pthread_mutex_unlock(&zinfo->zinfo_mutex); - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + + close(fd); + uzfs_zinfo_drop_refcnt(zinfo); zk_thread_exit(); } @@ -331,6 +344,9 @@ uzfs_zvol_io_ack_sender(void *arg) while (1) { if ((zinfo->state == ZVOL_INFO_STATE_OFFLINE) || (zinfo->conn_closed == B_TRUE)) { + zinfo->is_io_ack_sender_created = B_FALSE; + (void) pthread_mutex_unlock( + &zinfo->zinfo_mutex); goto exit; } if (STAILQ_EMPTY(&zinfo->complete_queue)) { @@ -378,7 +394,6 @@ uzfs_zvol_io_ack_sender(void *arg) */ if (zio_cmd->conn == fd) { zio_cmd_free(&zio_cmd); - (void) pthread_mutex_lock(&zinfo->zinfo_mutex); goto exit; } zio_cmd_free(&zio_cmd); @@ -394,8 +409,6 @@ uzfs_zvol_io_ack_sender(void *arg) LOG_ERRNO("socket write err"); if (zio_cmd->conn == fd) { zio_cmd_free(&zio_cmd); - (void) pthread_mutex_lock( - &zinfo->zinfo_mutex); goto exit; } } @@ -413,16 +426,16 @@ uzfs_zvol_io_ack_sender(void *arg) exit: zinfo->zio_cmd_in_ack = NULL; shutdown(fd, SHUT_RDWR); - close(fd); LOG_INFO("Data connection for zvol %s closed", zinfo->name); + + (void) pthread_mutex_lock(&zinfo->zinfo_mutex); while (!STAILQ_EMPTY(&zinfo->complete_queue)) { zio_cmd = STAILQ_FIRST(&zinfo->complete_queue); STAILQ_REMOVE_HEAD(&zinfo->complete_queue, cmd_link); zio_cmd_free(&zio_cmd); } - zinfo->is_io_ack_sender_created = B_FALSE; (void) pthread_mutex_unlock(&zinfo->zinfo_mutex); - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); zk_thread_exit(); } diff --git a/include/zrepl_mgmt.h b/include/zrepl_mgmt.h index 1ea91675e691..b9bdda72f551 100644 --- a/include/zrepl_mgmt.h +++ b/include/zrepl_mgmt.h @@ -81,7 +81,7 @@ typedef struct zvol_info_s { zvol_info_state_t state; char name[MAXPATHLEN]; zvol_state_t *zv; - int refcnt; + uint64_t refcnt; int is_io_ack_sender_created; uint32_t timeout; /* iSCSI timeout val for this zvol */ uint64_t zvol_guid; @@ -153,8 +153,6 @@ typedef struct zvol_rebuild_s { extern int uzfs_zinfo_init(void *zv, const char *ds_name, nvlist_t *create_props); extern zvol_info_t *uzfs_zinfo_lookup(const char *name); -extern void uzfs_zinfo_drop_refcnt(zvol_info_t *zinfo, int locked); -extern void uzfs_zinfo_take_refcnt(zvol_info_t *zinfo, int locked); extern void uzfs_zinfo_replay_zil_all(void); extern int uzfs_zinfo_destroy(const char *ds_name, spa_t *spa); uint64_t uzfs_zvol_get_last_committed_io_no(zvol_state_t *zv); @@ -163,6 +161,25 @@ void uzfs_zvol_store_last_committed_io_no(zvol_state_t *zv, extern int create_and_bind(const char *port, int bind_needed, boolean_t nonblocking); +/* + * API to drop refcnt on zinfo. If refcnt + * dropped to zero then free zinfo. + */ +inline void +uzfs_zinfo_drop_refcnt(zvol_info_t *zinfo) +{ + atomic_dec_64(&zinfo->refcnt); +} + +/* + * API to take refcount on zinfo. + */ +inline void +uzfs_zinfo_take_refcnt(zvol_info_t *zinfo) +{ + atomic_inc_64(&zinfo->refcnt); +} + #ifdef __cplusplus } #endif diff --git a/lib/libzpool/uzfs_rebuilding.c b/lib/libzpool/uzfs_rebuilding.c index 4de3157121e8..f6fc801872a8 100644 --- a/lib/libzpool/uzfs_rebuilding.c +++ b/lib/libzpool/uzfs_rebuilding.c @@ -209,6 +209,8 @@ uzfs_get_io_diff(zvol_state_t *zv, blk_metadata_t *low, EXECUTE_DIFF_CALLBACK(last_lun_offset, diff_count, buf, last_index, arg, last_md, snap_zv, func, ret); + if (ret != 0) + break; last_lun_offset = lun_offset; last_md = (blk_metadata_t *)(buf+i); last_index = i; @@ -224,6 +226,8 @@ uzfs_get_io_diff(zvol_state_t *zv, blk_metadata_t *low, EXECUTE_DIFF_CALLBACK(last_lun_offset, diff_count, buf, last_index, arg, last_md, snap_zv, func, ret); + if (ret != 0) + break; } lun_offset += zv->zv_metavolblocksize; @@ -231,6 +235,8 @@ uzfs_get_io_diff(zvol_state_t *zv, blk_metadata_t *low, if (!ret && diff_count) { EXECUTE_DIFF_CALLBACK(last_lun_offset, diff_count, buf, last_index, arg, last_md, snap_zv, func, ret); + if (ret != 0) + break; } } diff --git a/lib/libzpool/zrepl_mgmt.c b/lib/libzpool/zrepl_mgmt.c index 7f5807d8ffb1..de4c4710e43e 100644 --- a/lib/libzpool/zrepl_mgmt.c +++ b/lib/libzpool/zrepl_mgmt.c @@ -119,58 +119,20 @@ create_and_bind(const char *port, int bind_needed, boolean_t nonblock) return (sfd); } -/* - * API to drop refcnt on zinfo. If refcnt - * dropped to zero then free zinfo. - */ -void -uzfs_zinfo_drop_refcnt(zvol_info_t *zinfo, int locked) -{ - if (!locked) { - (void) mutex_enter(&zvol_list_mutex); - } - - zinfo->refcnt--; - if (zinfo->refcnt == 0) { - (void) uzfs_zinfo_free(zinfo); - } - - if (!locked) { - (void) mutex_exit(&zvol_list_mutex); - } -} - -/* - * API to take refcount on zinfo. - */ -void -uzfs_zinfo_take_refcnt(zvol_info_t *zinfo, int locked) -{ - if (!locked) { - (void) mutex_enter(&zvol_list_mutex); - } - zinfo->refcnt++; - if (!locked) { - (void) mutex_exit(&zvol_list_mutex); - } -} - static void uzfs_insert_zinfo_list(zvol_info_t *zinfo) { LOG_INFO("Instantiating zvol %s", zinfo->name); /* Base refcount is taken here */ (void) mutex_enter(&zvol_list_mutex); - uzfs_zinfo_take_refcnt(zinfo, B_TRUE); + uzfs_zinfo_take_refcnt(zinfo); SLIST_INSERT_HEAD(&zvol_list, zinfo, zinfo_next); (void) mutex_exit(&zvol_list_mutex); } static void -uzfs_remove_zinfo_list(zvol_info_t *zinfo) +uzfs_mark_offline_and_free_zinfo(zvol_info_t *zinfo) { - LOG_INFO("Removing zvol %s", zinfo->name); - SLIST_REMOVE(&zvol_list, zinfo, zvol_info_s, zinfo_next); (void) pthread_mutex_lock(&zinfo->zinfo_mutex); zinfo->state = ZVOL_INFO_STATE_OFFLINE; /* Send signal to ack_sender thread about offline */ @@ -179,7 +141,17 @@ uzfs_remove_zinfo_list(zvol_info_t *zinfo) } (void) pthread_mutex_unlock(&zinfo->zinfo_mutex); /* Base refcount is droped here */ - uzfs_zinfo_drop_refcnt(zinfo, B_TRUE); + uzfs_zinfo_drop_refcnt(zinfo); + + /* Wait for refcounts to be drained */ + while (zinfo->refcnt > 0) { + LOG_DEBUG("Waiting for refcount to go down to" + " zero on zvol:%s", zinfo->name); + sleep(5); + } + + LOG_INFO("Freeing zvol %s", zinfo->name); + (void) uzfs_zinfo_free(zinfo); } zvol_info_t * @@ -216,7 +188,7 @@ uzfs_zinfo_lookup(const char *name) } if (zv != NULL) { /* Take refcount */ - uzfs_zinfo_take_refcnt(zv, B_TRUE); + uzfs_zinfo_take_refcnt(zv); } (void) mutex_exit(&zvol_list_mutex); @@ -254,9 +226,14 @@ uzfs_zinfo_destroy(const char *name, spa_t *spa) SLIST_FOREACH_SAFE(zinfo, &zvol_list, zinfo_next, zt) { if (strncmp(spa_name(spa), zinfo->name, strlen(spa_name(spa))) == 0) { + SLIST_REMOVE(&zvol_list, zinfo, zvol_info_s, + zinfo_next); + + mutex_exit(&zvol_list_mutex); zv = zinfo->zv; - uzfs_remove_zinfo_list(zinfo); + uzfs_mark_offline_and_free_zinfo(zinfo); uzfs_close_dataset(zv); + mutex_enter(&zvol_list_mutex); } } } else { @@ -265,9 +242,14 @@ uzfs_zinfo_destroy(const char *name, spa_t *spa) ((strncmp(zinfo->name, name, namelen) == 0) && zinfo->name[namelen] == '/' && zinfo->name[namelen + 1] == '\0')) { + SLIST_REMOVE(&zvol_list, zinfo, zvol_info_s, + zinfo_next); + + mutex_exit(&zvol_list_mutex); zv = zinfo->zv; - uzfs_remove_zinfo_list(zinfo); + uzfs_mark_offline_and_free_zinfo(zinfo); uzfs_close_dataset(zv); + mutex_enter(&zvol_list_mutex); break; } } diff --git a/lib/libzrepl/data_conn.c b/lib/libzrepl/data_conn.c index e7a2a97443e3..3ef0f9dc5883 100644 --- a/lib/libzrepl/data_conn.c +++ b/lib/libzrepl/data_conn.c @@ -259,6 +259,15 @@ uzfs_zvol_worker(void *arg) rebuild_cmd_req = hdr->flags & ZVOL_OP_FLAG_REBUILD; read_metadata = hdr->flags & ZVOL_OP_FLAG_READ_METADATA; + /* + * Why to delay offline activity ? anyway + * we are not going to ACK these IOs + */ + if (zinfo->state == ZVOL_INFO_STATE_OFFLINE) { + zio_cmd_free(&zio_cmd); + goto drop_refcount; + } + /* * If zvol hasn't passed rebuild phase or if read * is meant for rebuild or if target has asked for metadata @@ -326,7 +335,7 @@ uzfs_zvol_worker(void *arg) (void) pthread_mutex_unlock(&zinfo->zinfo_mutex); drop_refcount: - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); } void @@ -467,7 +476,7 @@ uzfs_zvol_rebuild_dw_replica(void *arg) * Take refcount for uzfs_zvol_worker to work on it. * Will dropped by uzfs_zvol_worker once cmd is executed. */ - uzfs_zinfo_take_refcnt(zinfo, B_FALSE); + uzfs_zinfo_take_refcnt(zinfo); zio_cmd->zv = zinfo; uzfs_zvol_worker(zio_cmd); if (zio_cmd->hdr.status != ZVOL_OP_STATUS_OK) { @@ -511,7 +520,7 @@ uzfs_zvol_rebuild_dw_replica(void *arg) close(sfd); } /* Parent thread have taken refcount, drop it now */ - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); zk_thread_exit(); } @@ -828,10 +837,13 @@ uzfs_zvol_rebuild_scanner_callback(off_t offset, size_t len, hdr.len = len; hdr.flags = ZVOL_OP_FLAG_REBUILD; hdr.status = ZVOL_OP_STATUS_OK; + if (zinfo->state == ZVOL_INFO_STATE_OFFLINE) + return (-1); + LOG_DEBUG("IO number for rebuild %ld", metadata->io_num); zio_cmd = zio_cmd_alloc(&hdr, warg->fd); /* Take refcount for uzfs_zvol_worker to work on it */ - uzfs_zinfo_take_refcnt(zinfo, B_FALSE); + uzfs_zinfo_take_refcnt(zinfo); zio_cmd->zv = zinfo; /* @@ -869,10 +881,9 @@ uzfs_zvol_rebuild_scanner(void *arg) } read_socket: rc = uzfs_zvol_read_header(fd, &hdr); - if (rc != 0) { - LOG_DEBUG("Error:%d in reading header\n", errno); + if ((rc != 0) || ((zinfo != NULL) && + (zinfo->state == ZVOL_INFO_STATE_OFFLINE))) goto exit; - } LOG_DEBUG("op_code=%d io_seq=%ld", hdr.opcode, hdr.io_seq); @@ -941,7 +952,7 @@ uzfs_zvol_rebuild_scanner(void *arg) hdr.opcode = ZVOL_OPCODE_REBUILD_STEP_DONE; zio_cmd = zio_cmd_alloc(&hdr, fd); /* Take refcount for uzfs_zvol_worker to work on it */ - uzfs_zinfo_take_refcnt(zinfo, B_FALSE); + uzfs_zinfo_take_refcnt(zinfo); zio_cmd->zv = zinfo; uzfs_zvol_worker(zio_cmd); zio_cmd = NULL; @@ -961,7 +972,7 @@ uzfs_zvol_rebuild_scanner(void *arg) if (zinfo != NULL) { LOG_INFO("Closing rebuild connection for zvol %s", zinfo->name); remove_pending_cmds_to_ack(fd, zinfo); - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); } else { LOG_INFO("Closing rebuild connection"); } diff --git a/lib/libzrepl/mgmt_conn.c b/lib/libzrepl/mgmt_conn.c index 9a293aedd3e7..4d28aa4bd159 100644 --- a/lib/libzrepl/mgmt_conn.c +++ b/lib/libzrepl/mgmt_conn.c @@ -559,7 +559,7 @@ static void free_async_task(async_task_t *async_task) { ASSERT(MUTEX_HELD(&async_tasks_mtx)); - uzfs_zinfo_drop_refcnt(async_task->zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(async_task->zinfo); kmem_free(async_task->payload, async_task->payload_length); kmem_free(async_task, sizeof (*async_task)); } @@ -755,7 +755,7 @@ uzfs_zvol_rebuild_dw_replica_start(uzfs_mgmt_conn_t *conn, zvol_io_hdr_t *hdrp, goto ret_error; } - uzfs_zinfo_take_refcnt(zinfo, B_FALSE); + uzfs_zinfo_take_refcnt(zinfo); thrd_arg = kmem_alloc(sizeof (rebuild_thread_arg_t), KM_SLEEP); thrd_arg->zinfo = zinfo; @@ -801,7 +801,7 @@ handle_start_rebuild_req(uzfs_mgmt_conn_t *conn, zvol_io_hdr_t *hdrp, (zinfo->zv == NULL)) { if (zinfo != NULL) { LOG_ERR("rebuilding failed for %s..", zinfo->name); - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); } else LOG_ERR("rebuilding failed.."); @@ -815,7 +815,7 @@ handle_start_rebuild_req(uzfs_mgmt_conn_t *conn, zvol_io_hdr_t *hdrp, if (uzfs_zvol_get_rebuild_status(zinfo->zv) != ZVOL_REBUILDING_INIT) { mutex_exit(&zinfo->zv->rebuild_mtx); - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); LOG_ERR("rebuilding failed for %s due to improper rebuild " "status", zinfo->name); rc = reply_nodata(conn, ZVOL_OP_STATUS_FAILED, @@ -842,7 +842,7 @@ handle_start_rebuild_req(uzfs_mgmt_conn_t *conn, zvol_io_hdr_t *hdrp, uzfs_update_ionum_interval(zinfo, 0); LOG_INFO("Rebuild of zvol %s completed", zinfo->name); - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); rc = reply_nodata(conn, ZVOL_OP_STATUS_OK, hdrp->opcode, hdrp->io_seq); goto end; @@ -857,7 +857,7 @@ handle_start_rebuild_req(uzfs_mgmt_conn_t *conn, zvol_io_hdr_t *hdrp, zinfo, rebuild_op_cnt); /* dropping refcount for uzfs_zinfo_lookup */ - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); end: return (rc); } @@ -907,7 +907,7 @@ process_message(uzfs_mgmt_conn_t *conn) * from that case would not be trivial so we pretend a miss. */ if (zinfo->mgmt_conn != conn) { - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); LOGERRCONN(conn, "Target used invalid connection for " "zvol %s", zvol_name); rc = reply_nodata(conn, ZVOL_OP_STATUS_FAILED, @@ -936,7 +936,7 @@ process_message(uzfs_mgmt_conn_t *conn) } else { ASSERT(0); } - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); break; case ZVOL_OPCODE_SNAP_CREATE: @@ -965,7 +965,7 @@ process_message(uzfs_mgmt_conn_t *conn) break; } if (zinfo->mgmt_conn != conn) { - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); LOGERRCONN(conn, "Target used invalid connection for " "zvol %s", zvol_name); rc = reply_nodata(conn, ZVOL_OP_STATUS_FAILED, @@ -999,7 +999,7 @@ process_message(uzfs_mgmt_conn_t *conn) break; } if (zinfo->mgmt_conn != conn) { - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); LOGERRCONN(conn, "Target used invalid connection for " "zvol %s", zvol_name); rc = reply_nodata(conn, ZVOL_OP_STATUS_FAILED, diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c index e762c19f2785..09895d0c9390 100644 --- a/module/zfs/zvol.c +++ b/module/zfs/zvol.c @@ -515,7 +515,7 @@ zvol_set_volsize(const char *name, uint64_t volsize) } #if !defined(_KERNEL) - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); #else if (zv != NULL) mutex_exit(&zv->zv_state_lock); diff --git a/tests/cbtest/gtest/test_uzfs.cc b/tests/cbtest/gtest/test_uzfs.cc index 363d1d24b809..b2c13d22ede8 100644 --- a/tests/cbtest/gtest/test_uzfs.cc +++ b/tests/cbtest/gtest/test_uzfs.cc @@ -309,7 +309,7 @@ test_alloc_async_task_and_add_to_list(zvol_info_t *zinfo, { async_task_t *arg; - uzfs_zinfo_take_refcnt(zinfo, B_TRUE); + uzfs_zinfo_take_refcnt(zinfo); arg = (async_task_t *)kmem_zalloc(sizeof (async_task_t), KM_SLEEP); arg->conn = conn; arg->zinfo = zinfo; @@ -411,7 +411,7 @@ TEST(uZFS, TestZInfoRefcnt) { EXPECT_EQ(2, zinfo->refcnt); - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); EXPECT_EQ(1, zinfo->refcnt); GtestUtils::strlcpy(ds1, "vol1 ", MAXNAMELEN); @@ -451,7 +451,7 @@ TEST(uZFS, TestZInfoRefcnt) { EXPECT_EQ(NULL, !zinfo1); EXPECT_EQ(3, zinfo->refcnt); - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); EXPECT_EQ(2, zinfo->refcnt); } @@ -934,7 +934,7 @@ uzfs_mock_zvol_rebuild_dw_replica(void *arg) * Take refcount for uzfs_zvol_worker to work on it. * Will dropped by uzfs_zvol_worker once cmd is executed. */ - uzfs_zinfo_take_refcnt(zinfo, B_FALSE); + uzfs_zinfo_take_refcnt(zinfo); zio_cmd->zv = zinfo; uzfs_zvol_worker(zio_cmd); if (zio_cmd->hdr.status != ZVOL_OP_STATUS_OK) { @@ -978,7 +978,7 @@ uzfs_mock_zvol_rebuild_dw_replica(void *arg) close(sfd); } /* Parent thread have taken refcount, drop it now */ - uzfs_zinfo_drop_refcnt(zinfo, B_FALSE); + uzfs_zinfo_drop_refcnt(zinfo); rebuild_test_case = 0; zk_thread_exit(); @@ -996,7 +996,7 @@ void execute_rebuild_test_case(const char *s, int test_case, zinfo->zv->zv_status = ZVOL_STATUS_DEGRADED; memset(&zinfo->zv->rebuild_info, 0, sizeof (zvol_rebuild_info_t)); zinfo->zv->rebuild_info.rebuild_cnt = 1; - uzfs_zinfo_take_refcnt(zinfo, B_FALSE); + uzfs_zinfo_take_refcnt(zinfo); uzfs_zvol_set_rebuild_status(zinfo->zv, status); if (!is_rebuild_scanner)