aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/log.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-02-21 07:51:39 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2006-02-21 07:51:39 -0500
commitf55ab26a8f92a23988c3e6da28dae4741933a4e2 (patch)
treeb6f9e89ce1b2ccde8d81314aeea06f6a02f882f7 /fs/gfs2/log.c
parent5c4e9e036678fae65c9288e1c00a6f33cd447283 (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.c54
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
26static 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
35static void do_lock_wait(struct gfs2_sbd *sdp, wait_queue_head_t *wq, 26static 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
43static void lock_for_trans(struct gfs2_sbd *sdp) 32static 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
51static void unlock_from_trans(struct gfs2_sbd *sdp) 38static 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
58void gfs2_lock_for_flush(struct gfs2_sbd *sdp) 45static 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
66void gfs2_unlock_from_flush(struct gfs2_sbd *sdp) 51static 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
628void gfs2_log_shutdown(struct gfs2_sbd *sdp) 612void 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