diff options
| -rw-r--r-- | fs/gfs2/glops.c | 10 | ||||
| -rw-r--r-- | fs/gfs2/incore.h | 1 | ||||
| -rw-r--r-- | fs/gfs2/log.c | 30 | ||||
| -rw-r--r-- | fs/gfs2/lops.c | 5 | ||||
| -rw-r--r-- | fs/gfs2/ops_fstype.c | 1 |
5 files changed, 29 insertions, 18 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index ac5fac948f8..3754e3cbf02 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
| @@ -56,20 +56,26 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) | |||
| 56 | BUG_ON(current->journal_info); | 56 | BUG_ON(current->journal_info); |
| 57 | current->journal_info = &tr; | 57 | current->journal_info = &tr; |
| 58 | 58 | ||
| 59 | gfs2_log_lock(sdp); | 59 | spin_lock(&sdp->sd_ail_lock); |
| 60 | while (!list_empty(head)) { | 60 | while (!list_empty(head)) { |
| 61 | bd = list_entry(head->next, struct gfs2_bufdata, | 61 | bd = list_entry(head->next, struct gfs2_bufdata, |
| 62 | bd_ail_gl_list); | 62 | bd_ail_gl_list); |
| 63 | bh = bd->bd_bh; | 63 | bh = bd->bd_bh; |
| 64 | gfs2_remove_from_ail(bd); | 64 | gfs2_remove_from_ail(bd); |
| 65 | spin_unlock(&sdp->sd_ail_lock); | ||
| 66 | |||
| 65 | bd->bd_bh = NULL; | 67 | bd->bd_bh = NULL; |
| 66 | bh->b_private = NULL; | 68 | bh->b_private = NULL; |
| 67 | bd->bd_blkno = bh->b_blocknr; | 69 | bd->bd_blkno = bh->b_blocknr; |
| 70 | gfs2_log_lock(sdp); | ||
| 68 | gfs2_assert_withdraw(sdp, !buffer_busy(bh)); | 71 | gfs2_assert_withdraw(sdp, !buffer_busy(bh)); |
| 69 | gfs2_trans_add_revoke(sdp, bd); | 72 | gfs2_trans_add_revoke(sdp, bd); |
| 73 | gfs2_log_unlock(sdp); | ||
| 74 | |||
| 75 | spin_lock(&sdp->sd_ail_lock); | ||
| 70 | } | 76 | } |
| 71 | gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count)); | 77 | gfs2_assert_withdraw(sdp, !atomic_read(&gl->gl_ail_count)); |
| 72 | gfs2_log_unlock(sdp); | 78 | spin_unlock(&sdp->sd_ail_lock); |
| 73 | 79 | ||
| 74 | gfs2_trans_end(sdp); | 80 | gfs2_trans_end(sdp); |
| 75 | gfs2_log_flush(sdp, NULL); | 81 | gfs2_log_flush(sdp, NULL); |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 59aaaa05113..870a89d6d4d 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
| @@ -651,6 +651,7 @@ struct gfs2_sbd { | |||
| 651 | unsigned int sd_log_flush_head; | 651 | unsigned int sd_log_flush_head; |
| 652 | u64 sd_log_flush_wrapped; | 652 | u64 sd_log_flush_wrapped; |
| 653 | 653 | ||
| 654 | spinlock_t sd_ail_lock; | ||
| 654 | struct list_head sd_ail1_list; | 655 | struct list_head sd_ail1_list; |
| 655 | struct list_head sd_ail2_list; | 656 | struct list_head sd_ail2_list; |
| 656 | u64 sd_ail_sync_gen; | 657 | u64 sd_ail_sync_gen; |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index eb01f3575e1..4e3c044934e 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
| @@ -88,8 +88,8 @@ void gfs2_remove_from_ail(struct gfs2_bufdata *bd) | |||
| 88 | */ | 88 | */ |
| 89 | 89 | ||
| 90 | static void gfs2_ail1_start_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | 90 | static void gfs2_ail1_start_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai) |
| 91 | __releases(&sdp->sd_log_lock) | 91 | __releases(&sdp->sd_ail_lock) |
| 92 | __acquires(&sdp->sd_log_lock) | 92 | __acquires(&sdp->sd_ail_lock) |
| 93 | { | 93 | { |
| 94 | struct gfs2_bufdata *bd, *s; | 94 | struct gfs2_bufdata *bd, *s; |
| 95 | struct buffer_head *bh; | 95 | struct buffer_head *bh; |
| @@ -117,7 +117,7 @@ __acquires(&sdp->sd_log_lock) | |||
| 117 | list_move(&bd->bd_ail_st_list, &ai->ai_ail1_list); | 117 | list_move(&bd->bd_ail_st_list, &ai->ai_ail1_list); |
| 118 | 118 | ||
| 119 | get_bh(bh); | 119 | get_bh(bh); |
| 120 | gfs2_log_unlock(sdp); | 120 | spin_unlock(&sdp->sd_ail_lock); |
| 121 | lock_buffer(bh); | 121 | lock_buffer(bh); |
| 122 | if (test_clear_buffer_dirty(bh)) { | 122 | if (test_clear_buffer_dirty(bh)) { |
| 123 | bh->b_end_io = end_buffer_write_sync; | 123 | bh->b_end_io = end_buffer_write_sync; |
| @@ -126,7 +126,7 @@ __acquires(&sdp->sd_log_lock) | |||
| 126 | unlock_buffer(bh); | 126 | unlock_buffer(bh); |
| 127 | brelse(bh); | 127 | brelse(bh); |
| 128 | } | 128 | } |
| 129 | gfs2_log_lock(sdp); | 129 | spin_lock(&sdp->sd_ail_lock); |
| 130 | 130 | ||
| 131 | retry = 1; | 131 | retry = 1; |
| 132 | break; | 132 | break; |
| @@ -175,10 +175,10 @@ static void gfs2_ail1_start(struct gfs2_sbd *sdp) | |||
| 175 | struct gfs2_ail *ai; | 175 | struct gfs2_ail *ai; |
| 176 | int done = 0; | 176 | int done = 0; |
| 177 | 177 | ||
| 178 | gfs2_log_lock(sdp); | 178 | spin_lock(&sdp->sd_ail_lock); |
| 179 | head = &sdp->sd_ail1_list; | 179 | head = &sdp->sd_ail1_list; |
| 180 | if (list_empty(head)) { | 180 | if (list_empty(head)) { |
| 181 | gfs2_log_unlock(sdp); | 181 | spin_unlock(&sdp->sd_ail_lock); |
| 182 | return; | 182 | return; |
| 183 | } | 183 | } |
| 184 | sync_gen = sdp->sd_ail_sync_gen++; | 184 | sync_gen = sdp->sd_ail_sync_gen++; |
| @@ -189,13 +189,13 @@ static void gfs2_ail1_start(struct gfs2_sbd *sdp) | |||
| 189 | if (ai->ai_sync_gen >= sync_gen) | 189 | if (ai->ai_sync_gen >= sync_gen) |
| 190 | continue; | 190 | continue; |
| 191 | ai->ai_sync_gen = sync_gen; | 191 | ai->ai_sync_gen = sync_gen; |
| 192 | gfs2_ail1_start_one(sdp, ai); /* This may drop log lock */ | 192 | gfs2_ail1_start_one(sdp, ai); /* This may drop ail lock */ |
| 193 | done = 0; | 193 | done = 0; |
| 194 | break; | 194 | break; |
| 195 | } | 195 | } |
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | gfs2_log_unlock(sdp); | 198 | spin_unlock(&sdp->sd_ail_lock); |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | static int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags) | 201 | static int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags) |
| @@ -203,7 +203,7 @@ static int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags) | |||
| 203 | struct gfs2_ail *ai, *s; | 203 | struct gfs2_ail *ai, *s; |
| 204 | int ret; | 204 | int ret; |
| 205 | 205 | ||
| 206 | gfs2_log_lock(sdp); | 206 | spin_lock(&sdp->sd_ail_lock); |
| 207 | 207 | ||
| 208 | list_for_each_entry_safe_reverse(ai, s, &sdp->sd_ail1_list, ai_list) { | 208 | list_for_each_entry_safe_reverse(ai, s, &sdp->sd_ail1_list, ai_list) { |
| 209 | if (gfs2_ail1_empty_one(sdp, ai, flags)) | 209 | if (gfs2_ail1_empty_one(sdp, ai, flags)) |
| @@ -214,7 +214,7 @@ static int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags) | |||
| 214 | 214 | ||
| 215 | ret = list_empty(&sdp->sd_ail1_list); | 215 | ret = list_empty(&sdp->sd_ail1_list); |
| 216 | 216 | ||
| 217 | gfs2_log_unlock(sdp); | 217 | spin_unlock(&sdp->sd_ail_lock); |
| 218 | 218 | ||
| 219 | return ret; | 219 | return ret; |
| 220 | } | 220 | } |
| @@ -247,7 +247,7 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) | |||
| 247 | int wrap = (new_tail < old_tail); | 247 | int wrap = (new_tail < old_tail); |
| 248 | int a, b, rm; | 248 | int a, b, rm; |
| 249 | 249 | ||
| 250 | gfs2_log_lock(sdp); | 250 | spin_lock(&sdp->sd_ail_lock); |
| 251 | 251 | ||
| 252 | list_for_each_entry_safe(ai, safe, &sdp->sd_ail2_list, ai_list) { | 252 | list_for_each_entry_safe(ai, safe, &sdp->sd_ail2_list, ai_list) { |
| 253 | a = (old_tail <= ai->ai_first); | 253 | a = (old_tail <= ai->ai_first); |
| @@ -263,7 +263,7 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) | |||
| 263 | kfree(ai); | 263 | kfree(ai); |
| 264 | } | 264 | } |
| 265 | 265 | ||
| 266 | gfs2_log_unlock(sdp); | 266 | spin_unlock(&sdp->sd_ail_lock); |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | /** | 269 | /** |
| @@ -421,7 +421,7 @@ static unsigned int current_tail(struct gfs2_sbd *sdp) | |||
| 421 | struct gfs2_ail *ai; | 421 | struct gfs2_ail *ai; |
| 422 | unsigned int tail; | 422 | unsigned int tail; |
| 423 | 423 | ||
| 424 | gfs2_log_lock(sdp); | 424 | spin_lock(&sdp->sd_ail_lock); |
| 425 | 425 | ||
| 426 | if (list_empty(&sdp->sd_ail1_list)) { | 426 | if (list_empty(&sdp->sd_ail1_list)) { |
| 427 | tail = sdp->sd_log_head; | 427 | tail = sdp->sd_log_head; |
| @@ -430,7 +430,7 @@ static unsigned int current_tail(struct gfs2_sbd *sdp) | |||
| 430 | tail = ai->ai_first; | 430 | tail = ai->ai_first; |
| 431 | } | 431 | } |
| 432 | 432 | ||
| 433 | gfs2_log_unlock(sdp); | 433 | spin_unlock(&sdp->sd_ail_lock); |
| 434 | 434 | ||
| 435 | return tail; | 435 | return tail; |
| 436 | } | 436 | } |
| @@ -743,10 +743,12 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
| 743 | sdp->sd_log_commited_databuf = 0; | 743 | sdp->sd_log_commited_databuf = 0; |
| 744 | sdp->sd_log_commited_revoke = 0; | 744 | sdp->sd_log_commited_revoke = 0; |
| 745 | 745 | ||
| 746 | spin_lock(&sdp->sd_ail_lock); | ||
| 746 | if (!list_empty(&ai->ai_ail1_list)) { | 747 | if (!list_empty(&ai->ai_ail1_list)) { |
| 747 | list_add(&ai->ai_list, &sdp->sd_ail1_list); | 748 | list_add(&ai->ai_list, &sdp->sd_ail1_list); |
| 748 | ai = NULL; | 749 | ai = NULL; |
| 749 | } | 750 | } |
| 751 | spin_unlock(&sdp->sd_ail_lock); | ||
| 750 | gfs2_log_unlock(sdp); | 752 | gfs2_log_unlock(sdp); |
| 751 | trace_gfs2_log_flush(sdp, 0); | 753 | trace_gfs2_log_flush(sdp, 0); |
| 752 | up_write(&sdp->sd_log_flush_lock); | 754 | up_write(&sdp->sd_log_flush_lock); |
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 11a73efa826..4295a6a0f1e 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
| @@ -80,7 +80,7 @@ static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh, | |||
| 80 | mark_buffer_dirty(bh); | 80 | mark_buffer_dirty(bh); |
| 81 | clear_buffer_pinned(bh); | 81 | clear_buffer_pinned(bh); |
| 82 | 82 | ||
| 83 | gfs2_log_lock(sdp); | 83 | spin_lock(&sdp->sd_ail_lock); |
| 84 | if (bd->bd_ail) { | 84 | if (bd->bd_ail) { |
| 85 | list_del(&bd->bd_ail_st_list); | 85 | list_del(&bd->bd_ail_st_list); |
| 86 | brelse(bh); | 86 | brelse(bh); |
| @@ -91,10 +91,11 @@ static void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh, | |||
| 91 | } | 91 | } |
| 92 | bd->bd_ail = ai; | 92 | bd->bd_ail = ai; |
| 93 | list_add(&bd->bd_ail_st_list, &ai->ai_ail1_list); | 93 | list_add(&bd->bd_ail_st_list, &ai->ai_ail1_list); |
| 94 | spin_unlock(&sdp->sd_ail_lock); | ||
| 95 | |||
| 94 | if (test_and_clear_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags)) | 96 | if (test_and_clear_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags)) |
| 95 | gfs2_glock_schedule_for_reclaim(bd->bd_gl); | 97 | gfs2_glock_schedule_for_reclaim(bd->bd_gl); |
| 96 | trace_gfs2_pin(bd, 0); | 98 | trace_gfs2_pin(bd, 0); |
| 97 | gfs2_log_unlock(sdp); | ||
| 98 | unlock_buffer(bh); | 99 | unlock_buffer(bh); |
| 99 | atomic_dec(&sdp->sd_log_pinned); | 100 | atomic_dec(&sdp->sd_log_pinned); |
| 100 | } | 101 | } |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 67654d0ba15..42ef24355af 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
| @@ -99,6 +99,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) | |||
| 99 | 99 | ||
| 100 | init_waitqueue_head(&sdp->sd_log_waitq); | 100 | init_waitqueue_head(&sdp->sd_log_waitq); |
| 101 | init_waitqueue_head(&sdp->sd_logd_waitq); | 101 | init_waitqueue_head(&sdp->sd_logd_waitq); |
| 102 | spin_lock_init(&sdp->sd_ail_lock); | ||
| 102 | INIT_LIST_HEAD(&sdp->sd_ail1_list); | 103 | INIT_LIST_HEAD(&sdp->sd_ail1_list); |
| 103 | INIT_LIST_HEAD(&sdp->sd_ail2_list); | 104 | INIT_LIST_HEAD(&sdp->sd_ail2_list); |
| 104 | 105 | ||
