summaryrefslogtreecommitdiffstats
path: root/module/zfs
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2020-03-04 15:07:11 -0800
committerGitHub <[email protected]>2020-03-04 15:07:11 -0800
commit2288d4196821ae4b5fa375e8e519f6e83f26abad (patch)
tree49c49baf2112da27d14ea2f90e09a333d1ab99da /module/zfs
parentb3212d2fa6ab8d7d8373373e8a6b8acbbf45508e (diff)
Add trim support to zpool wait
Manual trims fall into the category of long-running pool activities which people might want to wait synchronously for. This change adds support to 'zpool wait' for waiting for manual trim operations to complete. It also adds a '-w' flag to 'zpool trim' which can be used to turn 'zpool trim' into a synchronous operation. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Serapheim Dimitropoulos <[email protected]> Signed-off-by: John Gallagher <[email protected]> Closes #10071
Diffstat (limited to 'module/zfs')
-rw-r--r--module/zfs/spa.c47
-rw-r--r--module/zfs/vdev_trim.c3
2 files changed, 32 insertions, 18 deletions
diff --git a/module/zfs/spa.c b/module/zfs/spa.c
index a6f97eb37..72a54ebce 100644
--- a/module/zfs/spa.c
+++ b/module/zfs/spa.c
@@ -9280,28 +9280,35 @@ spa_wake_waiters(spa_t *spa)
mutex_exit(&spa->spa_activities_lock);
}
-/* Whether the vdev or any of its descendants is initializing. */
+/* Whether the vdev or any of its descendants are being initialized/trimmed. */
static boolean_t
-spa_vdev_initializing_impl(vdev_t *vd)
+spa_vdev_activity_in_progress_impl(vdev_t *vd, zpool_wait_activity_t activity)
{
spa_t *spa = vd->vdev_spa;
- boolean_t initializing;
ASSERT(spa_config_held(spa, SCL_CONFIG | SCL_STATE, RW_READER));
ASSERT(MUTEX_HELD(&spa->spa_activities_lock));
+ ASSERT(activity == ZPOOL_WAIT_INITIALIZE ||
+ activity == ZPOOL_WAIT_TRIM);
+
+ kmutex_t *lock = activity == ZPOOL_WAIT_INITIALIZE ?
+ &vd->vdev_initialize_lock : &vd->vdev_trim_lock;
mutex_exit(&spa->spa_activities_lock);
- mutex_enter(&vd->vdev_initialize_lock);
+ mutex_enter(lock);
mutex_enter(&spa->spa_activities_lock);
- initializing = (vd->vdev_initialize_state == VDEV_INITIALIZE_ACTIVE);
- mutex_exit(&vd->vdev_initialize_lock);
+ boolean_t in_progress = (activity == ZPOOL_WAIT_INITIALIZE) ?
+ (vd->vdev_initialize_state == VDEV_INITIALIZE_ACTIVE) :
+ (vd->vdev_trim_state == VDEV_TRIM_ACTIVE);
+ mutex_exit(lock);
- if (initializing)
+ if (in_progress)
return (B_TRUE);
for (int i = 0; i < vd->vdev_children; i++) {
- if (spa_vdev_initializing_impl(vd->vdev_child[i]))
+ if (spa_vdev_activity_in_progress_impl(vd->vdev_child[i],
+ activity))
return (B_TRUE);
}
@@ -9310,12 +9317,13 @@ spa_vdev_initializing_impl(vdev_t *vd)
/*
* If use_guid is true, this checks whether the vdev specified by guid is
- * being initialized. Otherwise, it checks whether any vdev in the pool is being
- * initialized. The caller must hold the config lock and spa_activities_lock.
+ * being initialized/trimmed. Otherwise, it checks whether any vdev in the pool
+ * is being initialized/trimmed. The caller must hold the config lock and
+ * spa_activities_lock.
*/
static int
-spa_vdev_initializing(spa_t *spa, boolean_t use_guid, uint64_t guid,
- boolean_t *in_progress)
+spa_vdev_activity_in_progress(spa_t *spa, boolean_t use_guid, uint64_t guid,
+ zpool_wait_activity_t activity, boolean_t *in_progress)
{
mutex_exit(&spa->spa_activities_lock);
spa_config_enter(spa, SCL_CONFIG | SCL_STATE, FTAG, RW_READER);
@@ -9332,7 +9340,7 @@ spa_vdev_initializing(spa_t *spa, boolean_t use_guid, uint64_t guid,
vd = spa->spa_root_vdev;
}
- *in_progress = spa_vdev_initializing_impl(vd);
+ *in_progress = spa_vdev_activity_in_progress_impl(vd, activity);
spa_config_exit(spa, SCL_CONFIG | SCL_STATE, FTAG);
return (0);
@@ -9403,7 +9411,9 @@ spa_activity_in_progress(spa_t *spa, zpool_wait_activity_t activity,
spa_livelist_delete_check(spa));
break;
case ZPOOL_WAIT_INITIALIZE:
- error = spa_vdev_initializing(spa, use_tag, tag, in_progress);
+ case ZPOOL_WAIT_TRIM:
+ error = spa_vdev_activity_in_progress(spa, use_tag, tag,
+ activity, in_progress);
break;
case ZPOOL_WAIT_REPLACE:
mutex_exit(&spa->spa_activities_lock);
@@ -9443,15 +9453,16 @@ spa_wait_common(const char *pool, zpool_wait_activity_t activity,
{
/*
* The tag is used to distinguish between instances of an activity.
- * 'initialize' is the only activity that we use this for. The other
- * activities can only have a single instance in progress in a pool at
- * one time, making the tag unnecessary.
+ * 'initialize' and 'trim' are the only activities that we use this for.
+ * The other activities can only have a single instance in progress in a
+ * pool at one time, making the tag unnecessary.
*
* There can be multiple devices being replaced at once, but since they
* all finish once resilvering finishes, we don't bother keeping track
* of them individually, we just wait for them all to finish.
*/
- if (use_tag && activity != ZPOOL_WAIT_INITIALIZE)
+ if (use_tag && activity != ZPOOL_WAIT_INITIALIZE &&
+ activity != ZPOOL_WAIT_TRIM)
return (EINVAL);
if (activity < 0 || activity >= ZPOOL_WAIT_NUM_ACTIVITIES)
diff --git a/module/zfs/vdev_trim.c b/module/zfs/vdev_trim.c
index 7dec07e3c..137ba83df 100644
--- a/module/zfs/vdev_trim.c
+++ b/module/zfs/vdev_trim.c
@@ -346,6 +346,9 @@ vdev_trim_change_state(vdev_t *vd, vdev_trim_state_t new_state,
}
dmu_tx_commit(tx);
+
+ if (new_state != VDEV_TRIM_ACTIVE)
+ spa_notify_waiters(spa);
}
/*