Skip to content

Commit 2debf5f

Browse files
mmaybeeallanjude
authored andcommitted
VDEV_PROP_NOALLOC plumbing
Signed-off-by: Allan Jude <allan@klarasystems.com>
1 parent 3a5fae5 commit 2debf5f

File tree

8 files changed

+281
-67
lines changed

8 files changed

+281
-67
lines changed

cmd/zpool/zpool_main.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2431,6 +2431,12 @@ print_status_config(zpool_handle_t *zhp, status_cbdata_t *cb, const char *name,
24312431
1 << vs->vs_configured_ashift, 1 << vs->vs_physical_ashift);
24322432
}
24332433

2434+
if (vs->vs_scan_removing != 0) {
2435+
(void) printf(gettext(" (removing)"));
2436+
} else if (vs->vs_noalloc != 0) {
2437+
(void) printf(gettext(" (non-allocating)"));
2438+
}
2439+
24342440
/* The root vdev has the scrub/resilver stats */
24352441
root = fnvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
24362442
ZPOOL_CONFIG_VDEV_TREE);
@@ -10202,6 +10208,14 @@ set_callback(zpool_handle_t *zhp, void *data)
1020210208
int error;
1020310209
set_cbdata_t *cb = (set_cbdata_t *)data;
1020410210

10211+
if (cb->cb_type == ZFS_TYPE_VDEV) {
10212+
error = zpool_set_vdev_prop(zhp, *cb->cb_vdevs.cb_names,
10213+
cb->cb_propname, cb->cb_value);
10214+
if (!error)
10215+
cb->cb_any_successful = B_TRUE;
10216+
return (error);
10217+
}
10218+
1020510219
/* Check if we have out-of-bounds features */
1020610220
if (strcmp(cb->cb_propname, ZPOOL_CONFIG_COMPATIBILITY) == 0) {
1020710221
boolean_t features[SPA_FEATURES];
@@ -10259,11 +10273,7 @@ set_callback(zpool_handle_t *zhp, void *data)
1025910273
}
1026010274
}
1026110275

10262-
if (cb->cb_type == ZFS_TYPE_VDEV)
10263-
error = zpool_set_vdev_prop(zhp, *cb->cb_vdevs.cb_names,
10264-
cb->cb_propname, cb->cb_value);
10265-
else
10266-
error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
10276+
error = zpool_set_prop(zhp, cb->cb_propname, cb->cb_value);
1026710277

1026810278
if (!error)
1026910279
cb->cb_any_successful = B_TRUE;

