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
|
||||
* @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)
|
||||
{
|
||||
struct gfs2_glock *gl;
|
||||
struct rhash_head *pos;
|
||||
const struct bucket_table *tbl;
|
||||
int i;
|
||||
struct rhashtable_iter iter;
|
||||
|
||||
rcu_read_lock();
|
||||
tbl = rht_dereference_rcu(gl_hash_table.tbl, &gl_hash_table);
|
||||
for (i = 0; i < tbl->size; i++) {
|
||||
rht_for_each_entry_rcu(gl, pos, tbl, i, gl_node) {
|
||||
rhashtable_walk_enter(&gl_hash_table, &iter);
|
||||
|
||||
do {
|
||||
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) &&
|
||||
lockref_get_not_dead(&gl->gl_lockref))
|
||||
examiner(gl);
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
cond_resched();
|
||||
|
||||
rhashtable_walk_stop(&iter);
|
||||
} while (cond_resched(), gl == ERR_PTR(-EAGAIN));
|
||||
|
||||
rhashtable_walk_exit(&iter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue