Restructuring of the soft updates code to set it up so that the
single kernel-wide soft update lock can be replaced with a per-filesystem soft-updates lock. This per-filesystem lock will allow each filesystem to have its own soft-updates flushing thread rather than being limited to a single soft-updates flushing thread for the entire kernel. Move soft update variables out of the ufsmount structure and into their own mount_softdeps structure referenced by ufsmount field um_softdep. Eventually the per-filesystem lock will be in this structure. For now there is simply a pointer to the kernel-wide soft updates lock. Change all instances of ACQUIRE_LOCK and FREE_LOCK to pass the lock pointer in the mount_softdeps structure instead of a pointer to the kernel-wide soft-updates lock. Replace the five hash tables used by soft updates with per-filesystem copies of these tables allocated in the mount_softdeps structure. Several functions that flush dependencies when too many are allocated in the kernel used to operate across all filesystems. They are now parameterized to flush dependencies from a specified filesystem. For now, we stick with the round-robin flushing strategy when the kernel as a whole has too many dependencies allocated. While there are many lines of changes, there should be no functional change in the operation of soft updates. Tested by: Peter Holm and Scott Long Sponsored by: Netflix
This commit is contained in:
parent
6064b6ac48
commit
58941b9f15
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=256817
File diff suppressed because it is too large
Load Diff
@ -143,6 +143,39 @@
|
||||
|
||||
#define ALLCOMPLETE (ATTACHED | COMPLETE | DEPCOMPLETE)
|
||||
|
||||
/*
|
||||
* Values for each of the soft dependency types.
|
||||
*/
|
||||
#define D_PAGEDEP 0
|
||||
#define D_INODEDEP 1
|
||||
#define D_BMSAFEMAP 2
|
||||
#define D_NEWBLK 3
|
||||
#define D_ALLOCDIRECT 4
|
||||
#define D_INDIRDEP 5
|
||||
#define D_ALLOCINDIR 6
|
||||
#define D_FREEFRAG 7
|
||||
#define D_FREEBLKS 8
|
||||
#define D_FREEFILE 9
|
||||
#define D_DIRADD 10
|
||||
#define D_MKDIR 11
|
||||
#define D_DIRREM 12
|
||||
#define D_NEWDIRBLK 13
|
||||
#define D_FREEWORK 14
|
||||
#define D_FREEDEP 15
|
||||
#define D_JADDREF 16
|
||||
#define D_JREMREF 17
|
||||
#define D_JMVREF 18
|
||||
#define D_JNEWBLK 19
|
||||
#define D_JFREEBLK 20
|
||||
#define D_JFREEFRAG 21
|
||||
#define D_JSEG 22
|
||||
#define D_JSEGDEP 23
|
||||
#define D_SBDEP 24
|
||||
#define D_JTRUNC 25
|
||||
#define D_JFSYNC 26
|
||||
#define D_SENTINEL 27
|
||||
#define D_LAST D_SENTINEL
|
||||
|
||||
/*
|
||||
* The workitem queue.
|
||||
*
|
||||
@ -416,7 +449,8 @@ struct newblk {
|
||||
*/
|
||||
struct allocdirect {
|
||||
struct newblk ad_block; /* Common block logic */
|
||||
# define ad_state ad_block.nb_list.wk_state /* block pointer state */
|
||||
# define ad_list ad_block.nb_list /* block pointer worklist */
|
||||
# define ad_state ad_list.wk_state /* block pointer state */
|
||||
TAILQ_ENTRY(allocdirect) ad_next; /* inodedep's list of allocdirect's */
|
||||
struct inodedep *ad_inodedep; /* associated inodedep */
|
||||
ufs2_daddr_t ad_oldblkno; /* old value of block pointer */
|
||||
@ -947,3 +981,106 @@ struct sbdep {
|
||||
struct fs *sb_fs; /* Filesystem pointer within buf. */
|
||||
struct ufsmount *sb_ump; /* Our mount structure */
|
||||
};
|
||||
|
||||
/*
|
||||
* Private journaling structures.
|
||||
*/
|
||||
struct jblocks {
|
||||
struct jseglst jb_segs; /* TAILQ of current segments. */
|
||||
struct jseg *jb_writeseg; /* Next write to complete. */
|
||||
struct jseg *jb_oldestseg; /* Oldest segment with valid entries. */
|
||||
struct jextent *jb_extent; /* Extent array. */
|
||||
uint64_t jb_nextseq; /* Next sequence number. */
|
||||
uint64_t jb_oldestwrseq; /* Oldest written sequence number. */
|
||||
uint8_t jb_needseg; /* Need a forced segment. */
|
||||
uint8_t jb_suspended; /* Did journal suspend writes? */
|
||||
int jb_avail; /* Available extents. */
|
||||
int jb_used; /* Last used extent. */
|
||||
int jb_head; /* Allocator head. */
|
||||
int jb_off; /* Allocator extent offset. */
|
||||
int jb_blocks; /* Total disk blocks covered. */
|
||||
int jb_free; /* Total disk blocks free. */
|
||||
int jb_min; /* Minimum free space. */
|
||||
int jb_low; /* Low on space. */
|
||||
int jb_age; /* Insertion time of oldest rec. */
|
||||
};
|
||||
|
||||
struct jextent {
|
||||
ufs2_daddr_t je_daddr; /* Disk block address. */
|
||||
int je_blocks; /* Disk block count. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Hash table declarations.
|
||||
*/
|
||||
LIST_HEAD(mkdirlist, mkdir);
|
||||
LIST_HEAD(pagedep_hashhead, pagedep);
|
||||
LIST_HEAD(inodedep_hashhead, inodedep);
|
||||
LIST_HEAD(newblk_hashhead, newblk);
|
||||
LIST_HEAD(bmsafemap_hashhead, bmsafemap);
|
||||
TAILQ_HEAD(indir_hashhead, freework);
|
||||
|
||||
/*
|
||||
* Per-filesystem soft dependency data.
|
||||
* Allocated at mount and freed at unmount.
|
||||
*/
|
||||
struct mount_softdeps {
|
||||
struct rwlock *sd_fslock; /* softdep lock */
|
||||
struct workhead sd_workitem_pending; /* softdep work queue */
|
||||
struct worklist *sd_worklist_tail; /* Tail pointer for above */
|
||||
struct workhead sd_journal_pending; /* journal work queue */
|
||||
struct worklist *sd_journal_tail; /* Tail pointer for above */
|
||||
struct jblocks *sd_jblocks; /* Journal block information */
|
||||
struct inodedeplst sd_unlinked; /* Unlinked inodes */
|
||||
struct bmsafemaphd sd_dirtycg; /* Dirty CGs */
|
||||
struct mkdirlist sd_mkdirlisthd; /* Track mkdirs */
|
||||
struct pagedep_hashhead *sd_pdhash; /* pagedep hash table */
|
||||
u_long sd_pdhashsize; /* pagedep hash table size-1 */
|
||||
long sd_pdnextclean; /* next hash bucket to clean */
|
||||
struct inodedep_hashhead *sd_idhash; /* inodedep hash table */
|
||||
u_long sd_idhashsize; /* inodedep hash table size-1 */
|
||||
long sd_idnextclean; /* next hash bucket to clean */
|
||||
struct newblk_hashhead *sd_newblkhash; /* newblk hash table */
|
||||
u_long sd_newblkhashsize; /* newblk hash table size-1 */
|
||||
struct bmsafemap_hashhead *sd_bmhash; /* bmsafemap hash table */
|
||||
u_long sd_bmhashsize; /* bmsafemap hash table size-1*/
|
||||
struct indir_hashhead *sd_indirhash; /* indir hash table */
|
||||
u_long sd_indirhashsize; /* indir hash table size-1 */
|
||||
long sd_numindirdeps; /* outstanding indirdeps */
|
||||
int sd_on_journal; /* Items on the journal list */
|
||||
int sd_on_worklist; /* Items on the worklist */
|
||||
int sd_deps; /* Total dependency count */
|
||||
int sd_accdeps; /* accumulated dep count */
|
||||
int sd_req; /* Wakeup when deps hits 0. */
|
||||
u_long sd_curdeps[D_LAST + 1]; /* count of current deps */
|
||||
};
|
||||
/*
|
||||
* Keep the old names from when these were in the ufsmount structure.
|
||||
*/
|
||||
#define softdep_workitem_pending um_softdep->sd_workitem_pending
|
||||
#define softdep_worklist_tail um_softdep->sd_worklist_tail
|
||||
#define softdep_journal_pending um_softdep->sd_journal_pending
|
||||
#define softdep_journal_tail um_softdep->sd_journal_tail
|
||||
#define softdep_jblocks um_softdep->sd_jblocks
|
||||
#define softdep_unlinked um_softdep->sd_unlinked
|
||||
#define softdep_dirtycg um_softdep->sd_dirtycg
|
||||
#define softdep_mkdirlisthd um_softdep->sd_mkdirlisthd
|
||||
#define pagedep_hashtbl um_softdep->sd_pdhash
|
||||
#define pagedep_hash_size um_softdep->sd_pdhashsize
|
||||
#define pagedep_nextclean um_softdep->sd_pdnextclean
|
||||
#define inodedep_hashtbl um_softdep->sd_idhash
|
||||
#define inodedep_hash_size um_softdep->sd_idhashsize
|
||||
#define inodedep_nextclean um_softdep->sd_idnextclean
|
||||
#define newblk_hashtbl um_softdep->sd_newblkhash
|
||||
#define newblk_hash_size um_softdep->sd_newblkhashsize
|
||||
#define bmsafemap_hashtbl um_softdep->sd_bmhash
|
||||
#define bmsafemap_hash_size um_softdep->sd_bmhashsize
|
||||
#define indir_hashtbl um_softdep->sd_indirhash
|
||||
#define indir_hash_size um_softdep->sd_indirhashsize
|
||||
#define softdep_numindirdeps um_softdep->sd_numindirdeps
|
||||
#define softdep_on_journal um_softdep->sd_on_journal
|
||||
#define softdep_on_worklist um_softdep->sd_on_worklist
|
||||
#define softdep_deps um_softdep->sd_deps
|
||||
#define softdep_accdeps um_softdep->sd_accdeps
|
||||
#define softdep_req um_softdep->sd_req
|
||||
#define softdep_curdeps um_softdep->sd_curdeps
|
||||
|
@ -78,19 +78,7 @@ struct ufsmount {
|
||||
u_long um_seqinc; /* inc between seq blocks */
|
||||
struct mtx um_lock; /* Protects ufsmount & fs */
|
||||
pid_t um_fsckpid; /* PID permitted fsck sysctls */
|
||||
long um_numindirdeps; /* outstanding indirdeps */
|
||||
struct workhead softdep_workitem_pending; /* softdep work queue */
|
||||
struct worklist *softdep_worklist_tail; /* Tail pointer for above */
|
||||
struct workhead softdep_journal_pending; /* journal work queue */
|
||||
struct worklist *softdep_journal_tail; /* Tail pointer for above */
|
||||
struct jblocks *softdep_jblocks; /* Journal block information */
|
||||
struct inodedeplst softdep_unlinked; /* Unlinked inodes */
|
||||
struct bmsafemaphd softdep_dirtycg; /* Dirty CGs */
|
||||
int softdep_on_journal; /* Items on the journal list */
|
||||
int softdep_on_worklist; /* Items on the worklist */
|
||||
int softdep_deps; /* Total dependency count */
|
||||
int softdep_accdeps; /* accumulated dep count */
|
||||
int softdep_req; /* Wakeup when deps hits 0. */
|
||||
struct mount_softdeps *um_softdep; /* softdep mgmt structure */
|
||||
struct vnode *um_quotas[MAXQUOTAS]; /* pointer to quota files */
|
||||
struct ucred *um_cred[MAXQUOTAS]; /* quota file access cred */
|
||||
time_t um_btime[MAXQUOTAS]; /* block quota time limit */
|
||||
|
Loading…
Reference in New Issue
Block a user