include/sys/fs/zfs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,7 @@ typedef struct zpool_load_policy {
774774
#define ZPOOL_CONFIG_ORIG_GUID "orig_guid"
775775
#define ZPOOL_CONFIG_SPLIT_GUID "split_guid"
776776
#define ZPOOL_CONFIG_SPLIT_LIST "guid_list"
777+
#define ZPOOL_CONFIG_NONALLOCATING "non_allocating"
777778
#define ZPOOL_CONFIG_REMOVING "removing"
778779
#define ZPOOL_CONFIG_RESILVER_TXG "resilver_txg"
779780
#define ZPOOL_CONFIG_REBUILD_TXG "rebuild_txg"
@@ -1151,6 +1152,7 @@ typedef struct vdev_stat {
11511152
uint64_t vs_checksum_errors; /* checksum errors */
11521153
uint64_t vs_initialize_errors; /* initializing errors */
11531154
uint64_t vs_self_healed; /* self-healed bytes */
1155+
uint64_t vs_noalloc; /* allocations halted? */
11541156
uint64_t vs_scan_removing; /* removing? */
11551157
uint64_t vs_scan_processed; /* scan processed bytes */
11561158
uint64_t vs_fragmentation; /* device fragmentation */

include/sys/spa.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,8 @@ extern int spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot,
792792
int replacing, int rebuild);
793793
extern int spa_vdev_detach(spa_t *spa, uint64_t guid, uint64_t pguid,
794794
int replace_done);
795-
extern int spa_vdev_remove(spa_t *spa, uint64_t guid, boolean_t unspare);
795+
extern int spa_vdev_alloc(spa_t *spa, uint64_t guid);
796+
extern int spa_vdev_noalloc(spa_t *spa, uint64_t guid);
796797
extern boolean_t spa_vdev_remove_active(spa_t *spa);
797798
extern int spa_vdev_initialize(spa_t *spa, nvlist_t *nv, uint64_t cmd_type,
798799
nvlist_t *vdev_errlist);

include/sys/vdev_impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ struct vdev {
295295
list_node_t vdev_state_dirty_node; /* state dirty list */
296296
uint64_t vdev_deflate_ratio; /* deflation ratio (x512) */
297297
uint64_t vdev_islog; /* is an intent log device */
298+
uint64_t vdev_noalloc; /* device is passivated? */
298299
uint64_t vdev_removing; /* device is being removed? */
299300
boolean_t vdev_ishole; /* is a hole in the namespace */
300301
uint64_t vdev_top_zap;

module/zfs/vdev.c

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,8 @@ vdev_alloc(spa_t *spa, vdev_t **vdp, nvlist_t *nv, vdev_t *parent, uint_t id,
867867
&vd->vdev_ms_shift);
868868
(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_ASIZE,
869869
&vd->vdev_asize);
870+
(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_NONALLOCATING,
871+
&vd->vdev_noalloc);
870872
(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_REMOVING,
871873
&vd->vdev_removing);
872874
(void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_VDEV_TOP_ZAP,
@@ -1185,8 +1187,10 @@ vdev_top_transfer(vdev_t *svd, vdev_t *tvd)
11851187
ASSERT3P(tvd->vdev_indirect_mapping, ==, NULL);
11861188
ASSERT3P(tvd->vdev_indirect_births, ==, NULL);
11871189
ASSERT3P(tvd->vdev_obsolete_sm, ==, NULL);
1190+
ASSERT0(tvd->vdev_noalloc);
11881191
ASSERT0(tvd->vdev_removing);
11891192
ASSERT0(tvd->vdev_rebuilding);
1193+
tvd->vdev_noalloc = svd->vdev_noalloc;
11901194
tvd->vdev_removing = svd->vdev_removing;
11911195
tvd->vdev_rebuilding = svd->vdev_rebuilding;
11921196
tvd->vdev_rebuild_config = svd->vdev_rebuild_config;
@@ -1202,6 +1206,7 @@ vdev_top_transfer(vdev_t *svd, vdev_t *tvd)
12021206
svd->vdev_indirect_mapping = NULL;
12031207
svd->vdev_indirect_births = NULL;
12041208
svd->vdev_obsolete_sm = NULL;
1209+
svd->vdev_noalloc = 0;
12051210
svd->vdev_removing = 0;
12061211
svd->vdev_rebuilding = 0;
12071212

@@ -1500,11 +1505,11 @@ vdev_metaslab_init(vdev_t *vd, uint64_t txg)
15001505
spa_config_enter(spa, SCL_ALLOC, FTAG, RW_WRITER);
15011506

15021507
/*
1503-
* If the vdev is being removed we don't activate
1504-
* the metaslabs since we want to ensure that no new
1505-
* allocations are performed on this device.
1508+
* If the vdev is marked as non-allocating then don't
1509+
* activate the metaslabs since we want to ensure that
1510+
* no allocations are performed on this device.
15061511
*/
1507-
if (!expanding && !vd->vdev_removing) {
1512+
if (!expanding && !vd->vdev_noalloc) {
15081513
metaslab_group_activate(vd->vdev_mg);
15091514
if (vd->vdev_log_mg != NULL)
15101515
metaslab_group_activate(vd->vdev_log_mg);
@@ -4440,6 +4445,7 @@ vdev_get_stats_ex(vdev_t *vd, vdev_stat_t *vs, vdev_stat_ex_t *vsx)
44404445
vs->vs_fragmentation = (vd->vdev_mg != NULL) ?
44414446
vd->vdev_mg->mg_fragmentation : 0;
44424447
}
4448+
vs->vs_noalloc = vd->vdev_noalloc;
44434449
}
44444450

44454451
vdev_get_stats_ex_impl(vd, vs, vsx);
@@ -5516,6 +5522,7 @@ vdev_prop_set(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
55165522
nvpair_t *elem = NULL;
55175523
uint64_t vdev_guid;
55185524
nvlist_t *nvprops;
5525+
int error;
55195526

55205527
ASSERT(vd != NULL);
55215528

@@ -5528,7 +5535,7 @@ vdev_prop_set(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
55285535

55295536
#if 0
55305537
if ((error = vdev_prop_validate(spa, nvprops)) != 0)
5531-
return;
5538+
return (error);
55325539
#endif
55335540

55345541
while ((elem = nvlist_next_nvpair(nvprops, elem)) != NULL) {
@@ -5538,44 +5545,55 @@ vdev_prop_set(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl)
55385545
char *strval = NULL;
55395546

55405547
if (prop == VDEV_PROP_INVAL && !vdev_prop_user(propname)) {
5541-
intval = EINVAL;
5542-
vdev_prop_add_list(outnvl, propname, strval, intval, 0);
5543-
continue;
5548+
error = EINVAL;
5549+
goto end;
55445550
}
55455551

5546-
if (vdev_prop_readonly(prop) == B_TRUE) {
5547-
intval = EROFS;
5548-
vdev_prop_add_list(outnvl, propname, strval, intval, 0);
5549-
continue;
5552+
if (vdev_prop_readonly(prop)) {
5553+
error = EROFS;
5554+
goto end;
55505555
}
55515556

55525557
/* Special Processing */
55535558
switch (prop) {
55545559
case VDEV_PROP_PATH:
55555560
strval = vd->vdev_path;
55565561
if (strval == NULL)
5557-
intval = EROFS;
5558-
if (nvpair_type(elem) != DATA_TYPE_STRING)
5559-
intval = EINVAL;
5560-
if (intval == 0)
5561-
strval = fnvpair_value_string(elem);
5562+
error = EROFS;
5563+
else if (nvpair_type(elem) != DATA_TYPE_STRING)
5564+
error = EINVAL;
5565+
if (error != 0)
5566+
break;
5567+
strval = fnvpair_value_string(elem);
55625568
if (strval == NULL)
5563-
intval = EINVAL;
5564-
if (intval != 0) {
5565-
vdev_prop_add_list(outnvl, propname, strval,
5566-
intval, 0);
5567-
continue;
5568-
}
5569+
error = EINVAL;
5570+
if (error != 0)
5571+
break;
55695572
spa_strfree(vd->vdev_path);
55705573
vd->vdev_path = spa_strdup(strval);
55715574
spa_config_enter(spa, SCL_CONFIG, FTAG, RW_WRITER);
55725575
vdev_config_dirty(vd->vdev_top);
55735576
spa_config_exit(spa, SCL_CONFIG, FTAG);
55745577
break;
5578+
case VDEV_PROP_NOALLOC:
5579+
intval = fnvpair_value_uint64(elem);
5580+
if (intval == vd->vdev_noalloc)
5581+
return (0); /* noop */
5582+
if (intval == 1)
5583+
error = spa_vdev_noalloc(spa, vdev_guid);
5584+
else
5585+
error = spa_vdev_alloc(spa, vdev_guid);
5586+
break;
55755587
default:
55765588
/* Most processing is done in vdev_sync_props */
55775589
break;
55785590
}
5591+
end:
5592+
if (error != 0) {
5593+
intval = error;
5594+
vdev_prop_add_list(outnvl, propname, strval, intval, 0);
5595+
return (error);
5596+
}
55795597
}
55805598

55815599
return (dsl_sync_task(spa->spa_name, NULL, vdev_sync_props,

module/zfs/vdev_label.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,10 @@ vdev_config_generate(spa_t *spa, vdev_t *vd, boolean_t getstats,
478478
fnvlist_add_uint64(nv, ZPOOL_CONFIG_ASIZE,
479479
vd->vdev_asize);
480480
fnvlist_add_uint64(nv, ZPOOL_CONFIG_IS_LOG, vd->vdev_islog);
481+
if (vd->vdev_noalloc) {
482+
fnvlist_add_uint64(nv, ZPOOL_CONFIG_NONALLOCATING,
483+
vd->vdev_noalloc);
484+
}
481485
if (vd->vdev_removing) {
482486
fnvlist_add_uint64(nv, ZPOOL_CONFIG_REMOVING,
483487
vd->vdev_removing);

0 commit comments

Comments
 (0)