aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glock.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r--fs/gfs2/glock.c34
1 files changed, 12 insertions, 22 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index cf54b0b001fd..2316490723c0 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -15,7 +15,6 @@
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/sort.h> 16#include <linux/sort.h>
17#include <linux/jhash.h> 17#include <linux/jhash.h>
18#include <linux/kref.h>
19#include <linux/kallsyms.h> 18#include <linux/kallsyms.h>
20#include <linux/gfs2_ondisk.h> 19#include <linux/gfs2_ondisk.h>
21#include <linux/list.h> 20#include <linux/list.h>
@@ -179,23 +178,7 @@ static void glock_free(struct gfs2_glock *gl)
179 178
180void gfs2_glock_hold(struct gfs2_glock *gl) 179void gfs2_glock_hold(struct gfs2_glock *gl)
181{ 180{
182 kref_get(&gl->gl_ref); 181 atomic_inc(&gl->gl_ref);
183}
184
185/* All work is done after the return from kref_put() so we
186 can release the write_lock before the free. */
187
188static void kill_glock(struct kref *kref)
189{
190 struct gfs2_glock *gl = container_of(kref, struct gfs2_glock, gl_ref);
191 struct gfs2_sbd *sdp = gl->gl_sbd;
192
193 gfs2_assert(sdp, gl->gl_state == LM_ST_UNLOCKED);
194 gfs2_assert(sdp, list_empty(&gl->gl_reclaim));
195 gfs2_assert(sdp, list_empty(&gl->gl_holders));
196 gfs2_assert(sdp, list_empty(&gl->gl_waiters1));
197 gfs2_assert(sdp, list_empty(&gl->gl_waiters2));
198 gfs2_assert(sdp, list_empty(&gl->gl_waiters3));
199} 182}
200 183
201/** 184/**
@@ -207,12 +190,19 @@ static void kill_glock(struct kref *kref)
207int gfs2_glock_put(struct gfs2_glock *gl) 190int gfs2_glock_put(struct gfs2_glock *gl)
208{ 191{
209 int rv = 0; 192 int rv = 0;
193 struct gfs2_sbd *sdp = gl->gl_sbd;
210 194
211 write_lock(gl_lock_addr(gl->gl_hash)); 195 write_lock(gl_lock_addr(gl->gl_hash));
212 if (kref_put(&gl->gl_ref, kill_glock)) { 196 if (atomic_dec_and_test(&gl->gl_ref)) {
213 hlist_del(&gl->gl_list); 197 hlist_del(&gl->gl_list);
214 write_unlock(gl_lock_addr(gl->gl_hash)); 198 write_unlock(gl_lock_addr(gl->gl_hash));
215 BUG_ON(spin_is_locked(&gl->gl_spin)); 199 BUG_ON(spin_is_locked(&gl->gl_spin));
200 gfs2_assert(sdp, gl->gl_state == LM_ST_UNLOCKED);
201 gfs2_assert(sdp, list_empty(&gl->gl_reclaim));
202 gfs2_assert(sdp, list_empty(&gl->gl_holders));
203 gfs2_assert(sdp, list_empty(&gl->gl_waiters1));
204 gfs2_assert(sdp, list_empty(&gl->gl_waiters2));
205 gfs2_assert(sdp, list_empty(&gl->gl_waiters3));
216 glock_free(gl); 206 glock_free(gl);
217 rv = 1; 207 rv = 1;
218 goto out; 208 goto out;
@@ -267,7 +257,7 @@ static struct gfs2_glock *search_bucket(unsigned int hash,
267 if (gl->gl_sbd != sdp) 257 if (gl->gl_sbd != sdp)
268 continue; 258 continue;
269 259
270 kref_get(&gl->gl_ref); 260 atomic_inc(&gl->gl_ref);
271 261
272 return gl; 262 return gl;
273 } 263 }
@@ -333,7 +323,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number,
333 323
334 gl->gl_flags = 0; 324 gl->gl_flags = 0;
335 gl->gl_name = name; 325 gl->gl_name = name;
336 kref_init(&gl->gl_ref); 326 atomic_set(&gl->gl_ref, 1);
337 gl->gl_state = LM_ST_UNLOCKED; 327 gl->gl_state = LM_ST_UNLOCKED;
338 gl->gl_hash = hash; 328 gl->gl_hash = hash;
339 gl->gl_owner = NULL; 329 gl->gl_owner = NULL;
@@ -2124,7 +2114,7 @@ static int dump_glock(struct gfs2_glock *gl)
2124 printk(" %u", x); 2114 printk(" %u", x);
2125 } 2115 }
2126 printk(" \n"); 2116 printk(" \n");
2127 printk(KERN_INFO " gl_ref = %d\n", atomic_read(&gl->gl_ref.refcount)); 2117 printk(KERN_INFO " gl_ref = %d\n", atomic_read(&gl->gl_ref));
2128 printk(KERN_INFO " gl_state = %u\n", gl->gl_state); 2118 printk(KERN_INFO " gl_state = %u\n", gl->gl_state);
2129 printk(KERN_INFO " gl_owner = %s\n", gl->gl_owner->comm); 2119 printk(KERN_INFO " gl_owner = %s\n", gl->gl_owner->comm);
2130 print_symbol(KERN_INFO " gl_ip = %s\n", gl->gl_ip); 2120 print_symbol(KERN_INFO " gl_ip = %s\n", gl->gl_ip);