diff options
author | mckusick <mckusick@FreeBSD.org> | 2013-12-30 05:22:22 +0000 |
---|---|---|
committer | mckusick <mckusick@FreeBSD.org> | 2013-12-30 05:22:22 +0000 |
commit | fc0cf4002785ad6522bbca2fe8b339ec492e7c17 (patch) | |
tree | 1467f591fde2e8d982f760d417f9726f1c478876 /sys/ufs/ffs/softdep.h | |
parent | db06903b8464dde6952e2099f6625f6df1760fe9 (diff) | |
download | FreeBSD-src-fc0cf4002785ad6522bbca2fe8b339ec492e7c17.zip FreeBSD-src-fc0cf4002785ad6522bbca2fe8b339ec492e7c17.tar.gz |
MFC of 256801, 256803, 256808, 256812, 256817, 256845, and 256860.
This set of changes puts in place the infrastructure to allow soft
updates to be multi-threaded. It introduces no functional changes
from its current operation.
MFC of 256860:
Allow kernels without options SOFTUPDATES to build. This should fix the
embedded tinderboxes.
Reviewed by: emaste
MFC of 256845:
Fix build problem on ARM (which defaults to building without soft updates).
Reported by: Tinderbox
Sponsored by: Netflix
MFC of 256817:
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
MFC of 256812:
Fourth of several cleanups to soft dependency implementation.
Add KASSERTS that soft dependency functions only get called
for filesystems running with soft dependencies. Calling these
functions when soft updates are not compiled into the system
become panic's.
No functional change.
Tested by: Peter Holm and Scott Long
Sponsored by: Netflix
MFC of 256808:
Third of several cleanups to soft dependency implementation.
Ensure that softdep_unmount() and softdep_setup_sbupdate()
only get called for filesystems running with soft dependencies.
No functional change.
Tested by: Peter Holm and Scott Long
Sponsored by: Netflix
MFC of 256803:
Second of several cleanups to soft dependency implementation.
Delete two unused functions in ffs_sofdep.c.
No functional change.
Tested by: Peter Holm and Scott Long
Sponsored by: Netflix
MFC of 256801:
First of several cleanups to soft dependency implementation.
Convert three functions exported from ffs_softdep.c to static
functions as they are not used outside of ffs_softdep.c.
No functional change.
Tested by: Peter Holm and Scott Long
Sponsored by: Netflix
Diffstat (limited to 'sys/ufs/ffs/softdep.h')
-rw-r--r-- | sys/ufs/ffs/softdep.h | 139 |
1 files changed, 138 insertions, 1 deletions
diff --git a/sys/ufs/ffs/softdep.h b/sys/ufs/ffs/softdep.h index b251ba8..8a8a63a 100644 --- a/sys/ufs/ffs/softdep.h +++ b/sys/ufs/ffs/softdep.h @@ -144,6 +144,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. * * It is sometimes useful and/or necessary to clean up certain dependencies @@ -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 |