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);
}
}