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

Reply via email to