From c152fb8d2c26fabd1f7f53d8e9631bc8f385dddb Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sat, 9 Sep 2017 10:16:36 -0700 Subject: [PATCH] hammer2 - API breadnx / cluster_read API, bulkfree adj * API adjustments for breadnx() and cluster_readx() calls. Properly separate data and meta-data flagging for better swapcache operation. * Separate cluster read parameters for data and meta-data. Default data to 4 (+3 read-ahead) and meta-data to 1 (no read-ahead). --- sys/vfs/hammer2/hammer2.h | 3 +- sys/vfs/hammer2/hammer2_bulkfree.c | 58 ++++++++++++++++++++++++++++++-------- sys/vfs/hammer2/hammer2_chain.c | 2 +- sys/vfs/hammer2/hammer2_io.c | 40 ++++++++++++++++---------- sys/vfs/hammer2/hammer2_vfsops.c | 9 ++++-- 5 files changed, 81 insertions(+), 31 deletions(-) diff --git a/sys/vfs/hammer2/hammer2.h b/sys/vfs/hammer2/hammer2.h index ea5fd9ff8a..d8e804f59f 100644 --- a/sys/vfs/hammer2/hammer2.h +++ b/sys/vfs/hammer2/hammer2.h @@ -1342,7 +1342,8 @@ extern struct lock hammer2_mntlk; extern int hammer2_debug; -extern int hammer2_cluster_read; +extern int hammer2_cluster_meta_read; +extern int hammer2_cluster_data_read; extern int hammer2_cluster_write; extern int hammer2_dedup_enable; extern int hammer2_always_compress; diff --git a/sys/vfs/hammer2/hammer2_bulkfree.c b/sys/vfs/hammer2/hammer2_bulkfree.c index 5357428048..3fd4728830 100644 --- a/sys/vfs/hammer2/hammer2_bulkfree.c +++ b/sys/vfs/hammer2/hammer2_bulkfree.c @@ -82,8 +82,11 @@ typedef struct hammer2_bulkfree_info { long count_l0cleans; long count_linadjusts; long count_inodes_scanned; + long count_dirents_scanned; long count_dedup_factor; - long bytes_scanned; + long count_bytes_scanned; + long count_chains_scanned; + long count_chains_reported; hammer2_off_t adj_free; hammer2_tid_t mtid; hammer2_tid_t saved_mirror_tid; @@ -141,6 +144,15 @@ hammer2_bulk_scan(hammer2_chain_t *parent, if (error) break; + if (bref.type == HAMMER2_BREF_TYPE_DIRENT) + ++info->count_dirents_scanned; + + /* + * Ignore brefs without data (typically dirents) + */ + if ((bref.data_off & ~HAMMER2_OFF_MASK_RADIX) == 0) + continue; + /* * Process bref, chain is only non-NULL if the bref * might be recursable (its possible that we sometimes get @@ -150,6 +162,9 @@ hammer2_bulk_scan(hammer2_chain_t *parent, if (h2_bulkfree_test(info, &bref, 1)) continue; + if (bref.type == HAMMER2_BREF_TYPE_INODE) + ++info->count_inodes_scanned; + error |= func(info, &bref); if (error) break; @@ -162,13 +177,28 @@ hammer2_bulk_scan(hammer2_chain_t *parent, if (chain == NULL) continue; + if (chain) { + info->count_bytes_scanned += chain->bytes; + ++info->count_chains_scanned; + + if (info->count_chains_scanned >= + info->count_chains_reported + 50000) { + kprintf(" chains %-7ld inodes %-7ld " + "dirents %-7ld bytes %5ldMB\n", + info->count_chains_scanned, + info->count_inodes_scanned, + info->count_dirents_scanned, + info->count_bytes_scanned / 1000000); + info->count_chains_reported += 50000; + } + } + + /* * Else check type and setup depth-first scan. * * Account for bytes actually read. */ - info->bytes_scanned += chain->bytes; - switch(chain->bref.type) { case HAMMER2_BREF_TYPE_INODE: case HAMMER2_BREF_TYPE_FREEMAP_NODE: @@ -204,6 +234,9 @@ hammer2_bulk_scan(hammer2_chain_t *parent, } --info->depth; break; + case HAMMER2_BREF_TYPE_DATA: + kprintf("X"); + break; default: /* does not recurse */ break; @@ -350,6 +383,11 @@ hammer2_bulkfree_pass(hammer2_dev_t *hmp, hammer2_chain_t *vchain, bzero(&cbinfo, sizeof(cbinfo)); size = (bfi->size + HAMMER2_FREEMAP_LEVELN_PSIZE - 1) & ~(size_t)(HAMMER2_FREEMAP_LEVELN_PSIZE - 1); + if (size < 1024 * 1024) + size = 1024 * 1024; + if (size > 64 * 1024 * 1024) + size = 64 * 1024 * 1024; + cbinfo.hmp = hmp; cbinfo.bmap = kmem_alloc_swapbacked(&cbinfo.kp, size, VM_SUBSYS_HAMMER); cbinfo.saved_mirror_tid = hmp->voldata.mirror_tid; @@ -387,6 +425,12 @@ hammer2_bulkfree_pass(hammer2_dev_t *hmp, hammer2_chain_t *vchain, cbinfo_bmap_init(&cbinfo, size); bzero(cbinfo.dedup, sizeof(*cbinfo.dedup) * HAMMER2_DEDUP_HEUR_SIZE); + cbinfo.count_inodes_scanned = 0; + cbinfo.count_dirents_scanned = 0; + cbinfo.count_bytes_scanned = 0; + cbinfo.count_chains_scanned = 0; + cbinfo.count_chains_reported = 0; + incr = size / HAMMER2_FREEMAP_LEVELN_PSIZE * HAMMER2_FREEMAP_LEVEL1_SIZE; if (hmp->voldata.volu_size - cbinfo.sbase < incr) @@ -548,14 +592,6 @@ h2_bulkfree_callback(hammer2_bulkfree_info_t *cbinfo, hammer2_blockref_t *bref) if (hammer2_signal_check(&cbinfo->save_time)) return HAMMER2_ERROR_ABORTED; - if (bref->type == HAMMER2_BREF_TYPE_INODE) { - ++cbinfo->count_inodes_scanned; - if ((cbinfo->count_inodes_scanned & 65535) == 0) - kprintf(" inodes %6ld bytes %9ld\n", - cbinfo->count_inodes_scanned, - cbinfo->bytes_scanned); - } - /* * Calculate the data offset and determine if it is within * the current freemap range being gathered. diff --git a/sys/vfs/hammer2/hammer2_chain.c b/sys/vfs/hammer2/hammer2_chain.c index a225eb1e40..af115e44e1 100644 --- a/sys/vfs/hammer2/hammer2_chain.c +++ b/sys/vfs/hammer2/hammer2_chain.c @@ -2751,7 +2751,7 @@ hammer2_chain_next(hammer2_chain_t **parentp, hammer2_chain_t *chain, * locked and referenced. Any prior contents will be unlocked and dropped. * * Caller should check the return value. A normal scan EOF will return - * exactly HAMMER2_ERRORF_EOF. Any other non-zero value indicates an + * exactly HAMMER2_ERROR_EOF. Any other non-zero value indicates an * error trying to access parent data. Any error in the returned chain * must be tested separately by the caller. * diff --git a/sys/vfs/hammer2/hammer2_io.c b/sys/vfs/hammer2/hammer2_io.c index bb47e2d8d8..efa43cbe4c 100644 --- a/sys/vfs/hammer2/hammer2_io.c +++ b/sys/vfs/hammer2/hammer2_io.c @@ -191,6 +191,7 @@ hammer2_io_getblk(hammer2_dev_t *hmp, int btype, off_t lbase, int lsize, int op) int isgood; int error; int hce; + int notmetaflag = ((btype == HAMMER2_BREF_TYPE_DATA) ? B_NOTMETA : 0); KKASSERT((1 << (int)(lbase & HAMMER2_OFF_MASK_RADIX)) == lsize); @@ -252,6 +253,10 @@ hammer2_io_getblk(hammer2_dev_t *hmp, int btype, off_t lbase, int lsize, int op) * the I/O. */ KKASSERT(dio->bp == NULL); + if (btype == HAMMER2_BREF_TYPE_DATA) + hce = hammer2_cluster_data_read; + else + hce = hammer2_cluster_meta_read; error = 0; if (dio->pbase == (lbase & ~HAMMER2_OFF_MASK_RADIX) && @@ -268,39 +273,42 @@ hammer2_io_getblk(hammer2_dev_t *hmp, int btype, off_t lbase, int lsize, int op) break; case HAMMER2_DOP_READ: default: - if ((hce = hammer2_cluster_read) > 0) { + if (hce > 0) { /* * Synchronous cluster I/O for now. */ peof = (dio->pbase + HAMMER2_SEGMASK64) & ~HAMMER2_SEGMASK64; - error = cluster_read(dio->hmp->devvp, + dio->bp = NULL; + error = cluster_readx(dio->hmp->devvp, peof, dio->pbase, - dio->psize, + dio->psize, notmetaflag, dio->psize, HAMMER2_PBUFSIZE*hce, &dio->bp); } else { - error = bread(dio->hmp->devvp, dio->pbase, - dio->psize, &dio->bp); + dio->bp = NULL; + error = breadnx(dio->hmp->devvp, dio->pbase, + dio->psize, notmetaflag, + NULL, NULL, 0, &dio->bp); } } } else { - if ((hce = hammer2_cluster_read) > 0) { + if (hce > 0) { /* * Synchronous cluster I/O for now. */ peof = (dio->pbase + HAMMER2_SEGMASK64) & ~HAMMER2_SEGMASK64; - error = cluster_read(dio->hmp->devvp, - peof, dio->pbase, - dio->psize, - dio->psize, - HAMMER2_PBUFSIZE*hce, - &dio->bp); + error = cluster_readx(dio->hmp->devvp, + peof, dio->pbase, dio->psize, + notmetaflag, + dio->psize, HAMMER2_PBUFSIZE*hce, + &dio->bp); } else { - error = bread(dio->hmp->devvp, dio->pbase, - dio->psize, &dio->bp); + error = breadnx(dio->hmp->devvp, dio->pbase, + dio->psize, notmetaflag, + NULL, NULL, 0, &dio->bp); } if (dio->bp) { /* @@ -334,8 +342,10 @@ hammer2_io_getblk(hammer2_dev_t *hmp, int btype, off_t lbase, int lsize, int op) } } - if (dio->bp) + if (dio->bp) { BUF_KERNPROC(dio->bp); + dio->bp->b_flags &= ~B_AGE; + } dio->error = error; /* diff --git a/sys/vfs/hammer2/hammer2_vfsops.c b/sys/vfs/hammer2/hammer2_vfsops.c index 004ae861f1..d8d2d24fbc 100644 --- a/sys/vfs/hammer2/hammer2_vfsops.c +++ b/sys/vfs/hammer2/hammer2_vfsops.c @@ -78,7 +78,8 @@ struct hammer2_pfslist hammer2_pfslist; struct lock hammer2_mntlk; int hammer2_debug; -int hammer2_cluster_read = 4; /* physical read-ahead */ +int hammer2_cluster_meta_read = 1; /* physical read-ahead */ +int hammer2_cluster_data_read = 4; /* physical read-ahead */ int hammer2_cluster_write = 0; /* bdwrite() so later inval works */ int hammer2_dedup_enable = 1; int hammer2_always_compress = 0; /* always try to compress */ @@ -118,8 +119,10 @@ SYSCTL_NODE(_vfs, OID_AUTO, hammer2, CTLFLAG_RW, 0, "HAMMER2 filesystem"); SYSCTL_INT(_vfs_hammer2, OID_AUTO, debug, CTLFLAG_RW, &hammer2_debug, 0, ""); -SYSCTL_INT(_vfs_hammer2, OID_AUTO, cluster_read, CTLFLAG_RW, - &hammer2_cluster_read, 0, ""); +SYSCTL_INT(_vfs_hammer2, OID_AUTO, cluster_meta_read, CTLFLAG_RW, + &hammer2_cluster_meta_read, 0, ""); +SYSCTL_INT(_vfs_hammer2, OID_AUTO, cluster_data_read, CTLFLAG_RW, + &hammer2_cluster_data_read, 0, ""); SYSCTL_INT(_vfs_hammer2, OID_AUTO, cluster_write, CTLFLAG_RW, &hammer2_cluster_write, 0, ""); SYSCTL_INT(_vfs_hammer2, OID_AUTO, dedup_enable, CTLFLAG_RW, -- 2.11.4.GIT