diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/gfs2/glock.c | 28 | 
1 files changed, 17 insertions, 11 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 94f50cac91c6..70e94170af85 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -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);  }  /**  | 
