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