diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/glops.c | 2 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 6 | ||||
-rw-r--r-- | fs/gfs2/log.c | 28 | ||||
-rw-r--r-- | fs/gfs2/lops.c | 32 | ||||
-rw-r--r-- | fs/gfs2/lops.h | 5 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 2 | ||||
-rw-r--r-- | fs/gfs2/trans.c | 7 |
7 files changed, 53 insertions, 29 deletions
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 3bf0631b5d56..54b66809e818 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -82,6 +82,8 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) | |||
82 | struct gfs2_trans tr; | 82 | struct gfs2_trans tr; |
83 | 83 | ||
84 | memset(&tr, 0, sizeof(tr)); | 84 | memset(&tr, 0, sizeof(tr)); |
85 | INIT_LIST_HEAD(&tr.tr_buf); | ||
86 | INIT_LIST_HEAD(&tr.tr_databuf); | ||
85 | tr.tr_revokes = atomic_read(&gl->gl_ail_count); | 87 | tr.tr_revokes = atomic_read(&gl->gl_ail_count); |
86 | 88 | ||
87 | if (!tr.tr_revokes) | 89 | if (!tr.tr_revokes) |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 645655cccdc8..99aab64c771a 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -52,7 +52,7 @@ struct gfs2_log_header_host { | |||
52 | */ | 52 | */ |
53 | 53 | ||
54 | struct gfs2_log_operations { | 54 | struct gfs2_log_operations { |
55 | void (*lo_before_commit) (struct gfs2_sbd *sdp); | 55 | void (*lo_before_commit) (struct gfs2_sbd *sdp, struct gfs2_trans *tr); |
56 | void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_trans *tr); | 56 | void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_trans *tr); |
57 | void (*lo_before_scan) (struct gfs2_jdesc *jd, | 57 | void (*lo_before_scan) (struct gfs2_jdesc *jd, |
58 | struct gfs2_log_header_host *head, int pass); | 58 | struct gfs2_log_header_host *head, int pass); |
@@ -476,6 +476,8 @@ struct gfs2_trans { | |||
476 | unsigned int tr_num_revoke_rm; | 476 | unsigned int tr_num_revoke_rm; |
477 | 477 | ||
478 | struct list_head tr_list; | 478 | struct list_head tr_list; |
479 | struct list_head tr_databuf; | ||
480 | struct list_head tr_buf; | ||
479 | 481 | ||
480 | unsigned int tr_first; | 482 | unsigned int tr_first; |
481 | struct list_head tr_ail1_list; | 483 | struct list_head tr_ail1_list; |
@@ -756,9 +758,7 @@ struct gfs2_sbd { | |||
756 | unsigned int sd_log_num_rg; | 758 | unsigned int sd_log_num_rg; |
757 | unsigned int sd_log_num_databuf; | 759 | unsigned int sd_log_num_databuf; |
758 | 760 | ||
759 | struct list_head sd_log_le_buf; | ||
760 | struct list_head sd_log_le_revoke; | 761 | struct list_head sd_log_le_revoke; |
761 | struct list_head sd_log_le_databuf; | ||
762 | struct list_head sd_log_le_ordered; | 762 | struct list_head sd_log_le_ordered; |
763 | spinlock_t sd_ordered_lock; | 763 | spinlock_t sd_ordered_lock; |
764 | 764 | ||
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 1e1bda0de43d..975712c6660b 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -712,7 +712,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
712 | tr->tr_first = sdp->sd_log_flush_head; | 712 | tr->tr_first = sdp->sd_log_flush_head; |
713 | 713 | ||
714 | gfs2_ordered_write(sdp); | 714 | gfs2_ordered_write(sdp); |
715 | lops_before_commit(sdp); | 715 | lops_before_commit(sdp, tr); |
716 | gfs2_log_flush_bio(sdp, WRITE); | 716 | gfs2_log_flush_bio(sdp, WRITE); |
717 | 717 | ||
718 | if (sdp->sd_log_head != sdp->sd_log_flush_head) { | 718 | if (sdp->sd_log_head != sdp->sd_log_flush_head) { |
@@ -744,6 +744,27 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
744 | kfree(tr); | 744 | kfree(tr); |
745 | } | 745 | } |
746 | 746 | ||
747 | /** | ||
748 | * gfs2_merge_trans - Merge a new transaction into a cached transaction | ||
749 | * @old: Original transaction to be expanded | ||
750 | * @new: New transaction to be merged | ||
751 | */ | ||
752 | |||
753 | static void gfs2_merge_trans(struct gfs2_trans *old, struct gfs2_trans *new) | ||
754 | { | ||
755 | WARN_ON_ONCE(old->tr_attached != 1); | ||
756 | |||
757 | old->tr_num_buf_new += new->tr_num_buf_new; | ||
758 | old->tr_num_databuf_new += new->tr_num_databuf_new; | ||
759 | old->tr_num_buf_rm += new->tr_num_buf_rm; | ||
760 | old->tr_num_databuf_rm += new->tr_num_databuf_rm; | ||
761 | old->tr_num_revoke += new->tr_num_revoke; | ||
762 | old->tr_num_revoke_rm += new->tr_num_revoke_rm; | ||
763 | |||
764 | list_splice_tail_init(&new->tr_databuf, &old->tr_databuf); | ||
765 | list_splice_tail_init(&new->tr_buf, &old->tr_buf); | ||
766 | } | ||
767 | |||
747 | static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | 768 | static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
748 | { | 769 | { |
749 | unsigned int reserved; | 770 | unsigned int reserved; |
@@ -766,8 +787,9 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | |||
766 | sdp->sd_jdesc->jd_blocks); | 787 | sdp->sd_jdesc->jd_blocks); |
767 | sdp->sd_log_blks_reserved = reserved; | 788 | sdp->sd_log_blks_reserved = reserved; |
768 | 789 | ||
769 | if (sdp->sd_log_tr == NULL && | 790 | if (sdp->sd_log_tr) { |
770 | (tr->tr_num_buf_new || tr->tr_num_databuf_new)) { | 791 | gfs2_merge_trans(sdp->sd_log_tr, tr); |
792 | } else if (tr->tr_num_buf_new || tr->tr_num_databuf_new) { | ||
771 | gfs2_assert_withdraw(sdp, tr->tr_t_gh.gh_gl); | 793 | gfs2_assert_withdraw(sdp, tr->tr_t_gh.gh_gl); |
772 | sdp->sd_log_tr = tr; | 794 | sdp->sd_log_tr = tr; |
773 | tr->tr_attached = 1; | 795 | tr->tr_attached = 1; |
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 76693793cedd..ee9ec7fa3011 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
@@ -491,24 +491,23 @@ static void gfs2_before_commit(struct gfs2_sbd *sdp, unsigned int limit, | |||
491 | gfs2_log_unlock(sdp); | 491 | gfs2_log_unlock(sdp); |
492 | } | 492 | } |
493 | 493 | ||
494 | static void buf_lo_before_commit(struct gfs2_sbd *sdp) | 494 | static void buf_lo_before_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
495 | { | 495 | { |
496 | unsigned int limit = buf_limit(sdp); /* 503 for 4k blocks */ | 496 | unsigned int limit = buf_limit(sdp); /* 503 for 4k blocks */ |
497 | 497 | if (tr == NULL) | |
498 | gfs2_before_commit(sdp, limit, sdp->sd_log_num_buf, | 498 | return; |
499 | &sdp->sd_log_le_buf, 0); | 499 | gfs2_before_commit(sdp, limit, sdp->sd_log_num_buf, &tr->tr_buf, 0); |
500 | } | 500 | } |
501 | 501 | ||
502 | static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | 502 | static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
503 | { | 503 | { |
504 | struct list_head *head = &sdp->sd_log_le_buf; | 504 | struct list_head *head; |
505 | struct gfs2_bufdata *bd; | 505 | struct gfs2_bufdata *bd; |
506 | 506 | ||
507 | if (tr == NULL) { | 507 | if (tr == NULL) |
508 | gfs2_assert(sdp, list_empty(head)); | ||
509 | return; | 508 | return; |
510 | } | ||
511 | 509 | ||
510 | head = &tr->tr_buf; | ||
512 | while (!list_empty(head)) { | 511 | while (!list_empty(head)) { |
513 | bd = list_entry(head->next, struct gfs2_bufdata, bd_list); | 512 | bd = list_entry(head->next, struct gfs2_bufdata, bd_list); |
514 | list_del_init(&bd->bd_list); | 513 | list_del_init(&bd->bd_list); |
@@ -620,7 +619,7 @@ static void buf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass) | |||
620 | jd->jd_jid, sdp->sd_replayed_blocks, sdp->sd_found_blocks); | 619 | jd->jd_jid, sdp->sd_replayed_blocks, sdp->sd_found_blocks); |
621 | } | 620 | } |
622 | 621 | ||
623 | static void revoke_lo_before_commit(struct gfs2_sbd *sdp) | 622 | static void revoke_lo_before_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
624 | { | 623 | { |
625 | struct gfs2_meta_header *mh; | 624 | struct gfs2_meta_header *mh; |
626 | unsigned int offset; | 625 | unsigned int offset; |
@@ -760,12 +759,12 @@ static void revoke_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass) | |||
760 | * | 759 | * |
761 | */ | 760 | */ |
762 | 761 | ||
763 | static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | 762 | static void databuf_lo_before_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
764 | { | 763 | { |
765 | unsigned int limit = buf_limit(sdp) / 2; | 764 | unsigned int limit = buf_limit(sdp) / 2; |
766 | 765 | if (tr == NULL) | |
767 | gfs2_before_commit(sdp, limit, sdp->sd_log_num_databuf, | 766 | return; |
768 | &sdp->sd_log_le_databuf, 1); | 767 | gfs2_before_commit(sdp, limit, sdp->sd_log_num_databuf, &tr->tr_databuf, 1); |
769 | } | 768 | } |
770 | 769 | ||
771 | static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start, | 770 | static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start, |
@@ -840,14 +839,13 @@ static void databuf_lo_after_scan(struct gfs2_jdesc *jd, int error, int pass) | |||
840 | 839 | ||
841 | static void databuf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | 840 | static void databuf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
842 | { | 841 | { |
843 | struct list_head *head = &sdp->sd_log_le_databuf; | 842 | struct list_head *head; |
844 | struct gfs2_bufdata *bd; | 843 | struct gfs2_bufdata *bd; |
845 | 844 | ||
846 | if (tr == NULL) { | 845 | if (tr == NULL) |
847 | gfs2_assert(sdp, list_empty(head)); | ||
848 | return; | 846 | return; |
849 | } | ||
850 | 847 | ||
848 | head = &tr->tr_databuf; | ||
851 | while (!list_empty(head)) { | 849 | while (!list_empty(head)) { |
852 | bd = list_entry(head->next, struct gfs2_bufdata, bd_list); | 850 | bd = list_entry(head->next, struct gfs2_bufdata, bd_list); |
853 | list_del_init(&bd->bd_list); | 851 | list_del_init(&bd->bd_list); |
diff --git a/fs/gfs2/lops.h b/fs/gfs2/lops.h index 9ca2e6438419..a65a7ba32ffd 100644 --- a/fs/gfs2/lops.h +++ b/fs/gfs2/lops.h | |||
@@ -46,12 +46,13 @@ static inline unsigned int databuf_limit(struct gfs2_sbd *sdp) | |||
46 | return limit; | 46 | return limit; |
47 | } | 47 | } |
48 | 48 | ||
49 | static inline void lops_before_commit(struct gfs2_sbd *sdp) | 49 | static inline void lops_before_commit(struct gfs2_sbd *sdp, |
50 | struct gfs2_trans *tr) | ||
50 | { | 51 | { |
51 | int x; | 52 | int x; |
52 | for (x = 0; gfs2_log_ops[x]; x++) | 53 | for (x = 0; gfs2_log_ops[x]; x++) |
53 | if (gfs2_log_ops[x]->lo_before_commit) | 54 | if (gfs2_log_ops[x]->lo_before_commit) |
54 | gfs2_log_ops[x]->lo_before_commit(sdp); | 55 | gfs2_log_ops[x]->lo_before_commit(sdp, tr); |
55 | } | 56 | } |
56 | 57 | ||
57 | static inline void lops_after_commit(struct gfs2_sbd *sdp, | 58 | static inline void lops_after_commit(struct gfs2_sbd *sdp, |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index c6872d09561a..1f855a74a4ec 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -114,9 +114,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) | |||
114 | 114 | ||
115 | spin_lock_init(&sdp->sd_log_lock); | 115 | spin_lock_init(&sdp->sd_log_lock); |
116 | atomic_set(&sdp->sd_log_pinned, 0); | 116 | atomic_set(&sdp->sd_log_pinned, 0); |
117 | INIT_LIST_HEAD(&sdp->sd_log_le_buf); | ||
118 | INIT_LIST_HEAD(&sdp->sd_log_le_revoke); | 117 | INIT_LIST_HEAD(&sdp->sd_log_le_revoke); |
119 | INIT_LIST_HEAD(&sdp->sd_log_le_databuf); | ||
120 | INIT_LIST_HEAD(&sdp->sd_log_le_ordered); | 118 | INIT_LIST_HEAD(&sdp->sd_log_le_ordered); |
121 | spin_lock_init(&sdp->sd_ordered_lock); | 119 | spin_lock_init(&sdp->sd_ordered_lock); |
122 | 120 | ||
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c index 963b28c50fd4..e0464a22908c 100644 --- a/fs/gfs2/trans.c +++ b/fs/gfs2/trans.c | |||
@@ -51,6 +51,9 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks, | |||
51 | if (revokes) | 51 | if (revokes) |
52 | tr->tr_reserved += gfs2_struct2blk(sdp, revokes, | 52 | tr->tr_reserved += gfs2_struct2blk(sdp, revokes, |
53 | sizeof(u64)); | 53 | sizeof(u64)); |
54 | INIT_LIST_HEAD(&tr->tr_databuf); | ||
55 | INIT_LIST_HEAD(&tr->tr_buf); | ||
56 | |||
54 | sb_start_intwrite(sdp->sd_vfs); | 57 | sb_start_intwrite(sdp->sd_vfs); |
55 | gfs2_holder_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &tr->tr_t_gh); | 58 | gfs2_holder_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &tr->tr_t_gh); |
56 | 59 | ||
@@ -211,7 +214,7 @@ void gfs2_trans_add_data(struct gfs2_glock *gl, struct buffer_head *bh) | |||
211 | gfs2_pin(sdp, bd->bd_bh); | 214 | gfs2_pin(sdp, bd->bd_bh); |
212 | tr->tr_num_databuf_new++; | 215 | tr->tr_num_databuf_new++; |
213 | sdp->sd_log_num_databuf++; | 216 | sdp->sd_log_num_databuf++; |
214 | list_add_tail(&bd->bd_list, &sdp->sd_log_le_databuf); | 217 | list_add_tail(&bd->bd_list, &tr->tr_databuf); |
215 | } | 218 | } |
216 | gfs2_log_unlock(sdp); | 219 | gfs2_log_unlock(sdp); |
217 | unlock_buffer(bh); | 220 | unlock_buffer(bh); |
@@ -239,7 +242,7 @@ static void meta_lo_add(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) | |||
239 | mh->__pad0 = cpu_to_be64(0); | 242 | mh->__pad0 = cpu_to_be64(0); |
240 | mh->mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid); | 243 | mh->mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid); |
241 | sdp->sd_log_num_buf++; | 244 | sdp->sd_log_num_buf++; |
242 | list_add(&bd->bd_list, &sdp->sd_log_le_buf); | 245 | list_add(&bd->bd_list, &tr->tr_buf); |
243 | tr->tr_num_buf_new++; | 246 | tr->tr_num_buf_new++; |
244 | } | 247 | } |
245 | 248 | ||