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