diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2006-02-21 07:51:39 -0500 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-02-21 07:51:39 -0500 |
commit | f55ab26a8f92a23988c3e6da28dae4741933a4e2 (patch) | |
tree | b6f9e89ce1b2ccde8d81314aeea06f6a02f882f7 /fs/gfs2/log.c | |
parent | 5c4e9e036678fae65c9288e1c00a6f33cd447283 (diff) |
[GFS2] Use mutices rather than semaphores
As well as a number of minor bug fixes, this patch changes GFS
to use mutices rather than semaphores. This results in better
information in case there are any locking problems.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/log.c')
-rw-r--r-- | fs/gfs2/log.c | 54 |
1 files changed, 19 insertions, 35 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 49190a29dd4f..e6acb41332e7 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -23,29 +23,16 @@ | |||
23 | 23 | ||
24 | #define PULL 1 | 24 | #define PULL 1 |
25 | 25 | ||
26 | static inline int is_done(struct gfs2_sbd *sdp, atomic_t *a) | ||
27 | { | ||
28 | int done; | ||
29 | gfs2_log_lock(sdp); | ||
30 | done = atomic_read(a) ? 0 : 1; | ||
31 | gfs2_log_unlock(sdp); | ||
32 | return done; | ||
33 | } | ||
34 | |||
35 | static void do_lock_wait(struct gfs2_sbd *sdp, wait_queue_head_t *wq, | 26 | static void do_lock_wait(struct gfs2_sbd *sdp, wait_queue_head_t *wq, |
36 | atomic_t *a) | 27 | atomic_t *a) |
37 | { | 28 | { |
38 | gfs2_log_unlock(sdp); | 29 | wait_event(*wq, atomic_read(a) ? 0 : 1); |
39 | wait_event(*wq, is_done(sdp, a)); | ||
40 | gfs2_log_lock(sdp); | ||
41 | } | 30 | } |
42 | 31 | ||
43 | static void lock_for_trans(struct gfs2_sbd *sdp) | 32 | static void lock_for_trans(struct gfs2_sbd *sdp) |
44 | { | 33 | { |
45 | gfs2_log_lock(sdp); | ||
46 | do_lock_wait(sdp, &sdp->sd_log_trans_wq, &sdp->sd_log_flush_count); | 34 | do_lock_wait(sdp, &sdp->sd_log_trans_wq, &sdp->sd_log_flush_count); |
47 | atomic_inc(&sdp->sd_log_trans_count); | 35 | atomic_inc(&sdp->sd_log_trans_count); |
48 | gfs2_log_unlock(sdp); | ||
49 | } | 36 | } |
50 | 37 | ||
51 | static void unlock_from_trans(struct gfs2_sbd *sdp) | 38 | static void unlock_from_trans(struct gfs2_sbd *sdp) |
@@ -55,15 +42,13 @@ static void unlock_from_trans(struct gfs2_sbd *sdp) | |||
55 | wake_up(&sdp->sd_log_flush_wq); | 42 | wake_up(&sdp->sd_log_flush_wq); |
56 | } | 43 | } |
57 | 44 | ||
58 | void gfs2_lock_for_flush(struct gfs2_sbd *sdp) | 45 | static void gfs2_lock_for_flush(struct gfs2_sbd *sdp) |
59 | { | 46 | { |
60 | gfs2_log_lock(sdp); | ||
61 | atomic_inc(&sdp->sd_log_flush_count); | 47 | atomic_inc(&sdp->sd_log_flush_count); |
62 | do_lock_wait(sdp, &sdp->sd_log_flush_wq, &sdp->sd_log_trans_count); | 48 | do_lock_wait(sdp, &sdp->sd_log_flush_wq, &sdp->sd_log_trans_count); |
63 | gfs2_log_unlock(sdp); | ||
64 | } | 49 | } |
65 | 50 | ||
66 | void gfs2_unlock_from_flush(struct gfs2_sbd *sdp) | 51 | static void gfs2_unlock_from_flush(struct gfs2_sbd *sdp) |
67 | { | 52 | { |
68 | gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_flush_count)); | 53 | gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_flush_count)); |
69 | if (atomic_dec_and_test(&sdp->sd_log_flush_count)) | 54 | if (atomic_dec_and_test(&sdp->sd_log_flush_count)) |
@@ -209,7 +194,6 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) | |||
209 | 194 | ||
210 | for (;;) { | 195 | for (;;) { |
211 | gfs2_log_lock(sdp); | 196 | gfs2_log_lock(sdp); |
212 | |||
213 | if (list_empty(&list)) { | 197 | if (list_empty(&list)) { |
214 | list_add_tail(&list, &sdp->sd_log_blks_list); | 198 | list_add_tail(&list, &sdp->sd_log_blks_list); |
215 | while (sdp->sd_log_blks_list.next != &list) { | 199 | while (sdp->sd_log_blks_list.next != &list) { |
@@ -225,7 +209,6 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) | |||
225 | set_current_state(TASK_RUNNING); | 209 | set_current_state(TASK_RUNNING); |
226 | } | 210 | } |
227 | } | 211 | } |
228 | |||
229 | /* Never give away the last block so we can | 212 | /* Never give away the last block so we can |
230 | always pull the tail if we need to. */ | 213 | always pull the tail if we need to. */ |
231 | if (sdp->sd_log_blks_free > blks) { | 214 | if (sdp->sd_log_blks_free > blks) { |
@@ -237,14 +220,12 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) | |||
237 | } | 220 | } |
238 | 221 | ||
239 | gfs2_log_unlock(sdp); | 222 | gfs2_log_unlock(sdp); |
240 | |||
241 | gfs2_ail1_empty(sdp, 0); | 223 | gfs2_ail1_empty(sdp, 0); |
242 | gfs2_log_flush(sdp); | 224 | gfs2_log_flush(sdp); |
243 | 225 | ||
244 | if (try++) | 226 | if (try++) |
245 | gfs2_ail1_start(sdp, 0); | 227 | gfs2_ail1_start(sdp, 0); |
246 | } | 228 | } |
247 | |||
248 | lock_for_trans(sdp); | 229 | lock_for_trans(sdp); |
249 | 230 | ||
250 | return 0; | 231 | return 0; |
@@ -512,22 +493,26 @@ void gfs2_log_flush_i(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
512 | ai = kzalloc(sizeof(struct gfs2_ail), GFP_NOFS | __GFP_NOFAIL); | 493 | ai = kzalloc(sizeof(struct gfs2_ail), GFP_NOFS | __GFP_NOFAIL); |
513 | INIT_LIST_HEAD(&ai->ai_ail1_list); | 494 | INIT_LIST_HEAD(&ai->ai_ail1_list); |
514 | INIT_LIST_HEAD(&ai->ai_ail2_list); | 495 | INIT_LIST_HEAD(&ai->ai_ail2_list); |
515 | |||
516 | gfs2_lock_for_flush(sdp); | 496 | gfs2_lock_for_flush(sdp); |
517 | down(&sdp->sd_log_flush_lock); | 497 | |
498 | if (gl) { | ||
499 | gfs2_log_lock(sdp); | ||
500 | if (list_empty(&gl->gl_le.le_list)) { | ||
501 | gfs2_log_unlock(sdp); | ||
502 | gfs2_unlock_from_flush(sdp); | ||
503 | kfree(ai); | ||
504 | return; | ||
505 | } | ||
506 | gfs2_log_unlock(sdp); | ||
507 | } | ||
508 | |||
509 | mutex_lock(&sdp->sd_log_flush_lock); | ||
518 | 510 | ||
519 | gfs2_assert_withdraw(sdp, | 511 | gfs2_assert_withdraw(sdp, |
520 | sdp->sd_log_num_buf == sdp->sd_log_commited_buf); | 512 | sdp->sd_log_num_buf == sdp->sd_log_commited_buf); |
521 | gfs2_assert_withdraw(sdp, | 513 | gfs2_assert_withdraw(sdp, |
522 | sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); | 514 | sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); |
523 | 515 | ||
524 | if (gl && list_empty(&gl->gl_le.le_list)) { | ||
525 | up(&sdp->sd_log_flush_lock); | ||
526 | gfs2_unlock_from_flush(sdp); | ||
527 | kfree(ai); | ||
528 | return; | ||
529 | } | ||
530 | |||
531 | sdp->sd_log_flush_head = sdp->sd_log_head; | 516 | sdp->sd_log_flush_head = sdp->sd_log_head; |
532 | sdp->sd_log_flush_wrapped = 0; | 517 | sdp->sd_log_flush_wrapped = 0; |
533 | ai->ai_first = sdp->sd_log_flush_head; | 518 | ai->ai_first = sdp->sd_log_flush_head; |
@@ -538,7 +523,6 @@ void gfs2_log_flush_i(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
538 | else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle) | 523 | else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle) |
539 | log_write_header(sdp, 0, PULL); | 524 | log_write_header(sdp, 0, PULL); |
540 | lops_after_commit(sdp, ai); | 525 | lops_after_commit(sdp, ai); |
541 | |||
542 | sdp->sd_log_head = sdp->sd_log_flush_head; | 526 | sdp->sd_log_head = sdp->sd_log_flush_head; |
543 | if (sdp->sd_log_flush_wrapped) | 527 | if (sdp->sd_log_flush_wrapped) |
544 | sdp->sd_log_wraps++; | 528 | sdp->sd_log_wraps++; |
@@ -554,7 +538,7 @@ void gfs2_log_flush_i(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
554 | } | 538 | } |
555 | gfs2_log_unlock(sdp); | 539 | gfs2_log_unlock(sdp); |
556 | 540 | ||
557 | up(&sdp->sd_log_flush_lock); | 541 | mutex_unlock(&sdp->sd_log_flush_lock); |
558 | sdp->sd_vfs->s_dirt = 0; | 542 | sdp->sd_vfs->s_dirt = 0; |
559 | gfs2_unlock_from_flush(sdp); | 543 | gfs2_unlock_from_flush(sdp); |
560 | 544 | ||
@@ -627,7 +611,7 @@ void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | |||
627 | 611 | ||
628 | void gfs2_log_shutdown(struct gfs2_sbd *sdp) | 612 | void gfs2_log_shutdown(struct gfs2_sbd *sdp) |
629 | { | 613 | { |
630 | down(&sdp->sd_log_flush_lock); | 614 | mutex_lock(&sdp->sd_log_flush_lock); |
631 | 615 | ||
632 | gfs2_assert_withdraw(sdp, !atomic_read(&sdp->sd_log_trans_count)); | 616 | gfs2_assert_withdraw(sdp, !atomic_read(&sdp->sd_log_trans_count)); |
633 | gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved); | 617 | gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved); |
@@ -654,6 +638,6 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp) | |||
654 | sdp->sd_log_wraps++; | 638 | sdp->sd_log_wraps++; |
655 | sdp->sd_log_tail = sdp->sd_log_head; | 639 | sdp->sd_log_tail = sdp->sd_log_head; |
656 | 640 | ||
657 | up(&sdp->sd_log_flush_lock); | 641 | mutex_unlock(&sdp->sd_log_flush_lock); |
658 | } | 642 | } |
659 | 643 | ||