diff --git a/include/os/freebsd/spl/sys/random.h b/include/os/freebsd/spl/sys/random.h index b3c9115f5305..ecc0aa68788c 100644 --- a/include/os/freebsd/spl/sys/random.h +++ b/include/os/freebsd/spl/sys/random.h @@ -30,6 +30,9 @@ #define _OPENSOLARIS_SYS_RANDOM_H_ #include_next +#if __FreeBSD_version >= 1300108 +#include +#endif static inline int random_get_bytes(uint8_t *p, size_t s) @@ -45,4 +48,23 @@ random_get_pseudo_bytes(uint8_t *p, size_t s) return (0); } +static inline uint32_t +spa_get_random(uint32_t range) +{ +#if __FreeBSD_version >= 1300108 + return (prng32_bounded(range)); +#else + uint32_t r; + + ASSERT(range != 0); + + if (range == 1) + return (0); + + (void) random_get_pseudo_bytes((void *)&r, sizeof (r)); + + return (r % range); +#endif +} + #endif /* !_OPENSOLARIS_SYS_RANDOM_H_ */ diff --git a/include/os/linux/spl/sys/random.h b/include/os/linux/spl/sys/random.h index 1b8cb60d094f..95e83f3cc723 100644 --- a/include/os/linux/spl/sys/random.h +++ b/include/os/linux/spl/sys/random.h @@ -36,4 +36,19 @@ random_get_bytes(uint8_t *ptr, size_t len) extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len); +static __inline__ uint32_t +spa_get_random(uint32_t range) +{ + uint32_t r; + + ASSERT(range != 0); + + if (range == 1) + return (0); + + (void) random_get_pseudo_bytes((void *)&r, sizeof (r)); + + return (r % range); +} + #endif /* _SPL_RANDOM_H */ diff --git a/include/sys/spa.h b/include/sys/spa.h index 374d36e7327e..69d9aaee8cf2 100644 --- a/include/sys/spa.h +++ b/include/sys/spa.h @@ -1066,7 +1066,6 @@ extern spa_t *spa_by_guid(uint64_t pool_guid, uint64_t device_guid); extern boolean_t spa_guid_exists(uint64_t pool_guid, uint64_t device_guid); extern char *spa_strdup(const char *); extern void spa_strfree(char *); -extern uint64_t spa_get_random(uint64_t range); extern uint64_t spa_generate_guid(spa_t *spa); extern void snprintf_blkptr(char *buf, size_t buflen, const blkptr_t *bp); extern void spa_freeze(spa_t *spa); diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 3fb390c3f6e3..615002122eed 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -646,6 +646,21 @@ extern int lowbit64(uint64_t i); extern int random_get_bytes(uint8_t *ptr, size_t len); extern int random_get_pseudo_bytes(uint8_t *ptr, size_t len); +static __inline__ uint32_t +spa_get_random(uint32_t range) +{ + uint32_t r; + + ASSERT(range != 0); + + if (range == 1) + return (0); + + (void) random_get_pseudo_bytes((void *)&r, sizeof (r)); + + return (r % range); +} + extern void kernel_init(int mode); extern void kernel_fini(void); extern void random_init(void); diff --git a/module/zfs/spa_misc.c b/module/zfs/spa_misc.c index 1a2e5abc5335..77d891177cbf 100644 --- a/module/zfs/spa_misc.c +++ b/module/zfs/spa_misc.c @@ -1494,32 +1494,21 @@ spa_strfree(char *s) kmem_free(s, strlen(s) + 1); } -uint64_t -spa_get_random(uint64_t range) -{ - uint64_t r; - - ASSERT(range != 0); - - if (range == 1) - return (0); - - (void) random_get_pseudo_bytes((void *)&r, sizeof (uint64_t)); - - return (r % range); -} - uint64_t spa_generate_guid(spa_t *spa) { - uint64_t guid = spa_get_random(-1ULL); + uint64_t guid; if (spa != NULL) { - while (guid == 0 || spa_guid_exists(spa_guid(spa), guid)) - guid = spa_get_random(-1ULL); + do { + (void) random_get_pseudo_bytes((void *)&guid, + sizeof (guid)); + } while (guid == 0 || spa_guid_exists(spa_guid(spa), guid)); } else { - while (guid == 0 || spa_guid_exists(guid, 0)) - guid = spa_get_random(-1ULL); + do { + (void) random_get_pseudo_bytes((void *)&guid, + sizeof (guid)); + } while (guid == 0 || spa_guid_exists(guid, 0)); } return (guid); @@ -2888,7 +2877,6 @@ EXPORT_SYMBOL(spa_maxdnodesize); EXPORT_SYMBOL(spa_guid_exists); EXPORT_SYMBOL(spa_strdup); EXPORT_SYMBOL(spa_strfree); -EXPORT_SYMBOL(spa_get_random); EXPORT_SYMBOL(spa_generate_guid); EXPORT_SYMBOL(snprintf_blkptr); EXPORT_SYMBOL(spa_freeze); diff --git a/module/zfs/zil.c b/module/zfs/zil.c index d9c3042084e3..5443c2a1f3f1 100644 --- a/module/zfs/zil.c +++ b/module/zfs/zil.c @@ -205,8 +205,10 @@ zil_init_log_chain(zilog_t *zilog, blkptr_t *bp) { zio_cksum_t *zc = &bp->blk_cksum; - zc->zc_word[ZIL_ZC_GUID_0] = spa_get_random(-1ULL); - zc->zc_word[ZIL_ZC_GUID_1] = spa_get_random(-1ULL); + (void) random_get_pseudo_bytes((void *)&zc->zc_word[ZIL_ZC_GUID_0], + sizeof (zc->zc_word[ZIL_ZC_GUID_0])); + (void) random_get_pseudo_bytes((void *)&zc->zc_word[ZIL_ZC_GUID_1], + sizeof (zc->zc_word[ZIL_ZC_GUID_1])); zc->zc_word[ZIL_ZC_OBJSET] = dmu_objset_id(zilog->zl_os); zc->zc_word[ZIL_ZC_SEQ] = 1ULL; }