diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2008-05-21 12:03:22 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2008-06-27 04:39:22 -0400 |
commit | 6802e3400ff4549525930ee744030c36fce9cc73 (patch) | |
tree | db889bf5337c1d3bb12ebbf571c3c1cad1040496 /fs/gfs2/glops.c | |
parent | 543cf4cb3fe6f6cae3651ba918b9c56200b257d0 (diff) |
[GFS2] Clean up the glock core
This patch implements a number of cleanups to the core of the
GFS2 glock code. As a result a lot of code is removed. It looks
like a really big change, but actually a large part of this patch
is either removing or moving existing code.
There are some new bits too though, such as the new run_queue()
function which is considerably streamlined. Highlights of this
patch include:
o Fixes a cluster coherency bug during SH -> EX lock conversions
o Removes the "glmutex" code in favour of a single bit lock
o Removes the ->go_xmote_bh() for inodes since it was duplicating
->go_lock()
o We now only use the ->lm_lock() function for both locks and
unlocks (i.e. unlock is a lock with target mode LM_ST_UNLOCKED)
o The fast path is considerably shortly, giving performance gains
especially with lock_nolock
o The glock_workqueue is now used for all the callbacks from the DLM
which allows us to simplify the lock_dlm module (see following patch)
o The way is now open to make further changes such as eliminating the two
threads (gfs2_glockd and gfs2_scand) in favour of a more efficient
scheme.
This patch has undergone extensive testing with various test suites
so it should be pretty stable by now.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Cc: Bob Peterson <rpeterso@redhat.com>
Diffstat (limited to 'fs/gfs2/glops.c')
-rw-r--r-- | fs/gfs2/glops.c | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 07d84d16cda4..c6c318c2a0f6 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/buffer_head.h> | 13 | #include <linux/buffer_head.h> |
14 | #include <linux/gfs2_ondisk.h> | 14 | #include <linux/gfs2_ondisk.h> |
15 | #include <linux/lm_interface.h> | 15 | #include <linux/lm_interface.h> |
16 | #include <linux/bio.h> | ||
16 | 17 | ||
17 | #include "gfs2.h" | 18 | #include "gfs2.h" |
18 | #include "incore.h" | 19 | #include "incore.h" |
@@ -172,26 +173,6 @@ static void inode_go_sync(struct gfs2_glock *gl) | |||
172 | } | 173 | } |
173 | 174 | ||
174 | /** | 175 | /** |
175 | * inode_go_xmote_bh - After promoting/demoting a glock | ||
176 | * @gl: the glock | ||
177 | * | ||
178 | */ | ||
179 | |||
180 | static void inode_go_xmote_bh(struct gfs2_glock *gl) | ||
181 | { | ||
182 | struct gfs2_holder *gh = gl->gl_req_gh; | ||
183 | struct buffer_head *bh; | ||
184 | int error; | ||
185 | |||
186 | if (gl->gl_state != LM_ST_UNLOCKED && | ||
187 | (!gh || !(gh->gh_flags & GL_SKIP))) { | ||
188 | error = gfs2_meta_read(gl, gl->gl_name.ln_number, 0, &bh); | ||
189 | if (!error) | ||
190 | brelse(bh); | ||
191 | } | ||
192 | } | ||
193 | |||
194 | /** | ||
195 | * inode_go_inval - prepare a inode glock to be released | 176 | * inode_go_inval - prepare a inode glock to be released |
196 | * @gl: the glock | 177 | * @gl: the glock |
197 | * @flags: | 178 | * @flags: |
@@ -267,6 +248,26 @@ static int inode_go_lock(struct gfs2_holder *gh) | |||
267 | } | 248 | } |
268 | 249 | ||
269 | /** | 250 | /** |
251 | * inode_go_dump - print information about an inode | ||
252 | * @seq: The iterator | ||
253 | * @ip: the inode | ||
254 | * | ||
255 | * Returns: 0 on success, -ENOBUFS when we run out of space | ||
256 | */ | ||
257 | |||
258 | static int inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl) | ||
259 | { | ||
260 | const struct gfs2_inode *ip = gl->gl_object; | ||
261 | if (ip == NULL) | ||
262 | return 0; | ||
263 | gfs2_print_dbg(seq, " I: n:%llu/%llu t:%u f:0x%08lx\n", | ||
264 | (unsigned long long)ip->i_no_formal_ino, | ||
265 | (unsigned long long)ip->i_no_addr, | ||
266 | IF2DT(ip->i_inode.i_mode), ip->i_flags); | ||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | /** | ||
270 | * rgrp_go_demote_ok - Check to see if it's ok to unlock a RG's glock | 271 | * rgrp_go_demote_ok - Check to see if it's ok to unlock a RG's glock |
271 | * @gl: the glock | 272 | * @gl: the glock |
272 | * | 273 | * |
@@ -306,6 +307,22 @@ static void rgrp_go_unlock(struct gfs2_holder *gh) | |||
306 | } | 307 | } |
307 | 308 | ||
308 | /** | 309 | /** |
310 | * rgrp_go_dump - print out an rgrp | ||
311 | * @seq: The iterator | ||
312 | * @gl: The glock in question | ||
313 | * | ||
314 | */ | ||
315 | |||
316 | static int rgrp_go_dump(struct seq_file *seq, const struct gfs2_glock *gl) | ||
317 | { | ||
318 | const struct gfs2_rgrpd *rgd = gl->gl_object; | ||
319 | if (rgd == NULL) | ||
320 | return 0; | ||
321 | gfs2_print_dbg(seq, " R: n:%llu\n", (unsigned long long)rgd->rd_addr); | ||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | /** | ||
309 | * trans_go_sync - promote/demote the transaction glock | 326 | * trans_go_sync - promote/demote the transaction glock |
310 | * @gl: the glock | 327 | * @gl: the glock |
311 | * @state: the requested state | 328 | * @state: the requested state |
@@ -330,7 +347,7 @@ static void trans_go_sync(struct gfs2_glock *gl) | |||
330 | * | 347 | * |
331 | */ | 348 | */ |
332 | 349 | ||
333 | static void trans_go_xmote_bh(struct gfs2_glock *gl) | 350 | static int trans_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh) |
334 | { | 351 | { |
335 | struct gfs2_sbd *sdp = gl->gl_sbd; | 352 | struct gfs2_sbd *sdp = gl->gl_sbd; |
336 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); | 353 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); |
@@ -338,8 +355,7 @@ static void trans_go_xmote_bh(struct gfs2_glock *gl) | |||
338 | struct gfs2_log_header_host head; | 355 | struct gfs2_log_header_host head; |
339 | int error; | 356 | int error; |
340 | 357 | ||
341 | if (gl->gl_state != LM_ST_UNLOCKED && | 358 | if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { |
342 | test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { | ||
343 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); | 359 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); |
344 | 360 | ||
345 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); | 361 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); |
@@ -354,6 +370,7 @@ static void trans_go_xmote_bh(struct gfs2_glock *gl) | |||
354 | gfs2_log_pointers_init(sdp, head.lh_blkno); | 370 | gfs2_log_pointers_init(sdp, head.lh_blkno); |
355 | } | 371 | } |
356 | } | 372 | } |
373 | return 0; | ||
357 | } | 374 | } |
358 | 375 | ||
359 | /** | 376 | /** |
@@ -375,12 +392,12 @@ const struct gfs2_glock_operations gfs2_meta_glops = { | |||
375 | 392 | ||
376 | const struct gfs2_glock_operations gfs2_inode_glops = { | 393 | const struct gfs2_glock_operations gfs2_inode_glops = { |
377 | .go_xmote_th = inode_go_sync, | 394 | .go_xmote_th = inode_go_sync, |
378 | .go_xmote_bh = inode_go_xmote_bh, | ||
379 | .go_inval = inode_go_inval, | 395 | .go_inval = inode_go_inval, |
380 | .go_demote_ok = inode_go_demote_ok, | 396 | .go_demote_ok = inode_go_demote_ok, |
381 | .go_lock = inode_go_lock, | 397 | .go_lock = inode_go_lock, |
398 | .go_dump = inode_go_dump, | ||
382 | .go_type = LM_TYPE_INODE, | 399 | .go_type = LM_TYPE_INODE, |
383 | .go_min_hold_time = HZ / 10, | 400 | .go_min_hold_time = HZ / 5, |
384 | }; | 401 | }; |
385 | 402 | ||
386 | const struct gfs2_glock_operations gfs2_rgrp_glops = { | 403 | const struct gfs2_glock_operations gfs2_rgrp_glops = { |
@@ -389,8 +406,9 @@ const struct gfs2_glock_operations gfs2_rgrp_glops = { | |||
389 | .go_demote_ok = rgrp_go_demote_ok, | 406 | .go_demote_ok = rgrp_go_demote_ok, |
390 | .go_lock = rgrp_go_lock, | 407 | .go_lock = rgrp_go_lock, |
391 | .go_unlock = rgrp_go_unlock, | 408 | .go_unlock = rgrp_go_unlock, |
409 | .go_dump = rgrp_go_dump, | ||
392 | .go_type = LM_TYPE_RGRP, | 410 | .go_type = LM_TYPE_RGRP, |
393 | .go_min_hold_time = HZ / 10, | 411 | .go_min_hold_time = HZ / 5, |
394 | }; | 412 | }; |
395 | 413 | ||
396 | const struct gfs2_glock_operations gfs2_trans_glops = { | 414 | const struct gfs2_glock_operations gfs2_trans_glops = { |