gfs2: Use rhashtable walk interface in glock_hash_walk
The function glock_hash_walk walks the rhashtable by hand. This
is broken because if it catches the hash table in the middle of
a rehash, then it will miss entries.
This patch replaces the manual walk by using the rhashtable walk
interface.
Fixes: 88ffbf3e03
("GFS2: Use resizable hash table for glocks")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
4872e57c81
commit
6a25478077
|
@ -1420,26 +1420,32 @@ static struct shrinker glock_shrinker = {
|
||||||
* @sdp: the filesystem
|
* @sdp: the filesystem
|
||||||
* @bucket: the bucket
|
* @bucket: the bucket
|
||||||
*
|
*
|
||||||
|
* Note that the function can be called multiple times on the same
|
||||||
|
* object. So the user must ensure that the function can cope with
|
||||||
|
* that.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp)
|
static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp)
|
||||||
{
|
{
|
||||||
struct gfs2_glock *gl;
|
struct gfs2_glock *gl;
|
||||||
struct rhash_head *pos;
|
struct rhashtable_iter iter;
|
||||||
const struct bucket_table *tbl;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
rhashtable_walk_enter(&gl_hash_table, &iter);
|
||||||
tbl = rht_dereference_rcu(gl_hash_table.tbl, &gl_hash_table);
|
|
||||||
for (i = 0; i < tbl->size; i++) {
|
do {
|
||||||
rht_for_each_entry_rcu(gl, pos, tbl, i, gl_node) {
|
gl = ERR_PTR(rhashtable_walk_start(&iter));
|
||||||
|
if (gl)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
while ((gl = rhashtable_walk_next(&iter)) && !IS_ERR(gl))
|
||||||
if ((gl->gl_name.ln_sbd == sdp) &&
|
if ((gl->gl_name.ln_sbd == sdp) &&
|
||||||
lockref_get_not_dead(&gl->gl_lockref))
|
lockref_get_not_dead(&gl->gl_lockref))
|
||||||
examiner(gl);
|
examiner(gl);
|
||||||
}
|
|
||||||
}
|
rhashtable_walk_stop(&iter);
|
||||||
rcu_read_unlock();
|
} while (cond_resched(), gl == ERR_PTR(-EAGAIN));
|
||||||
cond_resched();
|
|
||||||
|
rhashtable_walk_exit(&iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue