Below is an updated diff addressing the following concerns:

On Fri, Mar 17, 2023 at 03:45:59PM +0100, Alexander Bluhm wrote:
> The FreeBSD Code puts the check_nifree label before the if
> (fs->fs_cs(fs, cg).cs_nifree == 0) check.  Could you move this chunk
> a little up to keep us in sync?

On Fri, Mar 17, 2023 at 03:57:39PM +0100, Mark Kettenis wrote:
> Don't hide a global variable like that!

There are also some concerns on the string "indallck",
to my understanding the first 7 characters show up as wchan in ps
and should be easy to grep for.
Any better names?
"ffs-node-lock"
"ffsndlock"

Index: ffs_alloc.c
===================================================================
RCS file: /cvs/src/sys/ufs/ffs/ffs_alloc.c,v
retrieving revision 1.114
diff -u -p -r1.114 ffs_alloc.c
--- ffs_alloc.c 11 Mar 2021 13:31:35 -0000      1.114
+++ ffs_alloc.c 17 Mar 2023 19:28:11 -0000
@@ -46,6 +46,7 @@
 #include <sys/buf.h>
 #include <sys/vnode.h>
 #include <sys/mount.h>
+#include <sys/rwlock.h>
 #include <sys/syslog.h>
 #include <sys/stdint.h>
 #include <sys/time.h>
@@ -75,6 +76,7 @@ daddr_t               ffs_mapsearch(struct fs *, stru
 
 static const struct timeval    fserr_interval = { 2, 0 };
 
+struct rwlock ffs_node_lock = RWLOCK_INITIALIZER("indallck");
 
 /*
  * Allocate a block in the file system.
@@ -1108,6 +1110,9 @@ ffs_nodealloccg(struct inode *ip, u_int 
         * and in the cylinder group itself.
         */
        fs = ip->i_fs;
+#ifdef FFS2
+ check_nifree:
+#endif
        if (fs->fs_cs(fs, cg).cs_nifree == 0)
                return (0);
 
@@ -1201,9 +1206,12 @@ gotit:
            /* Has any inode not been used at least once? */
            cgp->cg_initediblk < cgp->cg_ffs2_niblk) {
 
+               if (rw_enter(&ffs_node_lock, RW_WRITE | RW_SLEEPFAIL))
+                       goto check_nifree;
                 ibp = getblk(ip->i_devvp, fsbtodb(fs,
                     ino_to_fsba(fs, cg * fs->fs_ipg + cgp->cg_initediblk)),
                     (int)fs->fs_bsize, 0, INFSLP);
+               rw_exit(&ffs_node_lock);
 
                 memset(ibp->b_data, 0, fs->fs_bsize);
                 dp2 = (struct ufs2_dinode *)(ibp->b_data);

Reply via email to