xref: /freebsd/sys/contrib/openzfs/include/sys/dsl_scan.h (revision 2f10ffc003be396f3fc23cd2888023896560252b)
1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3  * This file and its contents are supplied under the terms of the
4  * Common Development and Distribution License ("CDDL"), version 1.0.
5  * You may only use this file in accordance with the terms of version
6  * 1.0 of the CDDL.
7  *
8  * A full copy of the text of the CDDL should have accompanied this
9  * source.  A copy of the CDDL is also available via the Internet at
10  * https://opensource.org/license/CDDL-1.0.
11  */
12 /*
13  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
14  * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
15  * Copyright (c) 2017, 2019, Datto Inc. All rights reserved.
16  */
17 
18 #ifndef	_SYS_DSL_SCAN_H
19 #define	_SYS_DSL_SCAN_H
20 
21 #include <sys/zfs_context.h>
22 #include <sys/zio.h>
23 #include <sys/zap.h>
24 #include <sys/ddt.h>
25 #include <sys/bplist.h>
26 
27 #ifdef	__cplusplus
28 extern "C" {
29 #endif
30 
31 struct objset;
32 struct dsl_dir;
33 struct dsl_dataset;
34 struct dsl_pool;
35 struct dmu_tx;
36 
37 extern int zfs_scan_suspend_progress;
38 
39 /*
40  * All members of this structure must be uint64_t, for byteswap
41  * purposes.
42  */
43 typedef struct dsl_scan_phys {
44 	uint64_t scn_func; /* pool_scan_func_t */
45 	uint64_t scn_state; /* dsl_scan_state_t */
46 	uint64_t scn_queue_obj;
47 	uint64_t scn_min_txg;
48 	uint64_t scn_max_txg;
49 	uint64_t scn_cur_min_txg;
50 	uint64_t scn_cur_max_txg;
51 	uint64_t scn_start_time;
52 	uint64_t scn_end_time;
53 	uint64_t scn_to_examine; /* total bytes to be scanned */
54 	uint64_t scn_examined; /* bytes scanned so far */
55 	uint64_t scn_skipped;	/* bytes skipped by scanner */
56 	uint64_t scn_processed;
57 	uint64_t scn_errors;	/* scan I/O error count */
58 	uint64_t scn_ddt_class_max;
59 	ddt_bookmark_t scn_ddt_bookmark;
60 	zbookmark_phys_t scn_bookmark;
61 	uint64_t scn_flags; /* dsl_scan_flags_t */
62 } dsl_scan_phys_t;
63 
64 #define	SCAN_PHYS_NUMINTS (sizeof (dsl_scan_phys_t) / sizeof (uint64_t))
65 
66 typedef enum dsl_scan_flags {
67 	DSF_VISIT_DS_AGAIN = 1<<0,
68 	DSF_SCRUB_PAUSED = 1<<1,
69 	DSF_SCRUB_THOROUGH = 1<<2,
70 } dsl_scan_flags_t;
71 
72 typedef struct dsl_errorscrub_phys {
73 	uint64_t dep_func; /* pool_scan_func_t */
74 	uint64_t dep_state; /* dsl_scan_state_t */
75 	uint64_t dep_cursor; /* serialized zap cursor for tracing progress */
76 	uint64_t dep_start_time; /* error scrub start time, unix timestamp */
77 	uint64_t dep_end_time; /* error scrub end time, unix timestamp */
78 	uint64_t dep_to_examine; /* total error blocks to be scrubbed */
79 	uint64_t dep_examined; /* blocks scrubbed so far */
80 	uint64_t dep_errors;	/* error scrub I/O error count */
81 	uint64_t dep_paused_flags; /* flag for paused */
82 } dsl_errorscrub_phys_t;
83 
84 #define	ERRORSCRUB_PHYS_NUMINTS (sizeof (dsl_errorscrub_phys_t) \
85 	/ sizeof (uint64_t))
86 
87 /*
88  * Every pool will have one dsl_scan_t and this structure will contain
89  * in-memory information about the scan and a pointer to the on-disk
90  * representation (i.e. dsl_scan_phys_t). Most of the state of the scan
91  * is contained on-disk to allow the scan to resume in the event of a reboot
92  * or panic. This structure maintains information about the behavior of a
93  * running scan, some caching information, and how it should traverse the pool.
94  *
95  * The following members of this structure direct the behavior of the scan:
96  *
97  * scn_suspending -	a scan that cannot be completed in a single txg or
98  *			has exceeded its allotted time will need to suspend.
99  *			When this flag is set the scanner will stop traversing
100  *			the pool and write out the current state to disk.
101  *
102  * scn_restart_txg -	directs the scanner to either restart or start a
103  *			a scan at the specified txg value.
104  *
105  * scn_done_txg -	when a scan completes its traversal it will set
106  *			the completion txg to the next txg. This is necessary
107  *			to ensure that any blocks that were freed during
108  *			the scan but have not yet been processed (i.e deferred
109  *			frees) are accounted for.
110  *
111  * scn_finished_txg -	the txg dsl_scan_done() marked the scan finished in.
112  *			That happens in syncing context, ahead of the config
113  *			and label writes of the same txg, so the scan is still
114  *			reported as in progress until this txg has synced.
115  *
116  * This structure also maintains information about deferred frees which are
117  * a special kind of traversal. Deferred free can exist in either a bptree or
118  * a bpobj structure. The scn_is_bptree flag will indicate the type of
119  * deferred free that is in progress. If the deferred free is part of an
120  * asynchronous destroy then the scn_async_destroying flag will be set.
121  */
122 typedef struct dsl_scan {
123 	struct dsl_pool *scn_dp;
124 	uint64_t scn_restart_txg;
125 	uint64_t scn_done_txg;
126 	uint64_t scn_finished_txg;
127 	uint64_t scn_sync_start_time;
128 	uint64_t scn_issued_before_pass;
129 
130 	/* for freeing blocks */
131 	boolean_t scn_is_bptree;
132 	boolean_t scn_async_destroying;
133 	boolean_t scn_async_stalled;
134 	uint64_t  scn_async_block_min_time_ms;
135 
136 	/* flags and stats for controlling scan state */
137 	boolean_t scn_is_sorted;	/* doing sequential scan */
138 	boolean_t scn_clearing;		/* scan is issuing sequential extents */
139 	boolean_t scn_checkpointing;	/* scan is issuing all queued extents */
140 	boolean_t scn_suspending;	/* scan is suspending until next txg */
141 	uint64_t scn_last_checkpoint;	/* time of last checkpoint */
142 
143 	/* members for thread synchronization */
144 	zio_t *scn_zio_root;		/* root zio for waiting on IO */
145 	taskq_t *scn_taskq;		/* task queue for issuing extents */
146 
147 	/* for controlling scan prefetch, protected by spa_scrub_lock */
148 	boolean_t scn_prefetch_stop;	/* prefetch should stop */
149 	zbookmark_phys_t scn_prefetch_bookmark;	/* prefetch start bookmark */
150 	avl_tree_t scn_prefetch_queue;	/* priority queue of prefetch IOs */
151 	uint64_t scn_maxinflight_bytes; /* max bytes in flight for pool */
152 
153 	/* per txg statistics */
154 	uint64_t scn_visited_this_txg;	/* total bps visited this txg */
155 	uint64_t scn_async_frees_this_txg; /* async frees (dedup/clone/gang) */
156 	uint64_t scn_holes_this_txg;
157 	uint64_t scn_lt_min_this_txg;
158 	uint64_t scn_gt_max_this_txg;
159 	uint64_t scn_ddt_contained_this_txg;
160 	uint64_t scn_objsets_visited_this_txg;
161 	uint64_t scn_avg_seg_size_this_txg;
162 	uint64_t scn_segs_this_txg;
163 	uint64_t scn_avg_zio_size_this_txg;
164 	uint64_t scn_zios_this_txg;
165 
166 	/* zap cursor for tracing error scrub progress */
167 	zap_cursor_t errorscrub_cursor;
168 	/* members needed for syncing scan status to disk */
169 	dsl_scan_phys_t scn_phys;	/* on disk representation of scan */
170 	dsl_scan_phys_t scn_phys_cached;
171 	avl_tree_t scn_queue;		/* queue of datasets to scan */
172 	kmutex_t scn_queue_lock;	/* serializes scn_queue inserts */
173 	uint64_t scn_queues_pending;	/* outstanding data to issue */
174 	/* members needed for syncing error scrub status to disk */
175 	dsl_errorscrub_phys_t errorscrub_phys;
176 } dsl_scan_t;
177 
178 typedef struct {
179 	pool_scan_func_t func;
180 	uint64_t	 txgstart;
181 	uint64_t	 txgend;
182 	dsl_scan_flags_t flags;
183 } setup_sync_arg_t;
184 
185 typedef struct dsl_scan_io_queue dsl_scan_io_queue_t;
186 
187 void scan_init(void);
188 void scan_fini(void);
189 int dsl_scan_init(struct dsl_pool *dp, uint64_t txg);
190 int dsl_scan_setup_check(void *, dmu_tx_t *);
191 void dsl_scan_setup_sync(void *, dmu_tx_t *);
192 void dsl_scan_fini(struct dsl_pool *dp);
193 void dsl_scan_sync(struct dsl_pool *, dmu_tx_t *);
194 int dsl_scan_cancel(struct dsl_pool *);
195 int dsl_scan(struct dsl_pool *, pool_scan_func_t, uint64_t starttxg,
196     uint64_t txgend, dsl_scan_flags_t flags);
197 void dsl_scan_assess_vdev(struct dsl_pool *dp, vdev_t *vd);
198 boolean_t dsl_scan_scrubbing(const struct dsl_pool *dp);
199 boolean_t dsl_errorscrubbing(const struct dsl_pool *dp);
200 boolean_t dsl_errorscrub_active(dsl_scan_t *scn);
201 void dsl_scan_restart_resilver(struct dsl_pool *, uint64_t txg);
202 int dsl_scrub_set_pause_resume(const struct dsl_pool *dp,
203     pool_scrub_cmd_t cmd);
204 void dsl_errorscrub_sync(struct dsl_pool *, dmu_tx_t *);
205 boolean_t dsl_scan_resilvering(struct dsl_pool *dp);
206 boolean_t dsl_scan_resilver_scheduled(struct dsl_pool *dp);
207 boolean_t dsl_dataset_unstable(struct dsl_dataset *ds);
208 void dsl_scan_ddt_entry(dsl_scan_t *scn, enum zio_checksum checksum,
209     ddt_t *ddt, ddt_lightweight_entry_t *ddlwe, dmu_tx_t *tx);
210 void dsl_scan_ds_destroyed(struct dsl_dataset *ds, struct dmu_tx *tx);
211 void dsl_scan_ds_snapshotted(struct dsl_dataset *ds, struct dmu_tx *tx);
212 void dsl_scan_ds_clone_swapped(struct dsl_dataset *ds1, struct dsl_dataset *ds2,
213     struct dmu_tx *tx);
214 boolean_t dsl_scan_active(dsl_scan_t *scn);
215 boolean_t dsl_scan_is_paused_scrub(const dsl_scan_t *scn);
216 boolean_t dsl_errorscrub_is_paused(const dsl_scan_t *scn);
217 void dsl_scan_freed(spa_t *spa, const blkptr_t *bp);
218 void dsl_scan_io_queue_destroy(dsl_scan_io_queue_t *queue);
219 void dsl_scan_io_queue_vdev_xfer(vdev_t *svd, vdev_t *tvd);
220 
221 #ifdef	__cplusplus
222 }
223 #endif
224 
225 #endif /* _SYS_DSL_SCAN_H */
226