On Fri, Mar 17, 2023 at 03:23:19PM +0100, Moritz Buhl wrote:
> FreeBSD fixed this in 2013:
> https://github.com/freebsd/freebsd-src/commit/94f4ac214c403b99cbc44dd6e9cdf4db2cc9b297
> 
> Below is a diff that addresses this with a exclusive lock
> using RW_SLEEPFAIL.

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?

With that OK bluhm.

> Index: ufs/ffs/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
> --- ufs/ffs/ffs_alloc.c       11 Mar 2021 13:31:35 -0000      1.114
> +++ ufs/ffs/ffs_alloc.c       10 Mar 2023 15:44:52 -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>
> @@ -1089,6 +1090,7 @@ gotit:
>  }
>  
>  /* inode allocation routine */
> +struct rwlock ffs_node_lock = RWLOCK_INITIALIZER("indallck");
>  daddr_t
>  ffs_nodealloccg(struct inode *ip, u_int cg, daddr_t ipref, int mode)
>  {
> @@ -1115,6 +1117,9 @@ ffs_nodealloccg(struct inode *ip, u_int 
>               return (0);
>  
>       cgp = (struct cg *)bp->b_data;
> +#ifdef FFS2
> + check_nifree:
> +#endif
>       if (cgp->cg_cs.cs_nifree == 0) {
>               brelse(bp);
>               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