Skip to content

Commit c01938b

Browse files
Luke Beirnecalccrypto
authored andcommitted
Z.I.A. disk open/close rework
Reworked how Z.I.A. opens and closes disks when changing parameters, specifically zia_provider and zia_disk/file_write. The purpose is to remove redundant file/disk openings when the provider has no use for them. zia_get_provider() no longer opens vdevs and the vdevs are now only opened in spa.c whenever the provider is set AND either zia_disk_write or zia_file_write is enabled. Rather than calling the generic vdev_close/open(), zia_open_vdevs() is called instead. Additionally, the zia_open/close_vdevs() functions are now wrapped with spa_vdev_state_enter() and spa_vdev_state_exit() functions. zia_close_vdevs() is not called whenever disabling file_write and disk_write as it will eventually be called whenever changing the provider or freeing it by destroying the zpool. Signed-off-by: Luke Beirne <[email protected]>
1 parent be42ee0 commit c01938b

File tree

3 files changed

+59
-45
lines changed

3 files changed

+59
-45
lines changed

include/sys/zia.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ void zia_prop_warn(boolean_t val, const char *name);
117117
int zia_init(void);
118118
int zia_fini(void);
119119

120-
void *zia_get_provider(const char *name, vdev_t *vdev);
120+
void zia_open_vdevs(vdev_t *vd);
121+
void *zia_get_provider(const char *name);
121122
const char *zia_get_provider_name(void *provider);
122123
int zia_put_provider(void **provider, vdev_t *vdev);
123124

module/zfs/spa.c

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,6 +2180,11 @@ spa_unload(spa_t *spa)
21802180

21812181
bpobj_close(&spa->spa_deferred_bpobj);
21822182

2183+
if (zia_get_props(spa)->provider != NULL) {
2184+
zia_put_provider(&zia_get_props(spa)->provider,
2185+
spa->spa_root_vdev);
2186+
}
2187+
21832188
spa_config_enter(spa, SCL_ALL, spa, RW_WRITER);
21842189

21852190
/*
@@ -2251,11 +2256,6 @@ spa_unload(spa_t *spa)
22512256
spa->spa_raidz_expand = NULL;
22522257
spa->spa_checkpoint_txg = 0;
22532258

2254-
if (zia_get_props(spa)->provider != NULL) {
2255-
zia_put_provider(&zia_get_props(spa)->provider,
2256-
spa->spa_root_vdev);
2257-
}
2258-
22592259
spa_config_exit(spa, SCL_ALL, spa);
22602260
}
22612261

@@ -9815,26 +9815,21 @@ spa_sync_props(void *arg, dmu_tx_t *tx)
98159815
if (zia_props->provider != NULL)
98169816
zia_put_provider(&zia_props->provider,
98179817
spa->spa_root_vdev);
9818-
zia_props->provider = zia_get_provider(strval,
9819-
spa->spa_root_vdev);
9818+
zia_props->provider = zia_get_provider(strval);
98209819
zia_props->can_offload = !!zia_props->provider;
98219820

98229821
/*
9823-
* Dirty the configuration on vdevs as above.
9824-
*/
9825-
if (tx->tx_txg != TXG_INITIAL) {
9826-
vdev_config_dirty(spa->spa_root_vdev);
9827-
spa_async_request(spa, SPA_ASYNC_CONFIG_UPDATE);
9828-
}
9829-
9830-
/*
9831-
* reopen devices so that provider is used
9832-
* copied from zfs_ioc_pool_reopen
9822+
* It is possible to enable disk_write or file_write
9823+
* without passing a provider, or swapping one
9824+
* provider with another while these flags are enabled.
9825+
* In those cases, vdevs must be opened for the new
9826+
* provider upon being passed.
9827+
* The vdevs will be closed for the older provider
9828+
* in zia_put_provider() first.
98339829
*/
9834-
spa_vdev_state_enter(spa, SCL_NONE);
9835-
vdev_close(spa->spa_root_vdev);
9836-
(void) vdev_open(spa->spa_root_vdev);
9837-
(void) spa_vdev_state_exit(spa, NULL, 0);
9830+
ASSERT3P(spa->spa_root_vdev, !=, NULL);
9831+
if (zia_props->disk_write || zia_props->file_write)
9832+
zia_open_vdevs(spa->spa_root_vdev);
98389833

98399834
spa_history_log_internal(spa, "set", tx,
98409835
"%s=%s", nvpair_name(elem), strval);
@@ -9924,11 +9919,16 @@ spa_sync_props(void *arg, dmu_tx_t *tx)
99249919
zia_props->file_write =
99259920
fnvpair_value_uint64(elem);
99269921

