NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/54504: -9/-current WAPBL panic: current transaction too big, to flush
The following reply was made to PR kern/54504; it has been noted by GNATS.
From: Konrad Schroder <perseant%hhhh.org@localhost>
To: NetBSD bugtracking <gnats-bugs%netbsd.org@localhost>
Cc:
Subject: Re: kern/54504: -9/-current WAPBL panic: current transaction too big,
to flush
Date: Mon, 3 Aug 2020 20:22:09 -0700
This patch successfully avoids a crash on my test setup.
I'm not sure I like polling wapbl_check. I don't see, though, how WAPBL
could deal with this problem on its own without relaxing its guarantees
to the point that a fsck would be required at boot anyway; and I don't
see how FFS could estimate the number of metadata blocks to be written
well enough to avoid some kind of periodic checking, without in essence
running ufs_truncate twice. It's perfectly likely that I'm missing
something, but if not, this seems the simplest and most reasonable solution.
Thoughts?
Index: sys/sys/mount.h
===================================================================
RCS file: /cvsroot/src/sys/sys/mount.h,v
retrieving revision 1.236
diff -u -r1.236 mount.h
--- sys/sys/mount.h    17 Jan 2020 20:08:10 -0000     1.236
+++ sys/sys/mount.h    3 Aug 2020 14:04:55 -0000
@@ -295,6 +295,7 @@
       void (*wo_wapbl_junlock_assert)(struct wapbl *);
       void (*wo_wapbl_jlock_assert)(struct wapbl *);
       void (*wo_wapbl_biodone)(struct buf *);
+Â Â Â Â Â Â int (*wo_wapbl_check)(struct wapbl *);
 };
 #define WAPBL_DISCARD(MP)                                             \
(*(MP)->mnt_wapbl_op->wo_wapbl_discard)((MP)->mnt_wapbl)
Index: sys/sys/wapbl.h
===================================================================
RCS file: /cvsroot/src/sys/sys/wapbl.h,v
retrieving revision 1.21
diff -u -r1.21 wapbl.h
--- sys/sys/wapbl.h    10 Dec 2018 21:19:33 -0000     1.21
+++ sys/sys/wapbl.h    3 Aug 2020 14:04:55 -0000
@@ -139,6 +139,9 @@
 /* End a transaction or decrement the transaction recursion level */
 void  wapbl_end(struct wapbl *);
+/* Check to see whether the transaction is approaching full */
+int   wapbl_check(struct wapbl *);
+
 /*
 * Add a new buffer to the current transaction. The buffers
 * data will be copied to the current transaction log and the
Index: sys/kern/vfs_wapbl.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_wapbl.c,v
retrieving revision 1.108
diff -u -r1.108 vfs_wapbl.c
--- sys/kern/vfs_wapbl.c   12 Apr 2020 17:02:52 -0000   1.108
+++ sys/kern/vfs_wapbl.c   3 Aug 2020 14:07:54 -0000
@@ -312,9 +312,9 @@
    .wo_wapbl_end      = wapbl_end,
    .wo_wapbl_junlock_assert= wapbl_junlock_assert,
    .wo_wapbl_jlock_assert   = wapbl_jlock_assert,
-
-Â Â Â /* XXX: the following is only used to say "this is a wapbl buf" */
+Â Â Â /* XXX: wp_wapbl_biodone is only used to say "this is a wapbl buf" */
    .wo_wapbl_biodone   = wapbl_biodone,
+   .wo_wapbl_check      = wapbl_check,
 };
 SYSCTL_SETUP(wapbl_sysctl_init, "wapbl sysctl")
@@ -3420,6 +3421,19 @@
    return 0;
 }
+int
+wapbl_check(struct wapbl *wl)
+{
+Â Â Â int error = 0;
+
+Â Â Â if (wapbl_transaction_len(wl) >
+Â Â Â Â Â Â (wl->wl_circ_size - wl->wl_reserved_bytes) / 2) {
+Â Â Â Â Â Â error = EAGAIN;
+Â Â Â }
+
+Â Â Â return error;
+}
+
 #ifdef _KERNEL
 MODULE(MODULE_CLASS_VFS, wapbl, NULL);
Index: sys/ufs/ffs/ffs_inode.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ffs/ffs_inode.c,v
retrieving revision 1.130
diff -u -r1.130 ffs_inode.c
--- sys/ufs/ffs/ffs_inode.c   26 Jul 2020 00:21:24 -0000   1.130
+++ sys/ufs/ffs/ffs_inode.c   3 Aug 2020 03:52:59 -0000
@@ -495,6 +495,9 @@
       }
       if (lastiblock[level] >= 0)
          goto done;
+Â Â Â Â Â Â error = UFS_WAPBL_CHECK(oip->i_ump->um_mountp);
+Â Â Â Â Â Â if (error)
+Â Â Â Â Â Â Â Â Â goto out;
    }
    /*
@@ -756,6 +759,10 @@
       BAP_ASSIGN(ip, i, 0);
       *countp += nblocks;
+
+Â Â Â Â Â Â error = UFS_WAPBL_CHECK(ip->i_ump->um_mountp);
+Â Â Â Â Â Â if (error)
+Â Â Â Â Â Â Â Â Â goto out;
    }
    /*
Index: sys/ufs/ufs/ufs_wapbl.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/ufs/ufs_wapbl.h,v
retrieving revision 1.19
diff -u -r1.19 ufs_wapbl.h
--- sys/ufs/ufs/ufs_wapbl.h   11 Apr 2020 17:43:54 -0000   1.19
+++ sys/ufs/ufs/ufs_wapbl.h   3 Aug 2020 03:52:59 -0000
@@ -94,6 +94,18 @@
    return 0;
 }
+static __inline int
+ufs_wapbl_check(struct mount *mp)
+{
+Â Â Â if (mp->mnt_wapbl) {
+Â Â Â Â Â Â int error;
+Â Â Â Â Â Â error = wapbl_check(mp->mnt_wapbl);
+Â Â Â Â Â Â if (error)
+Â Â Â Â Â Â Â Â Â return error;
+Â Â Â }
+Â Â Â return 0;
+}
+
 static __inline void
 ufs_wapbl_end(struct mount *mp)
 {
@@ -104,6 +116,7 @@
 #define   UFS_WAPBL_BEGIN(mp)                  \
    ufs_wapbl_begin(mp, __func__, __LINE__)
+#define   UFS_WAPBL_CHECK(mp) ufs_wapbl_check(mp)
 #define   UFS_WAPBL_END(mp) ufs_wapbl_end(mp)
 #define   UFS_WAPBL_UPDATE(vp, access, modify, flags)         \
@@ -145,6 +158,7 @@
 #else /* ! WAPBL */
 #define   UFS_WAPBL_BEGIN(mp) (__USE(mp), 0)
+#define   UFS_WAPBL_CHECK(mp) (__USE(mp), 0)
 #define   UFS_WAPBL_END(mp)   do { } while (0)
 #define   UFS_WAPBL_UPDATE(vp, access, modify, flags)   do { } while (0)
 #define   UFS_WAPBL_JLOCK_ASSERT(mp)
--
Konrad Schroder
perseant%hhhh.org@localhost
Home |
Main Index |
Thread Index |
Old Index