Skip to content

Commit 7e3f975

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 e7c9f9b commit 7e3f975

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
@@ -114,7 +114,8 @@ void zia_prop_warn(boolean_t val, const char *name);
114114
int zia_init(void);
115115
int zia_fini(void);
116116

117-
void *zia_get_provider(const char *name, vdev_t *vdev);
117+
void zia_open_vdevs(vdev_t *vd);
118+
void *zia_get_provider(const char *name);
118119
const char *zia_get_provider_name(void *provider);
119120
int zia_put_provider(void **provider, vdev_t *vdev);
120121

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
@@ -295,7 +295,7 @@ zia_fini(void)
295295

296296
#ifdef ZIA
297297
/* recursively find all leaf vdevs and open them */
298-
static void zia_open_vdevs(vdev_t *vd) {
298+
static void zia_open_vdevs_impl(vdev_t *vd) {
299299
vdev_ops_t *ops = vd->vdev_ops;
300300
if (ops->vdev_op_leaf) {
301301
ASSERT(!vd->vdev_zia_handle);
@@ -309,23 +309,34 @@ static void zia_open_vdevs(vdev_t *vd) {
309309
}
310310
#ifdef _KERNEL
311311
else if (memcmp(ops->vdev_op_type, "disk", 4) == 0) {
312-
/* first member is struct block_device * */
313-
void *disk = vd->vdev_tsd;
314-
zia_disk_open(vd, vd->vdev_path, disk);
312+
zia_disk_open(vd, vd->vdev_path,
313+
get_bdev(vd->vdev_tsd));
315314
}
316315
#endif
317316
}
318317
} else {
319318
for (uint64_t i = 0; i < vd->vdev_children; i++) {
320319
vdev_t *child = vd->vdev_child[i];
321-
zia_open_vdevs(child);
320+
zia_open_vdevs_impl(child);
322321
}
323322
}
324323
}
325324
#endif
326325

326+
void zia_open_vdevs(vdev_t *vd) {
327+
#ifdef ZIA
328+
if (!vd)
329+
return;
330+
331+
spa_vdev_state_enter(vd->vdev_spa, SCL_NONE);
332+
zia_open_vdevs_impl(vd);
333+
(void) spa_vdev_state_exit(vd->vdev_spa, NULL, 0);
334+
#endif
335+
(void) vd;
336+
}
337+
327338
void *
328-
zia_get_provider(const char *name, vdev_t *vdev)
339+
zia_get_provider(const char *name)
329340
{
330341
#ifdef ZIA
331342
if (!dpusm) {
@@ -339,13 +350,9 @@ zia_get_provider(const char *name, vdev_t *vdev)
339350
name, provider);
340351
#endif
341352

342-
/* set up Z.I.A. for existing vdevs */
343-
if (vdev) {
344-
zia_open_vdevs(vdev);
345-
}
346353
return (provider);
347354
#else
348-
(void) name; (void) vdev;
355+
(void) name;
349356

350357
#ifdef _KERNEL
351358
printk("Z.I.A. not available. Cannot obtain handle to providers.\n");
@@ -407,7 +414,9 @@ zia_put_provider(void **provider, vdev_t *vdev)
407414
* make sure the vdevs don't keep pointing to the invalid provider
408415
*/
409416
if (vdev) {
417+
spa_vdev_state_enter(vdev->vdev_spa, SCL_NONE);
410418
zia_close_vdevs(vdev);
419+
(void) spa_vdev_state_exit(vdev->vdev_spa, NULL, 0);
411420
}
412421

413422
#ifdef _KERNEL
@@ -1639,8 +1648,10 @@ zia_disk_open(vdev_t *vdev, const char *path,
16391648
return (ZIA_ERROR);
16401649
}
16411650

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

0 commit comments

Comments
 (0)