Lines Matching +full:write +full:- +full:1 +full:- +full:bps

1 // SPDX-License-Identifier: CDDL-1.0
10 * or https://opensource.org/licenses/CDDL-1.0.
23 * Copyright (C) 2008-2010 Lawrence Livermore National Security, LLC.
26 * LLNL-CODE-403049.
48 * (DMU_OST_ZVOL) and the device "minor" (some OS-specific representation of a
53 * It should not be used for anything not name-relateds, and you should avoid
60 * read, write, flush) so this lock is rarely taken during general IO. It
65 * half should held for the duration of an IO operation. The write half should
71 * - take zvol_state_lock if necessary, to protect zvol_state_list
72 * - take zv_suspend_lock if necessary, by the code path in question
73 * - take zv_state_lock to protect zvol_state_t
75 * The minor operations are issued to spa->spa_zvol_taskq queues, that are
76 * single-threaded (to preserve order of minor operations), and are executed
139 taskq_init_ent(&task->ent); in zv_request_task_create()
140 task->zvr = zvr; in zv_request_task_create()
153 uint64_t crc = -1ULL; in zvol_name_hash()
176 mutex_enter(&zv->zv_state_lock); in zvol_find_by_name_hash()
177 if (zv->zv_hash == hash && strcmp(zv->zv_name, name) == 0) { in zvol_find_by_name_hash()
183 !rw_tryenter(&zv->zv_suspend_lock, mode)) { in zvol_find_by_name_hash()
184 mutex_exit(&zv->zv_state_lock); in zvol_find_by_name_hash()
185 rw_enter(&zv->zv_suspend_lock, mode); in zvol_find_by_name_hash()
186 mutex_enter(&zv->zv_state_lock); in zvol_find_by_name_hash()
191 ASSERT(zv->zv_hash == hash && in zvol_find_by_name_hash()
192 strcmp(zv->zv_name, name) == 0); in zvol_find_by_name_hash()
197 mutex_exit(&zv->zv_state_lock); in zvol_find_by_name_hash()
224 nvlist_t *nvprops = zct->zct_props; in zvol_create_cb()
250 error = zap_update(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize, tx); in zvol_create_cb()
264 error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &val); in zvol_get_stats()
274 doi->doi_data_block_size); in zvol_get_stats()
295 if (volsize - 1 > SPEC_MAXOFFSET_T) in zvol_check_volsize()
321 error = zap_update(os, ZVOL_ZAP_OBJ, "size", 8, 1, in zvol_update_volsize()
355 ASSERT(zv == NULL || (MUTEX_HELD(&zv->zv_state_lock) && in zvol_set_volsize()
356 RW_READ_HELD(&zv->zv_suspend_lock))); in zvol_set_volsize()
358 if (zv == NULL || zv->zv_objset == NULL) { in zvol_set_volsize()
360 rw_exit(&zv->zv_suspend_lock); in zvol_set_volsize()
364 mutex_exit(&zv->zv_state_lock); in zvol_set_volsize()
369 zv->zv_objset = os; in zvol_set_volsize()
371 os = zv->zv_objset; in zvol_set_volsize()
377 (error = zvol_check_volsize(volsize, doi->doi_data_block_size))) in zvol_set_volsize()
382 zv->zv_volsize = volsize; in zvol_set_volsize()
383 zv->zv_changed = 1; in zvol_set_volsize()
391 zv->zv_objset = NULL; in zvol_set_volsize()
393 rw_exit(&zv->zv_suspend_lock); in zvol_set_volsize()
397 mutex_exit(&zv->zv_state_lock); in zvol_set_volsize()
414 zv->zv_threading = value; in zvol_set_volthreading()
415 mutex_exit(&zv->zv_state_lock); in zvol_set_volthreading()
427 return (-1); in zvol_set_ro()
429 zvol_os_set_disk_ro(zv, 1); in zvol_set_ro()
430 zv->zv_flags |= ZVOL_RDONLY; in zvol_set_ro()
433 zv->zv_flags &= ~ZVOL_RDONLY; in zvol_set_ro()
435 mutex_exit(&zv->zv_state_lock); in zvol_set_ro()
459 * We don't allow setting the property above 1MB, in zvol_check_volblocksize()
480 * implement DKIOCFREE/free-long-range.
489 ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr)); in zvol_replay_truncate()
494 offset = lr->lr_offset; in zvol_replay_truncate()
495 length = lr->lr_length; in zvol_replay_truncate()
497 dmu_tx_t *tx = dmu_tx_create(zv->zv_objset); in zvol_replay_truncate()
503 (void) zil_replaying(zv->zv_zilog, tx); in zvol_replay_truncate()
505 error = dmu_free_long_range(zv->zv_objset, ZVOL_OBJ, offset, in zvol_replay_truncate()
521 objset_t *os = zv->zv_objset; in zvol_replay_write()
522 char *data = (char *)(lr + 1); /* data follows lr_write_t */ in zvol_replay_write()
527 ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr)); in zvol_replay_write()
532 offset = lr->lr_offset; in zvol_replay_write()
533 length = lr->lr_length; in zvol_replay_write()
535 /* If it's a dmu_sync() block, write the whole block */ in zvol_replay_write()
536 if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) { in zvol_replay_write()
537 uint64_t blocksize = BP_GET_LSIZE(&lr->lr_blkptr); in zvol_replay_write()
539 offset -= offset % blocksize; in zvol_replay_write()
551 (void) zil_replaying(zv->zv_zilog, tx); in zvol_replay_write()
567 objset_t *os = zv->zv_objset; in zvol_replay_clone_range()
574 ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr)); in zvol_replay_clone_range()
575 ASSERT3U(lr->lr_common.lrc_reclen, >=, offsetof(lr_clone_range_t, in zvol_replay_clone_range()
576 lr_bps[lr->lr_nbps])); in zvol_replay_clone_range()
584 off = lr->lr_offset; in zvol_replay_clone_range()
585 len = lr->lr_length; in zvol_replay_clone_range()
586 blksz = lr->lr_blksz; in zvol_replay_clone_range()
592 error = dnode_hold(os, ZVOL_OBJ, zv, &zv->zv_dn); in zvol_replay_clone_range()
593 if (error != 0 || !zv->zv_dn) in zvol_replay_clone_range()
596 dmu_tx_hold_clone_by_dnode(tx, zv->zv_dn, off, len, blksz); in zvol_replay_clone_range()
602 error = dmu_brt_clone(zv->zv_objset, ZVOL_OBJ, off, len, in zvol_replay_clone_range()
603 tx, lr->lr_bps, lr->lr_nbps); in zvol_replay_clone_range()
613 VERIFY(zil_replaying(zv->zv_zilog, tx)); in zvol_replay_clone_range()
617 dnode_rele(zv->zv_dn, zv); in zvol_replay_clone_range()
618 zv->zv_dn = NULL; in zvol_replay_clone_range()
630 blkptr_t *bps; in zvol_clone_range() local
634 rw_enter(&zv_dst->zv_suspend_lock, RW_READER); in zvol_clone_range()
635 if (zv_dst->zv_zilog == NULL) { in zvol_clone_range()
636 rw_exit(&zv_dst->zv_suspend_lock); in zvol_clone_range()
637 rw_enter(&zv_dst->zv_suspend_lock, RW_WRITER); in zvol_clone_range()
638 if (zv_dst->zv_zilog == NULL) { in zvol_clone_range()
639 zv_dst->zv_zilog = zil_open(zv_dst->zv_objset, in zvol_clone_range()
640 zvol_get_data, &zv_dst->zv_kstat.dk_zil_sums); in zvol_clone_range()
641 zv_dst->zv_flags |= ZVOL_WRITTEN_TO; in zvol_clone_range()
642 VERIFY0((zv_dst->zv_zilog->zl_header->zh_flags & in zvol_clone_range()
645 rw_downgrade(&zv_dst->zv_suspend_lock); in zvol_clone_range()
648 rw_enter(&zv_src->zv_suspend_lock, RW_READER); in zvol_clone_range()
650 inos = zv_src->zv_objset; in zvol_clone_range()
651 outos = zv_dst->zv_objset; in zvol_clone_range()
665 if (inos->os_encrypted != outos->os_encrypted) { in zvol_clone_range()
669 if (zv_src->zv_volblocksize != zv_dst->zv_volblocksize) { in zvol_clone_range()
673 if (inoff >= zv_src->zv_volsize || outoff >= zv_dst->zv_volsize) { in zvol_clone_range()
680 if (len > zv_src->zv_volsize - inoff) in zvol_clone_range()
681 len = zv_src->zv_volsize - inoff; in zvol_clone_range()
682 if (len > zv_dst->zv_volsize - outoff) in zvol_clone_range()
683 len = zv_dst->zv_volsize - outoff; in zvol_clone_range()
700 if ((inoff % zv_src->zv_volblocksize) != 0 || in zvol_clone_range()
701 (outoff % zv_dst->zv_volblocksize) != 0) { in zvol_clone_range()
709 if ((len % zv_src->zv_volblocksize) != 0) { in zvol_clone_range()
714 zilog_dst = zv_dst->zv_zilog; in zvol_clone_range()
716 sizeof (bps[0]); in zvol_clone_range()
717 bps = vmem_alloc(sizeof (bps[0]) * maxblocks, KM_SLEEP); in zvol_clone_range()
722 inlr = zfs_rangelock_enter(&zv_src->zv_rangelock, inoff, len, in zvol_clone_range()
724 outlr = zfs_rangelock_enter(&zv_dst->zv_rangelock, outoff, len, in zvol_clone_range()
727 outlr = zfs_rangelock_enter(&zv_dst->zv_rangelock, outoff, len, in zvol_clone_range()
729 inlr = zfs_rangelock_enter(&zv_src->zv_rangelock, inoff, len, in zvol_clone_range()
736 size = MIN(zv_src->zv_volblocksize * maxblocks, len); in zvol_clone_range()
738 dmu_objset_spa(zv_src->zv_objset)); in zvol_clone_range()
739 error = dmu_read_l0_bps(zv_src->zv_objset, ZVOL_OBJ, inoff, in zvol_clone_range()
740 size, bps, &nbps); in zvol_clone_range()
751 (zv_src->zv_objset), last_synced_txg + 1); in zvol_clone_range()
757 tx = dmu_tx_create(zv_dst->zv_objset); in zvol_clone_range()
758 dmu_tx_hold_clone_by_dnode(tx, zv_dst->zv_dn, outoff, size, in zvol_clone_range()
759 zv_src->zv_volblocksize); in zvol_clone_range()
765 error = dmu_brt_clone(zv_dst->zv_objset, ZVOL_OBJ, outoff, size, in zvol_clone_range()
766 tx, bps, nbps); in zvol_clone_range()
772 size, zv_src->zv_volblocksize, bps, nbps); in zvol_clone_range()
776 len -= size; in zvol_clone_range()
778 vmem_free(bps, sizeof (bps[0]) * maxblocks); in zvol_clone_range()
781 if (error == 0 && zv_dst->zv_objset->os_sync == ZFS_SYNC_ALWAYS) { in zvol_clone_range()
786 rw_exit(&zv_src->zv_suspend_lock); in zvol_clone_range()
787 rw_exit(&zv_dst->zv_suspend_lock); in zvol_clone_range()
796 uint64_t len, uint64_t blksz, const blkptr_t *bps, size_t nbps) in zvol_log_clone_range() argument
809 partnbps = MIN(nbps, max_log_data / sizeof (bps[0])); in zvol_log_clone_range()
815 sizeof (*lr) + sizeof (bps[0]) * partnbps); in zvol_log_clone_range()
816 lr = (lr_clone_range_t *)&itx->itx_lr; in zvol_log_clone_range()
817 lr->lr_foid = ZVOL_OBJ; in zvol_log_clone_range()
818 lr->lr_offset = off; in zvol_log_clone_range()
819 lr->lr_length = partlen; in zvol_log_clone_range()
820 lr->lr_blksz = blksz; in zvol_log_clone_range()
821 lr->lr_nbps = partnbps; in zvol_log_clone_range()
822 memcpy(lr->lr_bps, bps, sizeof (bps[0]) * partnbps); in zvol_log_clone_range()
826 bps += partnbps; in zvol_log_clone_range()
828 nbps -= partnbps; in zvol_log_clone_range()
831 len -= partlen; in zvol_log_clone_range()
881 uint32_t blocksize = zv->zv_volblocksize; in zvol_log_write()
882 zilog_t *zilog = zv->zv_zilog; in zvol_log_write()
900 len = MIN(blocksize - P2PHASE(offset, blocksize), size); in zvol_log_write()
904 lr = (lr_write_t *)&itx->itx_lr; in zvol_log_write()
906 dmu_read_by_dnode(zv->zv_dn, offset, len, lr + 1, in zvol_log_write()
910 lr = (lr_write_t *)&itx->itx_lr; in zvol_log_write()
914 log_size += itx->itx_size; in zvol_log_write()
918 itx->itx_wr_state = wr_state; in zvol_log_write()
919 lr->lr_foid = ZVOL_OBJ; in zvol_log_write()
920 lr->lr_offset = offset; in zvol_log_write()
921 lr->lr_length = len; in zvol_log_write()
922 lr->lr_blkoff = 0; in zvol_log_write()
923 BP_ZERO(&lr->lr_blkptr); in zvol_log_write()
925 itx->itx_private = zv; in zvol_log_write()
930 size -= len; in zvol_log_write()
933 dsl_pool_wrlog_count(zilog->zl_dmu_pool, log_size, tx->tx_txg); in zvol_log_write()
937 * Log a DKIOCFREE/free-long-range to the ZIL with TX_TRUNCATE.
944 zilog_t *zilog = zv->zv_zilog; in zvol_log_truncate()
950 lr = (lr_truncate_t *)&itx->itx_lr; in zvol_log_truncate()
951 lr->lr_foid = ZVOL_OBJ; in zvol_log_truncate()
952 lr->lr_offset = off; in zvol_log_truncate()
953 lr->lr_length = len; in zvol_log_truncate()
963 if (zgd->zgd_db) in zvol_get_done()
964 dmu_buf_rele(zgd->zgd_db, zgd); in zvol_get_done()
966 zfs_rangelock_exit(zgd->zgd_lr); in zvol_get_done()
979 uint64_t offset = lr->lr_offset; in zvol_get_data()
980 uint64_t size = lr->lr_length; in zvol_get_data()
989 zgd->zgd_lwb = lwb; in zvol_get_data()
992 * Write records come in two flavors: immediate and indirect. in zvol_get_data()
996 * we don't have to write the data twice. in zvol_get_data()
998 if (buf != NULL) { /* immediate write */ in zvol_get_data()
999 zgd->zgd_lr = zfs_rangelock_enter(&zv->zv_rangelock, offset, in zvol_get_data()
1001 error = dmu_read_by_dnode(zv->zv_dn, offset, size, buf, in zvol_get_data()
1003 } else { /* indirect write */ in zvol_get_data()
1008 * the data. Contrarily to zfs_get_data we need not re-check in zvol_get_data()
1011 size = zv->zv_volblocksize; in zvol_get_data()
1013 zgd->zgd_lr = zfs_rangelock_enter(&zv->zv_rangelock, offset, in zvol_get_data()
1015 error = dmu_buf_hold_noread_by_dnode(zv->zv_dn, offset, zgd, in zvol_get_data()
1018 blkptr_t *bp = &lr->lr_blkptr; in zvol_get_data()
1020 zgd->zgd_db = db; in zvol_get_data()
1021 zgd->zgd_bp = bp; in zvol_get_data()
1024 ASSERT(db->db_offset == offset); in zvol_get_data()
1025 ASSERT(db->db_size == size); in zvol_get_data()
1027 error = dmu_sync(zio, lr->lr_common.lrc_txg, in zvol_get_data()
1049 hlist_add_head(&zv->zv_hlink, ZVOL_HT_HEAD(zv->zv_hash)); in zvol_insert()
1060 hlist_del(&zv->zv_hlink); in zvol_remove()
1064 * Setup zv after we just own the zv->objset
1072 objset_t *os = zv->zv_objset; in zvol_setup_zv()
1074 ASSERT(MUTEX_HELD(&zv->zv_state_lock)); in zvol_setup_zv()
1075 ASSERT(RW_LOCK_HELD(&zv->zv_suspend_lock)); in zvol_setup_zv()
1077 zv->zv_zilog = NULL; in zvol_setup_zv()
1078 zv->zv_flags &= ~ZVOL_WRITTEN_TO; in zvol_setup_zv()
1080 error = dsl_prop_get_integer(zv->zv_name, "readonly", &ro, NULL); in zvol_setup_zv()
1084 error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize); in zvol_setup_zv()
1088 error = dnode_hold(os, ZVOL_OBJ, zv, &zv->zv_dn); in zvol_setup_zv()
1093 zv->zv_volsize = volsize; in zvol_setup_zv()
1097 zvol_os_set_disk_ro(zv, 1); in zvol_setup_zv()
1098 zv->zv_flags |= ZVOL_RDONLY; in zvol_setup_zv()
1101 zv->zv_flags &= ~ZVOL_RDONLY; in zvol_setup_zv()
1113 ASSERT(MUTEX_HELD(&zv->zv_state_lock) && in zvol_shutdown_zv()
1114 RW_LOCK_HELD(&zv->zv_suspend_lock)); in zvol_shutdown_zv()
1116 if (zv->zv_flags & ZVOL_WRITTEN_TO) { in zvol_shutdown_zv()
1117 ASSERT(zv->zv_zilog != NULL); in zvol_shutdown_zv()
1118 zil_close(zv->zv_zilog); in zvol_shutdown_zv()
1121 zv->zv_zilog = NULL; in zvol_shutdown_zv()
1123 dnode_rele(zv->zv_dn, zv); in zvol_shutdown_zv()
1124 zv->zv_dn = NULL; in zvol_shutdown_zv()
1127 * Evict cached data. We must write out any dirty data before in zvol_shutdown_zv()
1130 if (zv->zv_flags & ZVOL_WRITTEN_TO) in zvol_shutdown_zv()
1131 txg_wait_synced(dmu_objset_pool(zv->zv_objset), 0); in zvol_shutdown_zv()
1132 dmu_objset_evict_dbufs(zv->zv_objset); in zvol_shutdown_zv()
1141 ASSERT(RW_WRITE_HELD(&zv->zv_suspend_lock)); in zvol_tag()
1142 return (zv->zv_open_count > 0 ? zv : NULL); in zvol_tag()
1159 ASSERT(MUTEX_HELD(&zv->zv_state_lock)); in zvol_suspend()
1160 ASSERT(RW_WRITE_HELD(&zv->zv_suspend_lock)); in zvol_suspend()
1169 if (zv->zv_flags & ZVOL_REMOVING) { in zvol_suspend()
1170 mutex_exit(&zv->zv_state_lock); in zvol_suspend()
1171 rw_exit(&zv->zv_suspend_lock); in zvol_suspend()
1176 atomic_inc(&zv->zv_suspend_ref); in zvol_suspend()
1178 if (zv->zv_open_count > 0) in zvol_suspend()
1185 mutex_exit(&zv->zv_state_lock); in zvol_suspend()
1197 ASSERT(RW_WRITE_HELD(&zv->zv_suspend_lock)); in zvol_resume()
1199 mutex_enter(&zv->zv_state_lock); in zvol_resume()
1201 if (zv->zv_open_count > 0) { in zvol_resume()
1202 VERIFY0(dmu_objset_hold(zv->zv_name, zv, &zv->zv_objset)); in zvol_resume()
1203 VERIFY3P(zv->zv_objset->os_dsl_dataset->ds_owner, ==, zv); in zvol_resume()
1204 VERIFY(dsl_dataset_long_held(zv->zv_objset->os_dsl_dataset)); in zvol_resume()
1205 dmu_objset_rele(zv->zv_objset, zv); in zvol_resume()
1210 mutex_exit(&zv->zv_state_lock); in zvol_resume()
1212 rw_exit(&zv->zv_suspend_lock); in zvol_resume()
1219 atomic_dec(&zv->zv_suspend_ref); in zvol_resume()
1221 if (zv->zv_flags & ZVOL_REMOVING) in zvol_resume()
1222 cv_broadcast(&zv->zv_removing_cv); in zvol_resume()
1233 ASSERT(RW_READ_HELD(&zv->zv_suspend_lock)); in zvol_first_open()
1234 ASSERT(MUTEX_HELD(&zv->zv_state_lock)); in zvol_first_open()
1237 boolean_t ro = (readonly || (strchr(zv->zv_name, '@') != NULL)); in zvol_first_open()
1238 error = dmu_objset_own(zv->zv_name, DMU_OST_ZVOL, ro, B_TRUE, zv, &os); in zvol_first_open()
1242 zv->zv_objset = os; in zvol_first_open()
1246 dmu_objset_disown(os, 1, zv); in zvol_first_open()
1247 zv->zv_objset = NULL; in zvol_first_open()
1256 ASSERT(RW_READ_HELD(&zv->zv_suspend_lock)); in zvol_last_close()
1257 ASSERT(MUTEX_HELD(&zv->zv_state_lock)); in zvol_last_close()
1259 if (zv->zv_flags & ZVOL_REMOVING) in zvol_last_close()
1260 cv_broadcast(&zv->zv_removing_cv); in zvol_last_close()
1264 dmu_objset_disown(zv->zv_objset, 1, zv); in zvol_last_close()
1265 zv->zv_objset = NULL; in zvol_last_close()
1284 char *dsname = job->name; in zvol_prefetch_minors_impl()
1287 job->error = dmu_objset_own(dsname, DMU_OST_ZVOL, B_TRUE, B_TRUE, in zvol_prefetch_minors_impl()
1289 if (job->error == 0) { in zvol_prefetch_minors_impl()
1302 list_t *minors_list = j->list; in zvol_create_snap_minor_cb()
1303 const char *name = j->name; in zvol_create_snap_minor_cb()
1322 job->name = n; in zvol_create_snap_minor_cb()
1323 job->list = minors_list; in zvol_create_snap_minor_cb()
1324 job->error = 0; in zvol_create_snap_minor_cb()
1326 /* don't care if dispatch fails, because job->error is 0 */ in zvol_create_snap_minor_cb()
1337 * is "best effort" - so we just skip over it if there are failures.
1349 if (!spa_feature_is_enabled(dp->dp_spa, in zvol_add_clones()
1356 if (dsl_dir_phys(dd)->dd_clones == 0) in zvol_add_clones()
1361 objset_t *mos = dd->dd_pool->dp_meta_objset; in zvol_add_clones()
1363 for (zap_cursor_init(zc, mos, dsl_dir_phys(dd)->dd_clones); in zvol_add_clones()
1369 if (dsl_dataset_hold_obj(dd->dd_pool, in zvol_add_clones()
1370 za->za_first_integer, FTAG, &clone) == 0) { in zvol_add_clones()
1377 job->name = n; in zvol_add_clones()
1378 job->list = minors_list; in zvol_add_clones()
1379 job->error = 0; in zvol_add_clones()
1425 job->name = n; in zvol_create_minors_cb()
1426 job->list = minors_list; in zvol_create_minors_cb()
1427 job->error = 0; in zvol_create_minors_cb()
1429 /* don't care if dispatch fails, because job->error is 0 */ in zvol_create_minors_cb()
1457 task->zt_total += total; in zvol_task_update_status()
1458 task->zt_done += done; in zvol_task_update_status()
1459 if (task->zt_total != task->zt_done) { in zvol_task_update_status()
1460 task->zt_status = -1; in zvol_task_update_status()
1462 task->zt_error = error; in zvol_task_update_status()
1479 if (task->zt_status == 0) in zvol_task_report_status()
1482 zvol_async_op_t op = MIN(task->zt_op, ZVOL_ASYNC_MAX); in zvol_task_report_status()
1483 if (task->zt_error) { in zvol_task_report_status()
1485 msg[op], task->zt_error); in zvol_task_report_status()
1503 * - scan the dataset for zvols, and
1504 * - for each zvol, create a minor node, then check if the zvol's snapshots
1514 const char *name = task->zt_name1; in zvol_create_minors_impl()
1571 if (!job->error) { in zvol_create_minors_impl()
1572 error = zvol_os_create_minor(job->name); in zvol_create_minors_impl()
1578 } else if (job->error == EINVAL) { in zvol_create_minors_impl()
1586 last_error = job->error; in zvol_create_minors_impl()
1589 kmem_strfree(job->name); in zvol_create_minors_impl()
1605 const char *name = task ? task->zt_name1 : NULL; in zvol_remove_minors_impl()
1607 boolean_t children = task ? !!task->zt_value : B_TRUE; in zvol_remove_minors_impl()
1617 * done with them, because that would make them appear to ZFS-side ops in zvol_remove_minors_impl()
1630 mutex_enter(&zv->zv_state_lock); in zvol_remove_minors_impl()
1631 if (zv->zv_flags & ZVOL_REMOVING) { in zvol_remove_minors_impl()
1633 mutex_exit(&zv->zv_state_lock); in zvol_remove_minors_impl()
1639 * - no name was offered (ie removing all at shutdown); or in zvol_remove_minors_impl()
1640 * - name matches exactly; or in zvol_remove_minors_impl()
1641 * - we were asked to remove children, and in zvol_remove_minors_impl()
1642 * - the start of the name matches, and in zvol_remove_minors_impl()
1643 * - there is a '/' immediately after the matched name; or in zvol_remove_minors_impl()
1644 * - there is a '@' immediately after the matched name in zvol_remove_minors_impl()
1646 if (name == NULL || strcmp(zv->zv_name, name) == 0 || in zvol_remove_minors_impl()
1647 (children && strncmp(zv->zv_name, name, namelen) == 0 && in zvol_remove_minors_impl()
1648 (zv->zv_name[namelen] == '/' || in zvol_remove_minors_impl()
1649 zv->zv_name[namelen] == '@'))) { in zvol_remove_minors_impl()
1653 * write half of the suspend lock to make sure that in zvol_remove_minors_impl()
1657 mutex_exit(&zv->zv_state_lock); in zvol_remove_minors_impl()
1658 rw_enter(&zv->zv_suspend_lock, RW_WRITER); in zvol_remove_minors_impl()
1659 mutex_enter(&zv->zv_state_lock); in zvol_remove_minors_impl()
1661 if (zv->zv_flags & ZVOL_REMOVING) { in zvol_remove_minors_impl()
1663 mutex_exit(&zv->zv_state_lock); in zvol_remove_minors_impl()
1664 rw_exit(&zv->zv_suspend_lock); in zvol_remove_minors_impl()
1672 zv->zv_flags |= ZVOL_REMOVING; in zvol_remove_minors_impl()
1673 mutex_exit(&zv->zv_state_lock); in zvol_remove_minors_impl()
1674 rw_exit(&zv->zv_suspend_lock); in zvol_remove_minors_impl()
1679 mutex_exit(&zv->zv_state_lock); in zvol_remove_minors_impl()
1687 task->zt_error = SET_ERROR(ENOENT); in zvol_remove_minors_impl()
1695 mutex_enter(&zv->zv_state_lock); in zvol_remove_minors_impl()
1703 while (zv->zv_open_count > 0 || in zvol_remove_minors_impl()
1704 atomic_read(&zv->zv_suspend_ref)) in zvol_remove_minors_impl()
1705 cv_wait(&zv->zv_removing_cv, &zv->zv_state_lock); in zvol_remove_minors_impl()
1711 * this zvol_state_t can never again be reached from an OS-side in zvol_remove_minors_impl()
1715 mutex_exit(&zv->zv_state_lock); in zvol_remove_minors_impl()
1757 const char *oldname = task->zt_name1; in zvol_rename_minors_impl()
1758 const char *newname = task->zt_name2; in zvol_rename_minors_impl()
1771 mutex_enter(&zv->zv_state_lock); in zvol_rename_minors_impl()
1773 if (strcmp(zv->zv_name, oldname) == 0) { in zvol_rename_minors_impl()
1775 } else if (strncmp(zv->zv_name, oldname, oldnamelen) == 0 && in zvol_rename_minors_impl()
1776 (zv->zv_name[oldnamelen] == '/' || in zvol_rename_minors_impl()
1777 zv->zv_name[oldnamelen] == '@')) { in zvol_rename_minors_impl()
1779 zv->zv_name[oldnamelen], in zvol_rename_minors_impl()
1780 zv->zv_name + oldnamelen + 1); in zvol_rename_minors_impl()
1790 mutex_exit(&zv->zv_state_lock); in zvol_rename_minors_impl()
1811 switch (arg->snapdev) { in zvol_set_snapdev_cb()
1820 zvol_task_update_status(arg->task, 1, error == 0, error); in zvol_set_snapdev_cb()
1827 const char *name = task->zt_name1; in zvol_set_snapdev_impl()
1828 uint64_t snapdev = task->zt_value; in zvol_set_snapdev_impl()
1843 const char *name = task->zt_name1; in zvol_set_volmode_impl()
1844 uint64_t volmode = task->zt_value; in zvol_set_volmode_impl()
1855 * this is necessary because our backing gendisk (zvol_state->zv_disk) in zvol_set_volmode_impl()
1863 old_volmode = zv->zv_volmode; in zvol_set_volmode_impl()
1864 mutex_exit(&zv->zv_state_lock); in zvol_set_volmode_impl()
1896 zvol_task_update_status(task, 1, error == 0, error); in zvol_set_volmode_impl()
1908 switch (task->zt_op) { in zvol_task_cb()
1952 error = dsl_dir_hold(dp, zsda->zsda_name, FTAG, &dd, NULL); in zvol_set_common_check()
1969 const char *prop_name = zfs_prop_to_name(zsda->zsda_prop); in zvol_set_common_sync_cb()
1976 if (zsda->zsda_prop == ZFS_PROP_VOLMODE) { in zvol_set_common_sync_cb()
1977 task->zt_op = ZVOL_ASYNC_SET_VOLMODE; in zvol_set_common_sync_cb()
1978 } else if (zsda->zsda_prop == ZFS_PROP_SNAPDEV) { in zvol_set_common_sync_cb()
1979 task->zt_op = ZVOL_ASYNC_SET_SNAPDEV; in zvol_set_common_sync_cb()
1984 task->zt_value = prop; in zvol_set_common_sync_cb()
1985 strlcpy(task->zt_name1, dsname, sizeof (task->zt_name1)); in zvol_set_common_sync_cb()
1986 (void) taskq_dispatch(dp->dp_spa->spa_zvol_taskq, zvol_task_cb, in zvol_set_common_sync_cb()
2007 VERIFY0(dsl_dir_hold(dp, zsda->zsda_name, FTAG, &dd, NULL)); in zvol_set_common_sync()
2009 error = dsl_dataset_hold(dp, zsda->zsda_name, FTAG, &ds); in zvol_set_common_sync()
2011 dsl_prop_set_sync_impl(ds, zfs_prop_to_name(zsda->zsda_prop), in zvol_set_common_sync()
2012 zsda->zsda_source, sizeof (zsda->zsda_value), 1, in zvol_set_common_sync()
2013 &zsda->zsda_value, tx); in zvol_set_common_sync()
2017 dmu_objset_find_dp(dp, dd->dd_object, zvol_set_common_sync_cb, in zvol_set_common_sync()
2049 task->zt_op = ZVOL_ASYNC_CREATE_MINORS; in zvol_create_minors()
2050 strlcpy(task->zt_name1, name, sizeof (task->zt_name1)); in zvol_create_minors()
2051 id = taskq_dispatch(spa->spa_zvol_taskq, zvol_task_cb, task, TQ_SLEEP); in zvol_create_minors()
2053 taskq_wait_id(spa->spa_zvol_taskq, id); in zvol_create_minors()
2065 task->zt_op = ZVOL_ASYNC_REMOVE_MINORS; in zvol_remove_minors()
2066 strlcpy(task->zt_name1, name, sizeof (task->zt_name1)); in zvol_remove_minors()
2067 task->zt_value = B_TRUE; in zvol_remove_minors()
2068 id = taskq_dispatch(spa->spa_zvol_taskq, zvol_task_cb, task, TQ_SLEEP); in zvol_remove_minors()
2070 taskq_wait_id(spa->spa_zvol_taskq, id); in zvol_remove_minors()
2081 task->zt_op = ZVOL_ASYNC_RENAME_MINORS; in zvol_rename_minors()
2082 strlcpy(task->zt_name1, name1, sizeof (task->zt_name1)); in zvol_rename_minors()
2083 strlcpy(task->zt_name2, name2, sizeof (task->zt_name2)); in zvol_rename_minors()
2084 id = taskq_dispatch(spa->spa_zvol_taskq, zvol_task_cb, task, TQ_SLEEP); in zvol_rename_minors()
2086 taskq_wait_id(spa->spa_zvol_taskq, id); in zvol_rename_minors()
2117 zvol_actual_threads = MIN(MAX(zvol_threads, 1), 1024); in zvol_init_impl()
2127 * ------- ------- ------- ------- in zvol_init_impl()
2128 * 1 1 32 32 in zvol_init_impl()
2129 * 2 1 32 32 in zvol_init_impl()
2130 * 4 1 32 32 in zvol_init_impl()
2141 num_tqs = 1 + max_ncpus / 6; in zvol_init_impl()
2143 num_tqs--; in zvol_init_impl()
2150 ztqs->tqs_cnt = num_tqs; in zvol_init_impl()
2151 ztqs->tqs_taskq = kmem_alloc(num_tqs * sizeof (taskq_t *), KM_SLEEP); in zvol_init_impl()
2155 (void) snprintf(name, sizeof (name), "%s_tq-%u", in zvol_init_impl()
2157 ztqs->tqs_taskq[i] = taskq_create(name, per_tq_thread, in zvol_init_impl()
2160 if (ztqs->tqs_taskq[i] == NULL) { in zvol_init_impl()
2161 for (int j = i - 1; j >= 0; j--) in zvol_init_impl()
2162 taskq_destroy(ztqs->tqs_taskq[j]); in zvol_init_impl()
2163 kmem_free(ztqs->tqs_taskq, ztqs->tqs_cnt * in zvol_init_impl()
2165 ztqs->tqs_taskq = NULL; in zvol_init_impl()
2193 if (ztqs->tqs_taskq == NULL) { in zvol_fini_impl()
2194 ASSERT0(ztqs->tqs_cnt); in zvol_fini_impl()
2196 for (uint_t i = 0; i < ztqs->tqs_cnt; i++) { in zvol_fini_impl()
2197 ASSERT3P(ztqs->tqs_taskq[i], !=, NULL); in zvol_fini_impl()
2198 taskq_destroy(ztqs->tqs_taskq[i]); in zvol_fini_impl()
2200 kmem_free(ztqs->tqs_taskq, ztqs->tqs_cnt * in zvol_fini_impl()
2202 ztqs->tqs_taskq = NULL; in zvol_fini_impl()