aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Price <anprice@redhat.com>2017-02-22 12:05:03 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-03-12 00:41:50 -0500
commit4cf918c804c657c3a8b9cd4bb46171315bdfad62 (patch)
tree714d8363a3aec818f0d459b6a74af1a8d9ab1664
parentc8cdd9234caced510db1a03491af475938f9855a (diff)
gfs2: Add missing rcu locking for glock lookup
commit f38e5fb95a1f8feda88531eedc98f69b24748712 upstream. We must hold the rcu read lock across looking up glocks and trying to bump their refcount to prevent the glocks from being freed in between. Signed-off-by: Andrew Price <anprice@redhat.com> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/gfs2/glock.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 14cbf60167a7..133f322573b5 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -658,9 +658,11 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
658 struct kmem_cache *cachep; 658 struct kmem_cache *cachep;
659 int ret, tries = 0; 659 int ret, tries = 0;
660 660
661 rcu_read_lock();
661 gl = rhashtable_lookup_fast(&gl_hash_table, &name, ht_parms); 662 gl = rhashtable_lookup_fast(&gl_hash_table, &name, ht_parms);
662 if (gl && !lockref_get_not_dead(&gl->gl_lockref)) 663 if (gl && !lockref_get_not_dead(&gl->gl_lockref))
663 gl = NULL; 664 gl = NULL;
665 rcu_read_unlock();
664 666
665 *glp = gl; 667 *glp = gl;
666 if (gl) 668 if (gl)
@@ -728,15 +730,18 @@ again:
728 730
729 if (ret == -EEXIST) { 731 if (ret == -EEXIST) {
730 ret = 0; 732 ret = 0;
733 rcu_read_lock();
731 tmp = rhashtable_lookup_fast(&gl_hash_table, &name, ht_parms); 734 tmp = rhashtable_lookup_fast(&gl_hash_table, &name, ht_parms);
732 if (tmp == NULL || !lockref_get_not_dead(&tmp->gl_lockref)) { 735 if (tmp == NULL || !lockref_get_not_dead(&tmp->gl_lockref)) {
733 if (++tries < 100) { 736 if (++tries < 100) {
737 rcu_read_unlock();
734 cond_resched(); 738 cond_resched();
735 goto again; 739 goto again;
736 } 740 }
737 tmp = NULL; 741 tmp = NULL;
738 ret = -ENOMEM; 742 ret = -ENOMEM;
739 } 743 }
744 rcu_read_unlock();
740 } else { 745 } else {
741 WARN_ON_ONCE(ret); 746 WARN_ON_ONCE(ret);
742 } 747 }