aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorTom Caputi <[email protected]>2018-10-19 00:06:18 -0400
committerBrian Behlendorf <[email protected]>2018-10-18 21:06:18 -0700
commit80a91e7469669e2a5da5873b8f09a752f7869062 (patch)
treeef5a4462892becccb939b2cd42a54ed580f5894f /include
parent9f438c5f948c0072f16431407a373ead34fabf6e (diff)
Defer new resilvers until the current one ends
Currently, if a resilver is triggered for any reason while an existing one is running, zfs will immediately restart the existing resilver from the beginning to include the new drive. This causes problems for system administrators when a drive fails while another is already resilvering. In this case, the optimal thing to do to reduce risk of data loss is to wait for the current resilver to end before immediately replacing the second failed drive, which allows the system to operate with two incomplete drives for the minimum amount of time. This patch introduces the resilver_defer feature that essentially does this for the admin without forcing them to wait and monitor the resilver manually. The change requires an on-disk feature since we must mark drives that are part of a deferred resilver in the vdev config to ensure that we do not assume they are done resilvering when an existing resilver completes. Reviewed-by: Matthew Ahrens <[email protected]> Reviewed-by: John Kennedy <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: @mmaybee Signed-off-by: Tom Caputi <[email protected]> Closes #7732
Diffstat (limited to 'include')
-rw-r--r--include/sys/fs/zfs.h2
-rw-r--r--include/sys/spa_impl.h7
-rw-r--r--include/sys/vdev.h2
-rw-r--r--include/sys/vdev_impl.h1
-rw-r--r--include/zfeature_common.h1
-rw-r--r--include/zfs_gitrev.h1
6 files changed, 14 insertions, 0 deletions
diff --git a/include/sys/fs/zfs.h b/include/sys/fs/zfs.h
index 6bbf84346..4f0e13dfd 100644
--- a/include/sys/fs/zfs.h
+++ b/include/sys/fs/zfs.h
@@ -710,6 +710,7 @@ typedef struct zpool_load_policy {
#define ZPOOL_CONFIG_VDEV_TOP_ZAP "com.delphix:vdev_zap_top"
#define ZPOOL_CONFIG_VDEV_LEAF_ZAP "com.delphix:vdev_zap_leaf"
#define ZPOOL_CONFIG_HAS_PER_VDEV_ZAPS "com.delphix:has_per_vdev_zaps"
+#define ZPOOL_CONFIG_RESILVER_DEFER "com.datto:resilver_defer"
#define ZPOOL_CONFIG_CACHEFILE "cachefile" /* not stored on disk */
#define ZPOOL_CONFIG_MMP_STATE "mmp_state" /* not stored on disk */
#define ZPOOL_CONFIG_MMP_TXG "mmp_txg" /* not stored on disk */
@@ -988,6 +989,7 @@ typedef struct vdev_stat {
uint64_t vs_scan_processed; /* scan processed bytes */
uint64_t vs_fragmentation; /* device fragmentation */
uint64_t vs_checkpoint_space; /* checkpoint-consumed space */
+ uint64_t vs_resilver_deferred; /* resilver deferred */
} vdev_stat_t;
/*
diff --git a/include/sys/spa_impl.h b/include/sys/spa_impl.h
index 9dbdcfcf5..404aaa9ee 100644
--- a/include/sys/spa_impl.h
+++ b/include/sys/spa_impl.h
@@ -281,6 +281,13 @@ struct spa {
uint64_t spa_scan_pass_scrub_spent_paused; /* total paused */
uint64_t spa_scan_pass_exam; /* examined bytes per pass */
uint64_t spa_scan_pass_issued; /* issued bytes per pass */
+
+ /*
+ * We are in the middle of a resilver, and another resilver
+ * is needed once this one completes. This is set iff any
+ * vdev_resilver_deferred is set.
+ */
+ boolean_t spa_resilver_deferred;
kmutex_t spa_async_lock; /* protect async state */
kthread_t *spa_async_thread; /* thread doing async task */
int spa_async_suspended; /* async tasks suspended */
diff --git a/include/sys/vdev.h b/include/sys/vdev.h
index b37b60bdd..2091892b2 100644
--- a/include/sys/vdev.h
+++ b/include/sys/vdev.h
@@ -149,6 +149,8 @@ extern int vdev_config_sync(vdev_t **svd, int svdcount, uint64_t txg);
extern void vdev_state_dirty(vdev_t *vd);
extern void vdev_state_clean(vdev_t *vd);
+extern void vdev_set_deferred_resilver(spa_t *spa, vdev_t *vd);
+
typedef enum vdev_config_flag {
VDEV_CONFIG_SPARE = 1 << 0,
VDEV_CONFIG_L2CACHE = 1 << 1,
diff --git a/include/sys/vdev_impl.h b/include/sys/vdev_impl.h
index d30868547..7b07fe6c1 100644
--- a/include/sys/vdev_impl.h
+++ b/include/sys/vdev_impl.h
@@ -335,6 +335,7 @@ struct vdev {
boolean_t vdev_isspare; /* was a hot spare */
boolean_t vdev_isl2cache; /* was a l2cache device */
boolean_t vdev_copy_uberblocks; /* post expand copy uberblocks */
+ boolean_t vdev_resilver_deferred; /* resilver deferred */
vdev_queue_t vdev_queue; /* I/O deadline schedule queue */
vdev_cache_t vdev_cache; /* physical block cache */
spa_aux_vdev_t *vdev_aux; /* for l2cache and spares vdevs */
diff --git a/include/zfeature_common.h b/include/zfeature_common.h
index 3804d7b1a..089a7e29d 100644
--- a/include/zfeature_common.h
+++ b/include/zfeature_common.h
@@ -65,6 +65,7 @@ typedef enum spa_feature {
SPA_FEATURE_POOL_CHECKPOINT,
SPA_FEATURE_SPACEMAP_V2,
SPA_FEATURE_ALLOCATION_CLASSES,
+ SPA_FEATURE_RESILVER_DEFER,
SPA_FEATURES
} spa_feature_t;
diff --git a/include/zfs_gitrev.h b/include/zfs_gitrev.h
new file mode 100644
index 000000000..13a831cb3
--- /dev/null
+++ b/include/zfs_gitrev.h
@@ -0,0 +1 @@
+#define ZFS_META_GITREV "unknown"