9927-
/* reopen devices so that provider is used */
9928-
spa_vdev_state_enter(spa, SCL_NONE);
9929-
vdev_close(spa->spa_root_vdev);
9930-
(void) vdev_open(spa->spa_root_vdev);
9931-
(void) spa_vdev_state_exit(spa, NULL, 0);
9922+
/*
9923+
* Only open vdevs for the provider if one
9924+
* has already been instantiated and if the
9925+
* passed value to file_write is 1, not 0
9926+
* to disable it.
9927+
*/
9928+
ASSERT3P(spa->spa_root_vdev, !=, NULL);
9929+
if (zia_props->provider && zia_props->file_write) {
9930+
zia_open_vdevs(spa->spa_root_vdev);
9931+
}
99329932

99339933
zia_prop_warn(zia_props->file_write,
99349934
"File Write");
@@ -9937,11 +9937,13 @@ spa_sync_props(void *arg, dmu_tx_t *tx)
99379937
zia_props->disk_write =
99389938
fnvpair_value_uint64(elem);
99399939

9940-
/* reopen devices so that provider is used */
9941-
spa_vdev_state_enter(spa, SCL_NONE);
9942-
vdev_close(spa->spa_root_vdev);
9943-
(void) vdev_open(spa->spa_root_vdev);
9944-
(void) spa_vdev_state_exit(spa, NULL, 0);
9940+
/*
9941+
* Check for the same reason as file_write.
9942+
*/
9943+
ASSERT3P(spa->spa_root_vdev, !=, NULL);
9944+
if (zia_props->provider && zia_props->disk_write) {
9945+
zia_open_vdevs(spa->spa_root_vdev);
9946+
}
99459947

99469948
zia_prop_warn(zia_props->disk_write,
99479949
"Disk Write");

module/zfs/zia.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ zia_fini(void)
293293

294294
#ifdef ZIA
295295
/* recursively find all leaf vdevs and open them */
296-
static void zia_open_vdevs(vdev_t *vd) {
296+
static void zia_open_vdevs_impl(vdev_t *vd) {
297297
vdev_ops_t *ops = vd->vdev_ops;
298298
if (ops->vdev_op_leaf) {
299299
ASSERT(!vd->vdev_zia_handle);
@@ -307,23 +307,34 @@ static void zia_open_vdevs(vdev_t *vd) {
307307
}
308308
#ifdef _KERNEL
309309
else if (memcmp(ops->vdev_op_type, "disk", 4) == 0) {
310-
/* first member is struct block_device * */
311-
void *disk = vd->vdev_tsd;
312-
zia_disk_open(vd, vd->vdev_path, disk);
310+
zia_disk_open(vd, vd->vdev_path,
311+
get_bdev(vd->vdev_tsd));
313312
}
314313
#endif
315314
}
316315
} else {
317316
for (uint64_t i = 0; i < vd->vdev_children; i++) {
318317
vdev_t *child = vd->vdev_child[i];
319-
zia_open_vdevs(child);
318+
zia_open_vdevs_impl(child);
320319
}
321320
}
322321
}
323322
#endif
324323

324+
void zia_open_vdevs(vdev_t *vd) {
325+
#ifdef ZIA
326+
if (!vd)
327+
return;
328+
329+
spa_vdev_state_enter(vd->vdev_spa, SCL_NONE);
330+
zia_open_vdevs_impl(vd);
331+
(void) spa_vdev_state_exit(vd->vdev_spa, NULL, 0);
332+
#endif
333+
(void) vd;
334+
}
335+
325336
void *
326-
zia_get_provider(const char *name, vdev_t *vdev)
337+
zia_get_provider(const char *name)
327338
{
328339
#ifdef ZIA
329340
if (!dpusm) {
@@ -337,13 +348,9 @@ zia_get_provider(const char *name, vdev_t *vdev)
337348
name, provider);
338349
#endif
339350

340-
/* set up Z.I.A. for existing vdevs */
341-
if (vdev) {
342-
zia_open_vdevs(vdev);
343-
}
344351
return (provider);
345352
#else
346-
(void) name; (void) vdev;
353+
(void) name;
347354

348355
#ifdef _KERNEL
349356
printk("Z.I.A. not available. Cannot obtain handle to providers.\n");
@@ -405,7 +412,9 @@ zia_put_provider(void **provider, vdev_t *vdev)
405412
* make sure the vdevs don't keep pointing to the invalid provider
406413
*/
407414
if (vdev) {
415+
spa_vdev_state_enter(vdev->vdev_spa, SCL_NONE);
408416
zia_close_vdevs(vdev);
417+
(void) spa_vdev_state_exit(vdev->vdev_spa, NULL, 0);
409418
}
410419

411420
#ifdef _KERNEL
@@ -1638,8 +1647,10 @@ zia_disk_open(vdev_t *vdev, const char *path,
16381647
return (ZIA_ERROR);
16391648
}
16401649

1641-
void *provider = zia_get_props(vdev->vdev_spa)->provider;
1642-
if (!dpusm || !provider) {
1650+
zia_props_t *props = zia_get_props(vdev->vdev_spa);
1651+
void *provider = props->provider;
1652+
1653+
if (!dpusm || !provider || props->disk_write != 1) {
16431654
return (ZIA_FALLBACK);
16441655
}
16451656

0 commit comments

Comments
 (0)