Here's another version: it starts with a random 31-bit integer and then for subsequent allocations sets 23 random bits and incremented 8 bits from the previous generation number, so it's guaranteed to not repeat for at least 256 allocations (suggested by Kai Antweiler).
-Dmitry Index: src/sys/ufs/ffs/ffs_alloc.c =================================================================== RCS file: /cvs/src/sys/ufs/ffs/ffs_alloc.c,v retrieving revision 1.108 diff -u -p -u -r1.108 ffs_alloc.c --- src/sys/ufs/ffs/ffs_alloc.c 23 May 2016 20:47:49 -0000 1.108 +++ src/sys/ufs/ffs/ffs_alloc.c 25 Jun 2017 20:57:41 -0000 @@ -361,6 +361,7 @@ ffs_inode_alloc(struct inode *pip, mode_ struct inode *ip; ufsino_t ino, ipref; int cg, error; + int32_t ngen; *vpp = NULL; fs = pip->i_fs; @@ -413,16 +414,18 @@ ffs_inode_alloc(struct inode *pip, mode_ /* * Set up a new generation number for this inode. - * XXX - just increment for now, this is wrong! (millert) - * Need a way to preserve randomization. */ - if (DIP(ip, gen) != 0) - DIP_ADD(ip, gen, 1); if (DIP(ip, gen) == 0) - DIP_ASSIGN(ip, gen, arc4random() & INT_MAX); + ngen = arc4random() & INT_MAX; + else { + ngen = (arc4random() << 8) & 0x7fffff; + ngen |= (u_int8_t)(DIP(ip, gen)) + 1; + } + + if (ngen == 0) + ngen = 1; - if (DIP(ip, gen) == 0 || DIP(ip, gen) == -1) - DIP_ASSIGN(ip, gen, 1); /* Shouldn't happen */ + DIP_ASSIGN(ip, gen, ngen); return (0);