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