Module Name: src Committed By: jdolecek Date: Sat Oct 1 13:15:45 UTC 2016
Modified Files: src/sys/kern: vfs_wapbl.c src/sys/sys: wapbl.h src/sys/ufs/ffs: ffs_extern.h ffs_wapbl.c Log Message: allocate wapbl dealloc registration structures via pool, so that there is more flexibility with limit handling To generate a diff of this commit: cvs rdiff -u -r1.80 -r1.81 src/sys/kern/vfs_wapbl.c cvs rdiff -u -r1.17 -r1.18 src/sys/sys/wapbl.h cvs rdiff -u -r1.82 -r1.83 src/sys/ufs/ffs/ffs_extern.h cvs rdiff -u -r1.33 -r1.34 src/sys/ufs/ffs/ffs_wapbl.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/vfs_wapbl.c diff -u src/sys/kern/vfs_wapbl.c:1.80 src/sys/kern/vfs_wapbl.c:1.81 --- src/sys/kern/vfs_wapbl.c:1.80 Thu Sep 22 16:22:29 2016 +++ src/sys/kern/vfs_wapbl.c Sat Oct 1 13:15:45 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_wapbl.c,v 1.80 2016/09/22 16:22:29 jdolecek Exp $ */ +/* $NetBSD: vfs_wapbl.c,v 1.81 2016/10/01 13:15:45 jdolecek Exp $ */ /*- * Copyright (c) 2003, 2008, 2009 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ #define WAPBL_INTERNAL #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_wapbl.c,v 1.80 2016/09/22 16:22:29 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_wapbl.c,v 1.81 2016/10/01 13:15:45 jdolecek Exp $"); #include <sys/param.h> #include <sys/bitops.h> @@ -206,10 +206,9 @@ struct wapbl { int wl_brperjblock; /* r Block records per journal block */ #endif - daddr_t *wl_deallocblks;/* lm: address of block */ - int *wl_dealloclens; /* lm: size of block */ - int wl_dealloccnt; /* lm: total count */ - int wl_dealloclim; /* l: max count */ + SIMPLEQ_HEAD(, wapbl_dealloc) wl_dealloclist; /* lm: list head */ + int wl_dealloccnt; /* lm: total count */ + int wl_dealloclim; /* r: max count */ /* hashtable of inode numbers for allocated but unlinked inodes */ /* synch ??? */ @@ -250,6 +249,7 @@ static inline size_t wapbl_space_used(si #ifdef _KERNEL static struct pool wapbl_entry_pool; +static struct pool wapbl_dealloc_pool; #define WAPBL_INODETRK_SIZE 83 static int wapbl_ino_pool_refcount; @@ -330,6 +330,8 @@ wapbl_init(void) pool_init(&wapbl_entry_pool, sizeof(struct wapbl_entry), 0, 0, 0, "wapblentrypl", &pool_allocator_kmem, IPL_VM); + pool_init(&wapbl_dealloc_pool, sizeof(struct wapbl_dealloc), 0, 0, 0, + "wapbldealloc", &pool_allocator_nointr, IPL_NONE); wapbl_sysctl_init(); } @@ -341,6 +343,7 @@ wapbl_fini(void) if (wapbl_sysctl != NULL) sysctl_teardown(&wapbl_sysctl); + pool_destroy(&wapbl_dealloc_pool); pool_destroy(&wapbl_entry_pool); return 0; @@ -509,12 +512,8 @@ wapbl_start(struct wapbl ** wlp, struct /* XXX tie this into resource estimation */ wl->wl_dealloclim = wl->wl_bufbytes_max / mp->mnt_stat.f_bsize / 2; + SIMPLEQ_INIT(&wl->wl_dealloclist); - wl->wl_deallocblks = wapbl_alloc(sizeof(*wl->wl_deallocblks) * - wl->wl_dealloclim); - wl->wl_dealloclens = wapbl_alloc(sizeof(*wl->wl_dealloclens) * - wl->wl_dealloclim); - wl->wl_buffer = wapbl_alloc(MAXPHYS); wl->wl_buffer_used = 0; @@ -562,10 +561,6 @@ wapbl_start(struct wapbl ** wlp, struct wapbl_discard(wl); wapbl_free(wl->wl_wc_scratch, wl->wl_wc_header->wc_len); wapbl_free(wl->wl_wc_header, wl->wl_wc_header->wc_len); - wapbl_free(wl->wl_deallocblks, - sizeof(*wl->wl_deallocblks) * wl->wl_dealloclim); - wapbl_free(wl->wl_dealloclens, - sizeof(*wl->wl_dealloclens) * wl->wl_dealloclim); wapbl_free(wl->wl_buffer, MAXPHYS); wapbl_inodetrk_free(wl); wapbl_free(wl, sizeof(*wl)); @@ -582,6 +577,7 @@ void wapbl_discard(struct wapbl *wl) { struct wapbl_entry *we; + struct wapbl_dealloc *wd; struct buf *bp; int i; @@ -590,8 +586,7 @@ wapbl_discard(struct wapbl *wl) * if we want to call flush from inside a transaction */ rw_enter(&wl->wl_rwlock, RW_WRITER); - wl->wl_flush(wl->wl_mount, wl->wl_deallocblks, wl->wl_dealloclens, - wl->wl_dealloccnt); + wl->wl_flush(wl->wl_mount, SIMPLEQ_FIRST(&wl->wl_dealloclist)); #ifdef WAPBL_DEBUG_PRINT { @@ -693,7 +688,12 @@ wapbl_discard(struct wapbl *wl) } /* Discard list of deallocs */ - wl->wl_dealloccnt = 0; + while ((wd = SIMPLEQ_FIRST(&wl->wl_dealloclist)) != NULL) { + SIMPLEQ_REMOVE_HEAD(&wl->wl_dealloclist, wd_entries); + pool_put(&wapbl_dealloc_pool, wd); + wl->wl_dealloccnt--; + } + /* XXX should we clear wl_reserved_bytes? */ KASSERT(wl->wl_bufbytes == 0); @@ -702,6 +702,8 @@ wapbl_discard(struct wapbl *wl) KASSERT(LIST_EMPTY(&wl->wl_bufs)); KASSERT(SIMPLEQ_EMPTY(&wl->wl_entries)); KASSERT(wl->wl_inohashcnt == 0); + KASSERT(SIMPLEQ_EMPTY(&wl->wl_dealloclist)); + KASSERT(wl->wl_dealloccnt == 0); rw_exit(&wl->wl_rwlock); } @@ -736,13 +738,11 @@ wapbl_stop(struct wapbl *wl, int force) KASSERT(wl->wl_dealloccnt == 0); KASSERT(SIMPLEQ_EMPTY(&wl->wl_entries)); KASSERT(wl->wl_inohashcnt == 0); + KASSERT(SIMPLEQ_EMPTY(&wl->wl_dealloclist)); + KASSERT(wl->wl_dealloccnt == 0); wapbl_free(wl->wl_wc_scratch, wl->wl_wc_header->wc_len); wapbl_free(wl->wl_wc_header, wl->wl_wc_header->wc_len); - wapbl_free(wl->wl_deallocblks, - sizeof(*wl->wl_deallocblks) * wl->wl_dealloclim); - wapbl_free(wl->wl_dealloclens, - sizeof(*wl->wl_dealloclens) * wl->wl_dealloclim); wapbl_free(wl->wl_buffer, MAXPHYS); wapbl_inodetrk_free(wl); @@ -1561,8 +1561,7 @@ wapbl_flush(struct wapbl *wl, int waitfo * if we want to call flush from inside a transaction */ rw_enter(&wl->wl_rwlock, RW_WRITER); - wl->wl_flush(wl->wl_mount, wl->wl_deallocblks, wl->wl_dealloclens, - wl->wl_dealloccnt); + wl->wl_flush(wl->wl_mount, SIMPLEQ_FIRST(&wl->wl_dealloclist)); /* * Now that we are exclusively locked and the file system has @@ -1683,7 +1682,7 @@ wapbl_flush(struct wapbl *wl, int waitfo wl->wl_tail = tail; KASSERT(wl->wl_reclaimable_bytes >= delta); wl->wl_reclaimable_bytes -= delta; - wl->wl_dealloccnt = 0; + KDASSERT(wl->wl_dealloccnt == 0); #ifdef WAPBL_DEBUG_BUFBYTES wl->wl_unsynced_bufbytes += wl->wl_bufbytes; #endif @@ -1739,8 +1738,8 @@ wapbl_flush(struct wapbl *wl, int waitfo out: if (error) { - wl->wl_flush_abort(wl->wl_mount, wl->wl_deallocblks, - wl->wl_dealloclens, wl->wl_dealloccnt); + wl->wl_flush_abort(wl->wl_mount, + SIMPLEQ_FIRST(&wl->wl_dealloclist)); } #ifdef WAPBL_DEBUG_PRINT @@ -1877,12 +1876,12 @@ wapbl_print(struct wapbl *wl, (*pr)("dealloced blks = "); { - int i; + struct wapbl_dealloc *wd; cnt = 0; - for (i = 0; i < wl->wl_dealloccnt; i++) { + SIMPLEQ_FOREACH(wd, &wl->wl_dealloclist, wd_entries) { (*pr)(" %"PRId64":%d,", - wl->wl_deallocblks[i], - wl->wl_dealloclens[i]); + wd->wd_blkno, + wd->wd_len); if ((++cnt % 4) == 0) { (*pr)("\n\t"); } @@ -1933,6 +1932,7 @@ wapbl_dump(struct wapbl *wl) void wapbl_register_deallocation(struct wapbl *wl, daddr_t blk, int len) { + struct wapbl_dealloc *wd; wapbl_jlock_assert(wl); @@ -1946,9 +1946,13 @@ wapbl_register_deallocation(struct wapbl if (__predict_false(wl->wl_dealloccnt >= wl->wl_dealloclim)) panic("wapbl_register_deallocation: out of resources"); - wl->wl_deallocblks[wl->wl_dealloccnt] = blk; - wl->wl_dealloclens[wl->wl_dealloccnt] = len; + wd = pool_get(&wapbl_dealloc_pool, PR_WAITOK); + wd->wd_blkno = blk; + wd->wd_len = len; + + SIMPLEQ_INSERT_TAIL(&wl->wl_dealloclist, wd, wd_entries); wl->wl_dealloccnt++; + WAPBL_PRINTF(WAPBL_PRINT_ALLOC, ("wapbl_register_deallocation: blk=%"PRId64" len=%d\n", blk, len)); mutex_exit(&wl->wl_mtx); @@ -2323,7 +2327,7 @@ wapbl_write_revocations(struct wapbl *wl { struct wapbl_wc_blocklist *wc = (struct wapbl_wc_blocklist *)wl->wl_wc_scratch; - int i; + struct wapbl_dealloc *wd, *lwd; int blocklen = 1<<wl->wl_log_dev_bshift; off_t off = *offp; int error; @@ -2331,18 +2335,19 @@ wapbl_write_revocations(struct wapbl *wl if (wl->wl_dealloccnt == 0) return 0; - i = 0; - while (i < wl->wl_dealloccnt) { + wd = SIMPLEQ_FIRST(&wl->wl_dealloclist); + while (wd) { wc->wc_type = WAPBL_WC_REVOCATIONS; wc->wc_len = blocklen; wc->wc_blkcount = 0; - while ((i < wl->wl_dealloccnt) && (wc->wc_blkcount < wl->wl_brperjblock)) { + while (wd && (wc->wc_blkcount < wl->wl_brperjblock)) { wc->wc_blocks[wc->wc_blkcount].wc_daddr = - wl->wl_deallocblks[i]; + wd->wd_blkno; wc->wc_blocks[wc->wc_blkcount].wc_dlen = - wl->wl_dealloclens[i]; + wd->wd_len; wc->wc_blkcount++; - i++; + + wd = SIMPLEQ_NEXT(wd, wd_entries); } WAPBL_PRINTF(WAPBL_PRINT_WRITE, ("wapbl_write_revocations: len = %u off = %"PRIdMAX"\n", @@ -2350,6 +2355,16 @@ wapbl_write_revocations(struct wapbl *wl error = wapbl_circ_write(wl, wc, blocklen, &off); if (error) return error; + + /* free all successfully written deallocs */ + lwd = wd; + while ((wd = SIMPLEQ_FIRST(&wl->wl_dealloclist)) != NULL) { + SIMPLEQ_REMOVE_HEAD(&wl->wl_dealloclist, wd_entries); + pool_put(&wapbl_dealloc_pool, wd); + wl->wl_dealloccnt--; + if (wd == lwd) + break; + } } *offp = off; return 0; Index: src/sys/sys/wapbl.h diff -u src/sys/sys/wapbl.h:1.17 src/sys/sys/wapbl.h:1.18 --- src/sys/sys/wapbl.h:1.17 Sat Jan 23 16:02:09 2016 +++ src/sys/sys/wapbl.h Sat Oct 1 13:15:45 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: wapbl.h,v 1.17 2016/01/23 16:02:09 christos Exp $ */ +/* $NetBSD: wapbl.h,v 1.18 2016/10/01 13:15:45 jdolecek Exp $ */ /*- * Copyright (c) 2003,2008 The NetBSD Foundation, Inc. @@ -94,7 +94,13 @@ struct wapbl_entry; struct wapbl_replay; struct wapbl; -typedef void (*wapbl_flush_fn_t)(struct mount *, daddr_t *, int *, int); +struct wapbl_dealloc { + SIMPLEQ_ENTRY(wapbl_dealloc) wd_entries; + daddr_t wd_blkno; /* address of block */ + int wd_len; /* size of block */ +}; + +typedef void (*wapbl_flush_fn_t)(struct mount *, struct wapbl_dealloc *); /* * This structure holds per transaction log information Index: src/sys/ufs/ffs/ffs_extern.h diff -u src/sys/ufs/ffs/ffs_extern.h:1.82 src/sys/ufs/ffs/ffs_extern.h:1.83 --- src/sys/ufs/ffs/ffs_extern.h:1.82 Fri Mar 27 17:27:56 2015 +++ src/sys/ufs/ffs/ffs_extern.h Sat Oct 1 13:15:45 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: ffs_extern.h,v 1.82 2015/03/27 17:27:56 riastradh Exp $ */ +/* $NetBSD: ffs_extern.h,v 1.83 2016/10/01 13:15:45 jdolecek Exp $ */ /*- * Copyright (c) 1991, 1993, 1994 @@ -168,8 +168,8 @@ int ffs_wapbl_stop(struct mount *, int); int ffs_wapbl_replay_start(struct mount *, struct fs *, struct vnode *); void ffs_wapbl_blkalloc(struct fs *, struct vnode *, daddr_t, int); -void ffs_wapbl_sync_metadata(struct mount *, daddr_t *, int *, int); -void ffs_wapbl_abort_sync_metadata(struct mount *, daddr_t *, int *, int); +void ffs_wapbl_sync_metadata(struct mount *, struct wapbl_dealloc *); +void ffs_wapbl_abort_sync_metadata(struct mount *, struct wapbl_dealloc *); extern int (**ffs_vnodeop_p)(void *); extern int (**ffs_specop_p)(void *); Index: src/sys/ufs/ffs/ffs_wapbl.c diff -u src/sys/ufs/ffs/ffs_wapbl.c:1.33 src/sys/ufs/ffs/ffs_wapbl.c:1.34 --- src/sys/ufs/ffs/ffs_wapbl.c:1.33 Sat Oct 1 13:06:20 2016 +++ src/sys/ufs/ffs/ffs_wapbl.c Sat Oct 1 13:15:45 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: ffs_wapbl.c,v 1.33 2016/10/01 13:06:20 jdolecek Exp $ */ +/* $NetBSD: ffs_wapbl.c,v 1.34 2016/10/01 13:15:45 jdolecek Exp $ */ /*- * Copyright (c) 2003,2006,2008 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ffs_wapbl.c,v 1.33 2016/10/01 13:06:20 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ffs_wapbl.c,v 1.34 2016/10/01 13:15:45 jdolecek Exp $"); #define WAPBL_INTERNAL @@ -167,12 +167,12 @@ ffs_wapbl_replay_finish(struct mount *mp /* Callback for wapbl */ void -ffs_wapbl_sync_metadata(struct mount *mp, daddr_t *deallocblks, - int *dealloclens, int dealloccnt) +ffs_wapbl_sync_metadata(struct mount *mp, struct wapbl_dealloc *fdealloc) { struct ufsmount *ump = VFSTOUFS(mp); struct fs *fs = ump->um_fs; - int i, error __diagused; + int error __diagused; + struct wapbl_dealloc *wd; UFS_WAPBL_JLOCK_ASSERT(mp); @@ -180,13 +180,13 @@ ffs_wapbl_sync_metadata(struct mount *mp ufs_wapbl_verify_inodes(mp, "ffs_wapbl_sync_metadata"); #endif - for (i = 0; i< dealloccnt; i++) { + for (wd = fdealloc; wd != NULL; wd = SIMPLEQ_NEXT(wd, wd_entries)) { /* * blkfree errors are unreported, might silently fail * if it cannot read the cylinder group block */ ffs_blkfree(fs, ump->um_devvp, - FFS_DBTOFSB(fs, deallocblks[i]), dealloclens[i], -1); + FFS_DBTOFSB(fs, wd->wd_blkno), wd->wd_len, -1); } if (fs->fs_fmod != 0) { @@ -198,22 +198,21 @@ ffs_wapbl_sync_metadata(struct mount *mp } void -ffs_wapbl_abort_sync_metadata(struct mount *mp, daddr_t *deallocblks, - int *dealloclens, int dealloccnt) +ffs_wapbl_abort_sync_metadata(struct mount *mp, struct wapbl_dealloc *fdealloc) { struct ufsmount *ump = VFSTOUFS(mp); struct fs *fs = ump->um_fs; - int i; + struct wapbl_dealloc *wd; - for (i = 0; i < dealloccnt; i++) { + for (wd = fdealloc; wd != NULL; wd = SIMPLEQ_NEXT(wd, wd_entries)) { /* * Since the above blkfree may have failed, this blkalloc might * fail as well, so don't check its error. Note that if the * blkfree succeeded above, then this shouldn't fail because * the buffer will be locked in the current transaction. */ - ffs_blkalloc_ump(ump, FFS_DBTOFSB(fs, deallocblks[i]), - dealloclens[i]); + ffs_blkalloc_ump(ump, FFS_DBTOFSB(fs, wd->wd_blkno), + wd->wd_len); } }