From 87880c8c1ae722d62cde48bc524ff96445ef7b8b Mon Sep 17 00:00:00 2001 From: David Gwynne Date: Tue, 18 Nov 2014 10:42:16 +0000 Subject: use siphash for key lookups in all the filesystem hashes. ok deraadt@ tedu@ --- sys/ufs/ffs/ffs_softdep.c | 33 ++++++++++++++++++++++----------- sys/ufs/ufs/ufs_quota.c | 15 +++++++++++---- 2 files changed, 33 insertions(+), 15 deletions(-) (limited to 'sys/ufs') diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 3caf5b6ea5c..747a41082aa 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ffs_softdep.c,v 1.128 2014/07/12 18:44:01 tedu Exp $ */ +/* $OpenBSD: ffs_softdep.c,v 1.129 2014/11/18 10:42:15 dlg Exp $ */ /* * Copyright 1998, 2000 Marshall Kirk McKusick. All Rights Reserved. @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -938,14 +939,13 @@ softdep_flushfiles(struct mount *oldmnt, int flags, struct proc *p) #define DEPALLOC 0x0001 /* allocate structure if lookup fails */ #define NODELAY 0x0002 /* cannot do background work */ +SIPHASH_KEY softdep_hashkey; + /* * Structures and routines associated with pagedep caching. */ LIST_HEAD(pagedep_hashhead, pagedep) *pagedep_hashtbl; u_long pagedep_hash; /* size of hash table - 1 */ -#define PAGEDEP_HASH(mp, inum, lbn) \ - (&pagedep_hashtbl[((((register_t)(mp)) >> 13) + (inum) + (lbn)) & \ - pagedep_hash]) STATIC struct sema pagedep_in_progress; /* @@ -959,6 +959,7 @@ STATIC int pagedep_lookup(struct inode *ip, daddr_t lbn, int flags, struct pagedep **pagedeppp) { + SIPHASH_CTX ctx; struct pagedep *pagedep; struct pagedep_hashhead *pagedephd; struct mount *mp; @@ -971,7 +972,12 @@ pagedep_lookup(struct inode *ip, daddr_t lbn, int flags, panic("pagedep_lookup: lock not held"); #endif mp = ITOV(ip)->v_mount; - pagedephd = PAGEDEP_HASH(mp, ip->i_number, lbn); + + SipHash24_Init(&ctx, &softdep_hashkey); + SipHash24_Update(&ctx, &mp, sizeof(mp)); + SipHash24_Update(&ctx, &ip->i_number, sizeof(ip->i_number)); + SipHash24_Update(&ctx, &lbn, sizeof(lbn)); + pagedephd = &pagedep_hashtbl[SipHash24_End(&ctx) & pagedep_hash]; top: LIST_FOREACH(pagedep, pagedephd, pd_hash) if (ip->i_number == pagedep->pd_ino && @@ -1015,8 +1021,6 @@ top: LIST_HEAD(inodedep_hashhead, inodedep) *inodedep_hashtbl; STATIC u_long inodedep_hash; /* size of hash table - 1 */ STATIC long num_inodedep; /* number of inodedep allocated */ -#define INODEDEP_HASH(fs, inum) \ - (&inodedep_hashtbl[((((register_t)(fs)) >> 13) + (inum)) & inodedep_hash]) STATIC struct sema inodedep_in_progress; /* @@ -1029,6 +1033,7 @@ STATIC int inodedep_lookup(struct fs *fs, ufsino_t inum, int flags, struct inodedep **inodedeppp) { + SIPHASH_CTX ctx; struct inodedep *inodedep; struct inodedep_hashhead *inodedephd; int firsttry; @@ -1040,7 +1045,10 @@ inodedep_lookup(struct fs *fs, ufsino_t inum, int flags, panic("inodedep_lookup: lock not held"); #endif firsttry = 1; - inodedephd = INODEDEP_HASH(fs, inum); + SipHash24_Init(&ctx, &softdep_hashkey); + SipHash24_Update(&ctx, &fs, sizeof(fs)); + SipHash24_Update(&ctx, &inum, sizeof(inum)); + inodedephd = &inodedep_hashtbl[SipHash24_End(&ctx) & inodedep_hash]; top: LIST_FOREACH(inodedep, inodedephd, id_hash) if (inum == inodedep->id_ino && fs == inodedep->id_fs) @@ -1092,8 +1100,6 @@ top: */ LIST_HEAD(newblk_hashhead, newblk) *newblk_hashtbl; u_long newblk_hash; /* size of hash table - 1 */ -#define NEWBLK_HASH(fs, inum) \ - (&newblk_hashtbl[((((register_t)(fs)) >> 13) + (inum)) & newblk_hash]) STATIC struct sema newblk_in_progress; /* @@ -1105,10 +1111,14 @@ STATIC int newblk_lookup(struct fs *fs, daddr_t newblkno, int flags, struct newblk **newblkpp) { + SIPHASH_CTX ctx; struct newblk *newblk; struct newblk_hashhead *newblkhd; - newblkhd = NEWBLK_HASH(fs, newblkno); + SipHash24_Init(&ctx, &softdep_hashkey); + SipHash24_Update(&ctx, &fs, sizeof(fs)); + SipHash24_Update(&ctx, &newblkno, sizeof(newblkno)); + newblkhd = &newblk_hashtbl[SipHash24_End(&ctx) & newblk_hash]; top: LIST_FOREACH(newblk, newblkhd, nb_hash) if (newblkno == newblk->nb_newblkno && fs == newblk->nb_fs) @@ -1155,6 +1165,7 @@ softdep_initialize(void) #else max_softdeps = desiredvnodes * 4; #endif + arc4random_buf(&softdep_hashkey, sizeof(softdep_hashkey)); pagedep_hashtbl = hashinit(desiredvnodes / 5, M_PAGEDEP, M_WAITOK, &pagedep_hash); sema_init(&pagedep_in_progress, "pagedep", PRIBIO, 0); diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c index 3e0faa649e2..fd3258fa2d6 100644 --- a/sys/ufs/ufs/ufs_quota.c +++ b/sys/ufs/ufs/ufs_quota.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ufs_quota.c,v 1.35 2014/10/13 03:46:33 guenther Exp $ */ +/* $OpenBSD: ufs_quota.c,v 1.36 2014/11/18 10:42:15 dlg Exp $ */ /* $NetBSD: ufs_quota.c,v 1.8 1996/02/09 22:36:09 christos Exp $ */ /* @@ -53,6 +53,8 @@ #include +#include + /* * The following structure records disk usage for a user or group on a * filesystem. There is one allocated for each quota that exists on any @@ -805,9 +807,8 @@ qsync(struct mount *mp) /* * Code pertaining to management of the in-core dquot data structures. */ -#define DQHASH(dqvp, id) \ - (&dqhashtbl[((((long)(dqvp)) >> 8) + id) & dqhash]) LIST_HEAD(dqhash, dquot) *dqhashtbl; +SIPHASH_KEY dqhashkey; u_long dqhash; /* @@ -824,6 +825,7 @@ void ufs_quota_init(void) { dqhashtbl = hashinit(desiredvnodes, M_DQUOT, M_WAITOK, &dqhash); + arc4random_buf(&dqhashkey, sizeof(dqhashkey)); TAILQ_INIT(&dqfreelist); } @@ -835,6 +837,7 @@ int dqget(struct vnode *vp, u_long id, struct ufsmount *ump, int type, struct dquot **dqp) { + SIPHASH_CTX ctx; struct proc *p = curproc; struct dquot *dq; struct dqhash *dqh; @@ -851,7 +854,11 @@ dqget(struct vnode *vp, u_long id, struct ufsmount *ump, int type, /* * Check the cache first. */ - dqh = DQHASH(dqvp, id); + SipHash24_Init(&ctx, &dqhashkey); + SipHash24_Update(&ctx, &dqvp, sizeof(dqvp)); + SipHash24_Update(&ctx, &id, sizeof(id)); + dqh = &dqhashtbl[SipHash24_End(&ctx) & dqhash]; + LIST_FOREACH(dq, dqh, dq_hash) { if (dq->dq_id != id || dq->dq_vp != dqvp) -- cgit v1.2.3