aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/log.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/log.c')
-rw-r--r--fs/gfs2/log.c78
1 files changed, 74 insertions, 4 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index b404f4853034..610613fb65b5 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -211,15 +211,16 @@ static void gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
211static int gfs2_ail1_empty(struct gfs2_sbd *sdp) 211static int gfs2_ail1_empty(struct gfs2_sbd *sdp)
212{ 212{
213 struct gfs2_trans *tr, *s; 213 struct gfs2_trans *tr, *s;
214 int oldest_tr = 1;
214 int ret; 215 int ret;
215 216
216 spin_lock(&sdp->sd_ail_lock); 217 spin_lock(&sdp->sd_ail_lock);
217 list_for_each_entry_safe_reverse(tr, s, &sdp->sd_ail1_list, tr_list) { 218 list_for_each_entry_safe_reverse(tr, s, &sdp->sd_ail1_list, tr_list) {
218 gfs2_ail1_empty_one(sdp, tr); 219 gfs2_ail1_empty_one(sdp, tr);
219 if (list_empty(&tr->tr_ail1_list)) 220 if (list_empty(&tr->tr_ail1_list) && oldest_tr)
220 list_move(&tr->tr_list, &sdp->sd_ail2_list); 221 list_move(&tr->tr_list, &sdp->sd_ail2_list);
221 else 222 else
222 break; 223 oldest_tr = 0;
223 } 224 }
224 ret = list_empty(&sdp->sd_ail1_list); 225 ret = list_empty(&sdp->sd_ail1_list);
225 spin_unlock(&sdp->sd_ail_lock); 226 spin_unlock(&sdp->sd_ail_lock);
@@ -317,7 +318,7 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail)
317 318
318int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) 319int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
319{ 320{
320 unsigned reserved_blks = 6 * (4096 / sdp->sd_vfs->s_blocksize); 321 unsigned reserved_blks = 7 * (4096 / sdp->sd_vfs->s_blocksize);
321 unsigned wanted = blks + reserved_blks; 322 unsigned wanted = blks + reserved_blks;
322 DEFINE_WAIT(wait); 323 DEFINE_WAIT(wait);
323 int did_wait = 0; 324 int did_wait = 0;
@@ -545,6 +546,76 @@ void gfs2_ordered_del_inode(struct gfs2_inode *ip)
545 spin_unlock(&sdp->sd_ordered_lock); 546 spin_unlock(&sdp->sd_ordered_lock);
546} 547}
547 548
549void gfs2_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd)
550{
551 struct buffer_head *bh = bd->bd_bh;
552 struct gfs2_glock *gl = bd->bd_gl;
553
554 gfs2_remove_from_ail(bd);
555 bd->bd_bh = NULL;
556 bh->b_private = NULL;
557 bd->bd_blkno = bh->b_blocknr;
558 bd->bd_ops = &gfs2_revoke_lops;
559 sdp->sd_log_num_revoke++;
560 atomic_inc(&gl->gl_revokes);
561 set_bit(GLF_LFLUSH, &gl->gl_flags);
562 list_add(&bd->bd_list, &sdp->sd_log_le_revoke);
563}
564
565void gfs2_write_revokes(struct gfs2_sbd *sdp)
566{
567 struct gfs2_trans *tr;
568 struct gfs2_bufdata *bd, *tmp;
569 int have_revokes = 0;
570 int max_revokes = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / sizeof(u64);
571
572 gfs2_ail1_empty(sdp);
573 spin_lock(&sdp->sd_ail_lock);
574 list_for_each_entry(tr, &sdp->sd_ail1_list, tr_list) {
575 list_for_each_entry(bd, &tr->tr_ail2_list, bd_ail_st_list) {
576 if (list_empty(&bd->bd_list)) {
577 have_revokes = 1;
578 goto done;
579 }
580 }
581 }
582done:
583 spin_unlock(&sdp->sd_ail_lock);
584 if (have_revokes == 0)
585 return;
586 while (sdp->sd_log_num_revoke > max_revokes)
587 max_revokes += (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header)) / sizeof(u64);
588 max_revokes -= sdp->sd_log_num_revoke;
589 if (!sdp->sd_log_num_revoke) {
590 atomic_dec(&sdp->sd_log_blks_free);
591 /* If no blocks have been reserved, we need to also
592 * reserve a block for the header */
593 if (!sdp->sd_log_blks_reserved)
594 atomic_dec(&sdp->sd_log_blks_free);
595 }
596 gfs2_log_lock(sdp);
597 spin_lock(&sdp->sd_ail_lock);
598 list_for_each_entry(tr, &sdp->sd_ail1_list, tr_list) {
599 list_for_each_entry_safe(bd, tmp, &tr->tr_ail2_list, bd_ail_st_list) {
600 if (max_revokes == 0)
601 goto out_of_blocks;
602 if (!list_empty(&bd->bd_list))
603 continue;
604 gfs2_add_revoke(sdp, bd);
605 max_revokes--;
606 }
607 }
608out_of_blocks:
609 spin_unlock(&sdp->sd_ail_lock);
610 gfs2_log_unlock(sdp);
611
612 if (!sdp->sd_log_num_revoke) {
613 atomic_inc(&sdp->sd_log_blks_free);
614 if (!sdp->sd_log_blks_reserved)
615 atomic_inc(&sdp->sd_log_blks_free);
616 }
617}
618
548/** 619/**
549 * log_write_header - Get and initialize a journal header buffer 620 * log_write_header - Get and initialize a journal header buffer
550 * @sdp: The GFS2 superblock 621 * @sdp: The GFS2 superblock
@@ -562,7 +633,6 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags)
562 lh = page_address(page); 633 lh = page_address(page);
563 clear_page(lh); 634 clear_page(lh);
564 635
565 gfs2_ail1_empty(sdp);
566 tail = current_tail(sdp); 636 tail = current_tail(sdp);
567 637
568 lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC); 638 lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC);