diff options
author | Alek P <[email protected]> | 2019-02-12 10:41:15 -0800 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2019-02-12 10:41:15 -0800 |
commit | dcec0a12c8e480262288ac76f6350652079ea173 (patch) | |
tree | 1f23e1c575dc61d00484b627f61e1b5e9ba6bac0 /include/sys | |
parent | 425d3237ee88abc53d8522a7139c926d278b4b7f (diff) |
port async unlinked drain from illumos-nexenta
This patch is an async implementation of the existing sync
zfs_unlinked_drain() function. This function is called at mount time and
is responsible for freeing znodes that we didn't get to freeing before.
We don't have to hold mounting of the dataset until the unlinked list is
fully drained as is done now. Since we can process the unlinked set
asynchronously this results in a better user experience when mounting a
dataset with entries in the unlinked set.
Reviewed by: Jorgen Lundman <[email protected]>
Reviewed by: Tom Caputi <[email protected]>
Reviewed by: Brian Behlendorf <[email protected]>
Reviewed-by: Matt Ahrens <[email protected]>
Reviewed by: Paul Dagnelie <[email protected]>
Signed-off-by: Alek Pinchuk <[email protected]>
Closes #8142
Diffstat (limited to 'include/sys')
-rw-r--r-- | include/sys/dataset_kstats.h | 16 | ||||
-rw-r--r-- | include/sys/dsl_pool.h | 2 | ||||
-rw-r--r-- | include/sys/zfs_dir.h | 1 | ||||
-rw-r--r-- | include/sys/zfs_vfsops.h | 3 |
4 files changed, 22 insertions, 0 deletions
diff --git a/include/sys/dataset_kstats.h b/include/sys/dataset_kstats.h index 5dd9a8e61..667d1b85f 100644 --- a/include/sys/dataset_kstats.h +++ b/include/sys/dataset_kstats.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2018 by Delphix. All rights reserved. + * Copyright (c) 2018 Datto Inc. */ #ifndef _SYS_DATASET_KSTATS_H @@ -35,6 +36,8 @@ typedef struct dataset_aggsum_stats_t { aggsum_t das_nwritten; aggsum_t das_reads; aggsum_t das_nread; + aggsum_t das_nunlinks; + aggsum_t das_nunlinked; } dataset_aggsum_stats_t; typedef struct dataset_kstat_values { @@ -43,6 +46,16 @@ typedef struct dataset_kstat_values { kstat_named_t dkv_nwritten; kstat_named_t dkv_reads; kstat_named_t dkv_nread; + /* + * nunlinks is initialized to the unlinked set size on mount and + * is incremented whenever a new entry is added to the unlinked set + */ + kstat_named_t dkv_nunlinks; + /* + * nunlinked is initialized to zero on mount and is incremented when an + * entry is removed from the unlinked set + */ + kstat_named_t dkv_nunlinked; } dataset_kstat_values_t; typedef struct dataset_kstats { @@ -56,4 +69,7 @@ void dataset_kstats_destroy(dataset_kstats_t *); void dataset_kstats_update_write_kstats(dataset_kstats_t *, int64_t); void dataset_kstats_update_read_kstats(dataset_kstats_t *, int64_t); +void dataset_kstats_update_nunlinks_kstat(dataset_kstats_t *, int64_t); +void dataset_kstats_update_nunlinked_kstat(dataset_kstats_t *, int64_t); + #endif /* _SYS_DATASET_KSTATS_H */ diff --git a/include/sys/dsl_pool.h b/include/sys/dsl_pool.h index 56317cf73..63ba3509a 100644 --- a/include/sys/dsl_pool.h +++ b/include/sys/dsl_pool.h @@ -96,6 +96,7 @@ typedef struct dsl_pool { struct dsl_dataset *dp_origin_snap; uint64_t dp_root_dir_obj; struct taskq *dp_iput_taskq; + struct taskq *dp_unlinked_drain_taskq; /* No lock needed - sync context only */ blkptr_t dp_meta_rootbp; @@ -176,6 +177,7 @@ boolean_t dsl_pool_config_held(dsl_pool_t *dp); boolean_t dsl_pool_config_held_writer(dsl_pool_t *dp); taskq_t *dsl_pool_iput_taskq(dsl_pool_t *dp); +taskq_t *dsl_pool_unlinked_drain_taskq(dsl_pool_t *dp); int dsl_pool_user_hold(dsl_pool_t *dp, uint64_t dsobj, const char *tag, uint64_t now, dmu_tx_t *tx); diff --git a/include/sys/zfs_dir.h b/include/sys/zfs_dir.h index 9ce3accfc..bcd4ec2c1 100644 --- a/include/sys/zfs_dir.h +++ b/include/sys/zfs_dir.h @@ -64,6 +64,7 @@ extern void zfs_dl_name_switch(zfs_dirlock_t *dl, char *new, char **old); extern boolean_t zfs_dirempty(znode_t *); extern void zfs_unlinked_add(znode_t *, dmu_tx_t *); extern void zfs_unlinked_drain(zfsvfs_t *zfsvfs); +extern void zfs_unlinked_drain_stop_wait(zfsvfs_t *zfsvfs); extern int zfs_sticky_remove_access(znode_t *, znode_t *, cred_t *cr); extern int zfs_get_xattrdir(znode_t *, struct inode **, cred_t *, int); extern int zfs_make_xattrdir(znode_t *, vattr_t *, struct inode **, cred_t *); diff --git a/include/sys/zfs_vfsops.h b/include/sys/zfs_vfsops.h index 0a4f52f2f..cad0aaece 100644 --- a/include/sys/zfs_vfsops.h +++ b/include/sys/zfs_vfsops.h @@ -117,6 +117,8 @@ struct zfsvfs { boolean_t z_replay; /* set during ZIL replay */ boolean_t z_use_sa; /* version allow system attributes */ boolean_t z_xattr_sa; /* allow xattrs to be stores as SA */ + boolean_t z_draining; /* is true when drain is active */ + boolean_t z_drain_cancel; /* signal the unlinked drain to stop */ uint64_t z_version; /* ZPL version */ uint64_t z_shares_dir; /* hidden shares dir */ dataset_kstats_t z_kstat; /* fs kstats */ @@ -132,6 +134,7 @@ struct zfsvfs { uint64_t z_hold_size; /* znode hold array size */ avl_tree_t *z_hold_trees; /* znode hold trees */ kmutex_t *z_hold_locks; /* znode hold locks */ + taskqid_t z_drain_task; /* task id for the unlink drain task */ }; #define ZSB_XATTR 0x0001 /* Enable user xattrs */ |