FreeBSD ZFS
The Zettabyte File System
Data Structures | Defines | Typedefs | Functions | Variables

dsl_scan.c File Reference

#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>
Include dependency graph for dsl_scan.c:

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_tscan_funcs [POOL_SCAN_FUNCS]

Define Documentation

#define DSL_SCAN_IS_SCRUB_RESILVER (   scn)
Value:
((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 Documentation

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

Function Documentation

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.

static int dsl_scan_free_block_cb ( void *  arg,
const blkptr_t bp,
dmu_tx_t tx 
) [static]

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.


Variable Documentation

dsl_syncfunc_t dsl_scan_cancel_sync [static]

Definition at line 58 of file dsl_scan.c.

Definition at line 55 of file dsl_scan.c.

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]
Initial value:

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.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines