FreeBSD ZFS
The Zettabyte File System
|
#include <sys/dsl_scan.h>
#include <sys/dsl_pool.h>
#include <sys/dsl_dataset.h>
#include <sys/dsl_prop.h>
#include <sys/dsl_dir.h>
#include <sys/dsl_synctask.h>
#include <sys/dnode.h>
#include <sys/dmu_tx.h>
#include <sys/dmu_objset.h>
#include <sys/arc.h>
#include <sys/zap.h>
#include <sys/zio.h>
#include <sys/zfs_context.h>
#include <sys/fs/zfs.h>
#include <sys/zfs_znode.h>
#include <sys/spa_impl.h>
#include <sys/vdev_impl.h>
#include <sys/zil_impl.h>
#include <sys/zio_checksum.h>
#include <sys/ddt.h>
#include <sys/sa.h>
#include <sys/sa_impl.h>
#include <sys/zfeature.h>
#include <sys/zfs_vfsops.h>
Go to the source code of this file.
Data Structures | |
struct | zil_scan_arg |
struct | enqueue_clones_arg |
Defines | |
#define | DSL_SCAN_IS_SCRUB_RESILVER(scn) |
Typedefs | |
typedef int( | scan_cb_t )(dsl_pool_t *, const blkptr_t *, const zbookmark_t *) |
typedef struct zil_scan_arg | zil_scan_arg_t |
Functions | |
static void | dsl_scan_sync_state (dsl_scan_t *, dmu_tx_t *tx) |
SYSCTL_DECL (_vfs_zfs) | |
TUNABLE_INT ("vfs.zfs.top_maxinflight",&zfs_top_maxinflight) | |
SYSCTL_UINT (_vfs_zfs, OID_AUTO, top_maxinflight, CTLFLAG_RW,&zfs_top_maxinflight, 0,"Maximum I/Os per top-level vdev") | |
TUNABLE_INT ("vfs.zfs.resilver_delay",&zfs_resilver_delay) | |
SYSCTL_UINT (_vfs_zfs, OID_AUTO, resilver_delay, CTLFLAG_RW,&zfs_resilver_delay, 0,"Number of ticks to delay resilver") | |
TUNABLE_INT ("vfs.zfs.scrub_delay",&zfs_scrub_delay) | |
SYSCTL_UINT (_vfs_zfs, OID_AUTO, scrub_delay, CTLFLAG_RW,&zfs_scrub_delay, 0,"Number of ticks to delay scrub") | |
TUNABLE_INT ("vfs.zfs.scan_idle",&zfs_scan_idle) | |
SYSCTL_UINT (_vfs_zfs, OID_AUTO, scan_idle, CTLFLAG_RW,&zfs_scan_idle, 0,"Idle scan window in clock ticks") | |
TUNABLE_INT ("vfs.zfs.scan_min_time_ms",&zfs_scan_min_time_ms) | |
SYSCTL_UINT (_vfs_zfs, OID_AUTO, scan_min_time_ms, CTLFLAG_RW,&zfs_scan_min_time_ms, 0,"Min millisecs to scrub per txg") | |
TUNABLE_INT ("vfs.zfs.free_min_time_ms",&zfs_free_min_time_ms) | |
SYSCTL_UINT (_vfs_zfs, OID_AUTO, free_min_time_ms, CTLFLAG_RW,&zfs_free_min_time_ms, 0,"Min millisecs to free per txg") | |
TUNABLE_INT ("vfs.zfs.resilver_min_time_ms",&zfs_resilver_min_time_ms) | |
SYSCTL_UINT (_vfs_zfs, OID_AUTO, resilver_min_time_ms, CTLFLAG_RW,&zfs_resilver_min_time_ms, 0,"Min millisecs to resilver per txg") | |
TUNABLE_INT ("vfs.zfs.no_scrub_io",&zfs_no_scrub_io) | |
SYSCTL_INT (_vfs_zfs, OID_AUTO, no_scrub_io, CTLFLAG_RW,&zfs_no_scrub_io, 0,"Disable scrub I/O") | |
TUNABLE_INT ("vfs.zfs.no_scrub_prefetch",&zfs_no_scrub_prefetch) | |
SYSCTL_INT (_vfs_zfs, OID_AUTO, no_scrub_prefetch, CTLFLAG_RW,&zfs_no_scrub_prefetch, 0,"Disable scrub prefetching") | |
int | dsl_scan_init (dsl_pool_t *dp, uint64_t txg) |
void | dsl_scan_fini (dsl_pool_t *dp) |
static int | dsl_scan_setup_check (void *arg1, void *arg2, dmu_tx_t *tx) |
static void | dsl_scan_setup_sync (void *arg1, void *arg2, dmu_tx_t *tx) |
static void | dsl_scan_done (dsl_scan_t *scn, boolean_t complete, dmu_tx_t *tx) |
static int | dsl_scan_cancel_check (void *arg1, void *arg2, dmu_tx_t *tx) |
static void | dsl_scan_cancel_sync (void *arg1, void *arg2, dmu_tx_t *tx) |
int | dsl_scan_cancel (dsl_pool_t *dp) |
static void | dsl_scan_visitbp (blkptr_t *bp, const zbookmark_t *zb, dnode_phys_t *dnp, arc_buf_t *pbuf, dsl_dataset_t *ds, dsl_scan_t *scn, dmu_objset_type_t ostype, dmu_tx_t *tx) |
static void | dsl_scan_visitdnode (dsl_scan_t *, dsl_dataset_t *ds, dmu_objset_type_t ostype, dnode_phys_t *dnp, arc_buf_t *buf, uint64_t object, dmu_tx_t *tx) |
void | dsl_free (dsl_pool_t *dp, uint64_t txg, const blkptr_t *bp) |
void | dsl_free_sync (zio_t *pio, dsl_pool_t *dp, uint64_t txg, const blkptr_t *bpp) |
int | dsl_read (zio_t *pio, spa_t *spa, const blkptr_t *bpp, arc_buf_t *pbuf, arc_done_func_t *done, void *private, int priority, int zio_flags, uint32_t *arc_flags, const zbookmark_t *zb) |
int | dsl_read_nolock (zio_t *pio, spa_t *spa, const blkptr_t *bpp, arc_done_func_t *done, void *private, int priority, int zio_flags, uint32_t *arc_flags, const zbookmark_t *zb) |
static uint64_t | dsl_scan_ds_maxtxg (dsl_dataset_t *ds) |
static boolean_t | dsl_scan_check_pause (dsl_scan_t *scn, const zbookmark_t *zb) |
static int | dsl_scan_zil_block (zilog_t *zilog, blkptr_t *bp, void *arg, uint64_t claim_txg) |
static int | dsl_scan_zil_record (zilog_t *zilog, lr_t *lrc, void *arg, uint64_t claim_txg) |
static void | dsl_scan_zil (dsl_pool_t *dp, zil_header_t *zh) |
static void | dsl_scan_prefetch (dsl_scan_t *scn, arc_buf_t *buf, blkptr_t *bp, uint64_t objset, uint64_t object, uint64_t blkid) |
static boolean_t | dsl_scan_check_resume (dsl_scan_t *scn, const dnode_phys_t *dnp, const zbookmark_t *zb) |
static int | dsl_scan_recurse (dsl_scan_t *scn, dsl_dataset_t *ds, dmu_objset_type_t ostype, dnode_phys_t *dnp, const blkptr_t *bp, const zbookmark_t *zb, dmu_tx_t *tx, arc_buf_t **bufp) |
static void | dsl_scan_visit_rootbp (dsl_scan_t *scn, dsl_dataset_t *ds, blkptr_t *bp, dmu_tx_t *tx) |
void | dsl_scan_ds_destroyed (dsl_dataset_t *ds, dmu_tx_t *tx) |
void | dsl_scan_ds_snapshotted (dsl_dataset_t *ds, dmu_tx_t *tx) |
void | dsl_scan_ds_clone_swapped (dsl_dataset_t *ds1, dsl_dataset_t *ds2, dmu_tx_t *tx) |
static int | enqueue_clones_cb (spa_t *spa, uint64_t dsobj, const char *dsname, void *arg) |
static void | dsl_scan_visitds (dsl_scan_t *scn, uint64_t dsobj, dmu_tx_t *tx) |
static int | enqueue_cb (spa_t *spa, uint64_t dsobj, const char *dsname, void *arg) |
static void | dsl_scan_ddt (dsl_scan_t *scn, dmu_tx_t *tx) |
Scrub/dedup interaction. | |
void | dsl_scan_ddt_entry (dsl_scan_t *scn, enum zio_checksum checksum, ddt_entry_t *dde, dmu_tx_t *tx) |
static void | dsl_scan_visit (dsl_scan_t *scn, dmu_tx_t *tx) |
static boolean_t | dsl_scan_free_should_pause (dsl_scan_t *scn) |
static int | dsl_scan_free_block_cb (void *arg, const blkptr_t *bp, dmu_tx_t *tx) |
boolean_t | dsl_scan_active (dsl_scan_t *scn) |
void | dsl_scan_sync (dsl_pool_t *dp, dmu_tx_t *tx) |
void | dsl_resilver_restart (dsl_pool_t *dp, uint64_t txg) |
This will start a new scan, or restart an existing one. | |
boolean_t | dsl_scan_resilvering (dsl_pool_t *dp) |
static void | count_block (zfs_all_blkstats_t *zab, const blkptr_t *bp) |
static void | dsl_scan_scrub_done (zio_t *zio) |
static int | dsl_scan_scrub_cb (dsl_pool_t *dp, const blkptr_t *bp, const zbookmark_t *zb) |
int | dsl_scan (dsl_pool_t *dp, pool_scan_func_t func) |
Variables | |
static scan_cb_t | dsl_scan_defrag_cb |
static scan_cb_t | dsl_scan_scrub_cb |
static scan_cb_t | dsl_scan_remove_cb |
static dsl_syncfunc_t | dsl_scan_cancel_sync |
unsigned int | zfs_top_maxinflight = 32 |
maximum I/Os per top-level | |
unsigned int | zfs_resilver_delay = 2 |
number of ticks to delay resilver | |
unsigned int | zfs_scrub_delay = 4 |
number of ticks to delay scrub | |
unsigned int | zfs_scan_idle = 50 |
idle window in clock ticks | |
unsigned int | zfs_scan_min_time_ms = 1000 |
min millisecs to scrub per txg | |
unsigned int | zfs_free_min_time_ms = 1000 |
min millisecs to free per txg | |
unsigned int | zfs_resilver_min_time_ms = 3000 |
min millisecs to resilver per txg | |
boolean_t | zfs_no_scrub_io = B_FALSE |
set to disable scrub i/o | |
boolean_t | zfs_no_scrub_prefetch = B_FALSE |
set to disable scrub prefetching | |
enum ddt_class | zfs_scrub_ddt_class_max = DDT_CLASS_DUPLICATE |
int | zfs_txg_timeout |
max seconds worth of delta per txg | |
static scan_cb_t * | scan_funcs [POOL_SCAN_FUNCS] |
#define DSL_SCAN_IS_SCRUB_RESILVER | ( | scn | ) |
((scn)->scn_phys.scn_func == POOL_SCAN_SCRUB || \ (scn)->scn_phys.scn_func == POOL_SCAN_RESILVER)
Definition at line 109 of file dsl_scan.c.
typedef int( scan_cb_t)(dsl_pool_t *, const blkptr_t *, const zbookmark_t *) |
Definition at line 53 of file dsl_scan.c.
typedef struct zil_scan_arg zil_scan_arg_t |
static void count_block | ( | zfs_all_blkstats_t * | zab, |
const blkptr_t * | bp | ||
) | [static] |
Definition at line 1603 of file dsl_scan.c.
void dsl_free | ( | dsl_pool_t * | dp, |
uint64_t | txg, | ||
const blkptr_t * | bp | ||
) |
Definition at line 392 of file dsl_scan.c.
void dsl_free_sync | ( | zio_t * | pio, |
dsl_pool_t * | dp, | ||
uint64_t | txg, | ||
const blkptr_t * | bpp | ||
) |
Definition at line 398 of file dsl_scan.c.
int dsl_read | ( | zio_t * | pio, |
spa_t * | spa, | ||
const blkptr_t * | bpp, | ||
arc_buf_t * | pbuf, | ||
arc_done_func_t * | done, | ||
void * | private, | ||
int | priority, | ||
int | zio_flags, | ||
uint32_t * | arc_flags, | ||
const zbookmark_t * | zb | ||
) |
Definition at line 406 of file dsl_scan.c.
int dsl_read_nolock | ( | zio_t * | pio, |
spa_t * | spa, | ||
const blkptr_t * | bpp, | ||
arc_done_func_t * | done, | ||
void * | private, | ||
int | priority, | ||
int | zio_flags, | ||
uint32_t * | arc_flags, | ||
const zbookmark_t * | zb | ||
) |
Definition at line 415 of file dsl_scan.c.
void dsl_resilver_restart | ( | dsl_pool_t * | dp, |
uint64_t | txg | ||
) |
This will start a new scan, or restart an existing one.
Definition at line 1575 of file dsl_scan.c.
int dsl_scan | ( | dsl_pool_t * | dp, |
pool_scan_func_t | func | ||
) |
Definition at line 1763 of file dsl_scan.c.
boolean_t dsl_scan_active | ( | dsl_scan_t * | scn | ) |
Definition at line 1406 of file dsl_scan.c.
int dsl_scan_cancel | ( | dsl_pool_t * | dp | ) |
Definition at line 373 of file dsl_scan.c.
static int dsl_scan_cancel_check | ( | void * | arg1, |
void * | arg2, | ||
dmu_tx_t * | tx | ||
) | [static] |
Definition at line 353 of file dsl_scan.c.
static void dsl_scan_cancel_sync | ( | void * | arg1, |
void * | arg2, | ||
dmu_tx_t * | tx | ||
) | [static] |
Definition at line 364 of file dsl_scan.c.
static boolean_t dsl_scan_check_pause | ( | dsl_scan_t * | scn, |
const zbookmark_t * | zb | ||
) | [static] |
Definition at line 442 of file dsl_scan.c.
static boolean_t dsl_scan_check_resume | ( | dsl_scan_t * | scn, |
const dnode_phys_t * | dnp, | ||
const zbookmark_t * | zb | ||
) | [static] |
Definition at line 603 of file dsl_scan.c.
static void dsl_scan_ddt | ( | dsl_scan_t * | scn, |
dmu_tx_t * | tx | ||
) | [static] |
Scrub/dedup interaction.
If there are N references to a deduped block, we don't want to scrub it N times -- ideally, we should scrub it exactly once.
We leverage the fact that the dde's replication class (enum ddt_class) is ordered from highest replication class (DDT_CLASS_DITTO) to lowest (DDT_CLASS_UNIQUE) so that we may walk the DDT in that order.
To prevent excess scrubbing, the scrub begins by walking the DDT to find all blocks with refcnt > 1, and scrubs each of these once. Since there are two replication classes which contain blocks with refcnt > 1, we scrub the highest replication class (DDT_CLASS_DITTO) first. Finally the top-down scrub begins, only visiting blocks with refcnt == 1.
There would be nothing more to say if a block's refcnt couldn't change during a scrub, but of course it can so we must account for changes in a block's replication class.
Here's an example of what can occur:
If a block has refcnt > 1 during the DDT scrub phase, but has refcnt == 1 when visited during the top-down scrub phase, it will be scrubbed twice. This negates our scrub optimization, but is otherwise harmless.
If a block has refcnt == 1 during the DDT scrub phase, but has refcnt > 1 on each visit during the top-down scrub phase, it will never be scrubbed. To catch this, ddt_sync_entry() notifies the scrub code whenever a block's reference class transitions to a higher level (i.e DDT_CLASS_UNIQUE to DDT_CLASS_DUPLICATE); if it transitions from refcnt == 1 to refcnt > 1 while a scrub is in progress, it scrubs the block right then.
Definition at line 1224 of file dsl_scan.c.
void dsl_scan_ddt_entry | ( | dsl_scan_t * | scn, |
enum zio_checksum | checksum, | ||
ddt_entry_t * | dde, | ||
dmu_tx_t * | tx | ||
) |
Definition at line 1264 of file dsl_scan.c.
static void dsl_scan_done | ( | dsl_scan_t * | scn, |
boolean_t | complete, | ||
dmu_tx_t * | tx | ||
) | [static] |
Definition at line 273 of file dsl_scan.c.
void dsl_scan_ds_clone_swapped | ( | dsl_dataset_t * | ds1, |
dsl_dataset_t * | ds2, | ||
dmu_tx_t * | tx | ||
) |
Definition at line 948 of file dsl_scan.c.
void dsl_scan_ds_destroyed | ( | dsl_dataset_t * | ds, |
dmu_tx_t * | tx | ||
) |
Definition at line 853 of file dsl_scan.c.
static uint64_t dsl_scan_ds_maxtxg | ( | dsl_dataset_t * | ds | ) | [static] |
Definition at line 424 of file dsl_scan.c.
void dsl_scan_ds_snapshotted | ( | dsl_dataset_t * | ds, |
dmu_tx_t * | tx | ||
) |
Definition at line 914 of file dsl_scan.c.
void dsl_scan_fini | ( | dsl_pool_t * | dp | ) |
Definition at line 182 of file dsl_scan.c.
Definition at line 1386 of file dsl_scan.c.
static boolean_t dsl_scan_free_should_pause | ( | dsl_scan_t * | scn | ) | [static] |
Definition at line 1374 of file dsl_scan.c.
int dsl_scan_init | ( | dsl_pool_t * | dp, |
uint64_t | txg | ||
) |
Definition at line 123 of file dsl_scan.c.
static void dsl_scan_prefetch | ( | dsl_scan_t * | scn, |
arc_buf_t * | buf, | ||
blkptr_t * | bp, | ||
uint64_t | objset, | ||
uint64_t | object, | ||
uint64_t | blkid | ||
) | [static] |
Definition at line 578 of file dsl_scan.c.
static int dsl_scan_recurse | ( | dsl_scan_t * | scn, |
dsl_dataset_t * | ds, | ||
dmu_objset_type_t | ostype, | ||
dnode_phys_t * | dnp, | ||
const blkptr_t * | bp, | ||
const zbookmark_t * | zb, | ||
dmu_tx_t * | tx, | ||
arc_buf_t ** | bufp | ||
) | [static] |
Definition at line 643 of file dsl_scan.c.
boolean_t dsl_scan_resilvering | ( | dsl_pool_t * | dp | ) |
Definition at line 1592 of file dsl_scan.c.
static int dsl_scan_scrub_cb | ( | dsl_pool_t * | dp, |
const blkptr_t * | bp, | ||
const zbookmark_t * | zb | ||
) | [static] |
Definition at line 1669 of file dsl_scan.c.
static void dsl_scan_scrub_done | ( | zio_t * | zio | ) | [static] |
Definition at line 1651 of file dsl_scan.c.
static int dsl_scan_setup_check | ( | void * | arg1, |
void * | arg2, | ||
dmu_tx_t * | tx | ||
) | [static] |
Definition at line 192 of file dsl_scan.c.
static void dsl_scan_setup_sync | ( | void * | arg1, |
void * | arg2, | ||
dmu_tx_t * | tx | ||
) | [static] |
Definition at line 204 of file dsl_scan.c.
void dsl_scan_sync | ( | dsl_pool_t * | dp, |
dmu_tx_t * | tx | ||
) |
Definition at line 1431 of file dsl_scan.c.
static void dsl_scan_sync_state | ( | dsl_scan_t * | scn, |
dmu_tx_t * | tx | ||
) | [static] |
Definition at line 433 of file dsl_scan.c.
static void dsl_scan_visit | ( | dsl_scan_t * | scn, |
dmu_tx_t * | tx | ||
) | [static] |
Definition at line 1287 of file dsl_scan.c.
static void dsl_scan_visit_rootbp | ( | dsl_scan_t * | scn, |
dsl_dataset_t * | ds, | ||
blkptr_t * | bp, | ||
dmu_tx_t * | tx | ||
) | [static] |
Definition at line 839 of file dsl_scan.c.
static void dsl_scan_visitbp | ( | blkptr_t * | bp, |
const zbookmark_t * | zb, | ||
dnode_phys_t * | dnp, | ||
arc_buf_t * | pbuf, | ||
dsl_dataset_t * | ds, | ||
dsl_scan_t * | scn, | ||
dmu_objset_type_t | ostype, | ||
dmu_tx_t * | tx | ||
) | [static] |
Definition at line 778 of file dsl_scan.c.
static void dsl_scan_visitdnode | ( | dsl_scan_t * | scn, |
dsl_dataset_t * | ds, | ||
dmu_objset_type_t | ostype, | ||
dnode_phys_t * | dnp, | ||
arc_buf_t * | buf, | ||
uint64_t | object, | ||
dmu_tx_t * | tx | ||
) | [static] |
Definition at line 749 of file dsl_scan.c.
static void dsl_scan_visitds | ( | dsl_scan_t * | scn, |
uint64_t | dsobj, | ||
dmu_tx_t * | tx | ||
) | [static] |
Definition at line 1048 of file dsl_scan.c.
static void dsl_scan_zil | ( | dsl_pool_t * | dp, |
zil_header_t * | zh | ||
) | [static] |
Definition at line 555 of file dsl_scan.c.
static int dsl_scan_zil_block | ( | zilog_t * | zilog, |
blkptr_t * | bp, | ||
void * | arg, | ||
uint64_t | claim_txg | ||
) | [static] |
Definition at line 494 of file dsl_scan.c.
static int dsl_scan_zil_record | ( | zilog_t * | zilog, |
lr_t * | lrc, | ||
void * | arg, | ||
uint64_t | claim_txg | ||
) | [static] |
Definition at line 523 of file dsl_scan.c.
static int enqueue_cb | ( | spa_t * | spa, |
uint64_t | dsobj, | ||
const char * | dsname, | ||
void * | arg | ||
) | [static] |
Definition at line 1151 of file dsl_scan.c.
static int enqueue_clones_cb | ( | spa_t * | spa, |
uint64_t | dsobj, | ||
const char * | dsname, | ||
void * | arg | ||
) | [static] |
Definition at line 1016 of file dsl_scan.c.
dsl_syncfunc_t dsl_scan_cancel_sync [static] |
Definition at line 58 of file dsl_scan.c.
scan_cb_t dsl_scan_defrag_cb [static] |
Definition at line 55 of file dsl_scan.c.
scan_cb_t dsl_scan_remove_cb [static] |
Definition at line 57 of file dsl_scan.c.
scan_cb_t dsl_scan_scrub_cb [static] |
Definition at line 56 of file dsl_scan.c.
scan_cb_t* scan_funcs[POOL_SCAN_FUNCS] [static] |
{ NULL, dsl_scan_scrub_cb, dsl_scan_scrub_cb, }
Definition at line 116 of file dsl_scan.c.
enum ddt_class zfs_scrub_ddt_class_max = DDT_CLASS_DUPLICATE |
Definition at line 107 of file dsl_scan.c.