summaryrefslogtreecommitdiffstats
path: root/sys/ufs/ffs/softdep.h
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2013-12-30 05:22:22 +0000
committermckusick <mckusick@FreeBSD.org>2013-12-30 05:22:22 +0000
commitfc0cf4002785ad6522bbca2fe8b339ec492e7c17 (patch)
tree1467f591fde2e8d982f760d417f9726f1c478876 /sys/ufs/ffs/softdep.h
parentdb06903b8464dde6952e2099f6625f6df1760fe9 (diff)
downloadFreeBSD-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.h139
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
OpenPOWER on IntegriCloud