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.c100
1 files changed, 76 insertions, 24 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index fbdc0dc9923e..8fcfb784f906 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -276,7 +276,7 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail)
276 * @blks: The number of blocks to reserve 276 * @blks: The number of blocks to reserve
277 * 277 *
278 * Note that we never give out the last few blocks of the journal. Thats 278 * Note that we never give out the last few blocks of the journal. Thats
279 * due to the fact that there is are a small number of header blocks 279 * due to the fact that there is a small number of header blocks
280 * associated with each log flush. The exact number can't be known until 280 * associated with each log flush. The exact number can't be known until
281 * flush time, so we ensure that we have just enough free blocks at all 281 * flush time, so we ensure that we have just enough free blocks at all
282 * times to avoid running out during a log flush. 282 * times to avoid running out during a log flush.
@@ -371,6 +371,58 @@ static inline unsigned int log_distance(struct gfs2_sbd *sdp, unsigned int newer
371 return dist; 371 return dist;
372} 372}
373 373
374/**
375 * calc_reserved - Calculate the number of blocks to reserve when
376 * refunding a transaction's unused buffers.
377 * @sdp: The GFS2 superblock
378 *
379 * This is complex. We need to reserve room for all our currently used
380 * metadata buffers (e.g. normal file I/O rewriting file time stamps) and
381 * all our journaled data buffers for journaled files (e.g. files in the
382 * meta_fs like rindex, or files for which chattr +j was done.)
383 * If we don't reserve enough space, gfs2_log_refund and gfs2_log_flush
384 * will count it as free space (sd_log_blks_free) and corruption will follow.
385 *
386 * We can have metadata bufs and jdata bufs in the same journal. So each
387 * type gets its own log header, for which we need to reserve a block.
388 * In fact, each type has the potential for needing more than one header
389 * in cases where we have more buffers than will fit on a journal page.
390 * Metadata journal entries take up half the space of journaled buffer entries.
391 * Thus, metadata entries have buf_limit (502) and journaled buffers have
392 * databuf_limit (251) before they cause a wrap around.
393 *
394 * Also, we need to reserve blocks for revoke journal entries and one for an
395 * overall header for the lot.
396 *
397 * Returns: the number of blocks reserved
398 */
399static unsigned int calc_reserved(struct gfs2_sbd *sdp)
400{
401 unsigned int reserved = 0;
402 unsigned int mbuf_limit, metabufhdrs_needed;
403 unsigned int dbuf_limit, databufhdrs_needed;
404 unsigned int revokes = 0;
405
406 mbuf_limit = buf_limit(sdp);
407 metabufhdrs_needed = (sdp->sd_log_commited_buf +
408 (mbuf_limit - 1)) / mbuf_limit;
409 dbuf_limit = databuf_limit(sdp);
410 databufhdrs_needed = (sdp->sd_log_commited_databuf +
411 (dbuf_limit - 1)) / dbuf_limit;
412
413 if (sdp->sd_log_commited_revoke)
414 revokes = gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke,
415 sizeof(u64));
416
417 reserved = sdp->sd_log_commited_buf + metabufhdrs_needed +
418 sdp->sd_log_commited_databuf + databufhdrs_needed +
419 revokes;
420 /* One for the overall header */
421 if (reserved)
422 reserved++;
423 return reserved;
424}
425
374static unsigned int current_tail(struct gfs2_sbd *sdp) 426static unsigned int current_tail(struct gfs2_sbd *sdp)
375{ 427{
376 struct gfs2_ail *ai; 428 struct gfs2_ail *ai;
@@ -461,14 +513,14 @@ struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp,
461 return bh; 513 return bh;
462} 514}
463 515
464static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail, int pull) 516static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail)
465{ 517{
466 unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail); 518 unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail);
467 519
468 ail2_empty(sdp, new_tail); 520 ail2_empty(sdp, new_tail);
469 521
470 gfs2_log_lock(sdp); 522 gfs2_log_lock(sdp);
471 sdp->sd_log_blks_free += dist - (pull ? 1 : 0); 523 sdp->sd_log_blks_free += dist;
472 gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks); 524 gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks);
473 gfs2_log_unlock(sdp); 525 gfs2_log_unlock(sdp);
474 526
@@ -518,7 +570,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull)
518 brelse(bh); 570 brelse(bh);
519 571
520 if (sdp->sd_log_tail != tail) 572 if (sdp->sd_log_tail != tail)
521 log_pull_tail(sdp, tail, pull); 573 log_pull_tail(sdp, tail);
522 else 574 else
523 gfs2_assert_withdraw(sdp, !pull); 575 gfs2_assert_withdraw(sdp, !pull);
524 576
@@ -579,7 +631,10 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
579 INIT_LIST_HEAD(&ai->ai_ail1_list); 631 INIT_LIST_HEAD(&ai->ai_ail1_list);
580 INIT_LIST_HEAD(&ai->ai_ail2_list); 632 INIT_LIST_HEAD(&ai->ai_ail2_list);
581 633
582 gfs2_assert_withdraw(sdp, sdp->sd_log_num_buf + sdp->sd_log_num_jdata == sdp->sd_log_commited_buf); 634 gfs2_assert_withdraw(sdp,
635 sdp->sd_log_num_buf + sdp->sd_log_num_jdata ==
636 sdp->sd_log_commited_buf +
637 sdp->sd_log_commited_databuf);
583 gfs2_assert_withdraw(sdp, 638 gfs2_assert_withdraw(sdp,
584 sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); 639 sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke);
585 640
@@ -590,16 +645,19 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
590 lops_before_commit(sdp); 645 lops_before_commit(sdp);
591 if (!list_empty(&sdp->sd_log_flush_list)) 646 if (!list_empty(&sdp->sd_log_flush_list))
592 log_flush_commit(sdp); 647 log_flush_commit(sdp);
593 else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle) 648 else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){
649 gfs2_log_lock(sdp);
650 sdp->sd_log_blks_free--; /* Adjust for unreserved buffer */
651 gfs2_log_unlock(sdp);
594 log_write_header(sdp, 0, PULL); 652 log_write_header(sdp, 0, PULL);
653 }
595 lops_after_commit(sdp, ai); 654 lops_after_commit(sdp, ai);
596 655
597 gfs2_log_lock(sdp); 656 gfs2_log_lock(sdp);
598 sdp->sd_log_head = sdp->sd_log_flush_head; 657 sdp->sd_log_head = sdp->sd_log_flush_head;
599 sdp->sd_log_blks_free -= sdp->sd_log_num_hdrs;
600 sdp->sd_log_blks_reserved = 0; 658 sdp->sd_log_blks_reserved = 0;
601 sdp->sd_log_commited_buf = 0; 659 sdp->sd_log_commited_buf = 0;
602 sdp->sd_log_num_hdrs = 0; 660 sdp->sd_log_commited_databuf = 0;
603 sdp->sd_log_commited_revoke = 0; 661 sdp->sd_log_commited_revoke = 0;
604 662
605 if (!list_empty(&ai->ai_ail1_list)) { 663 if (!list_empty(&ai->ai_ail1_list)) {
@@ -616,32 +674,26 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
616 674
617static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) 675static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
618{ 676{
619 unsigned int reserved = 0; 677 unsigned int reserved;
620 unsigned int old; 678 unsigned int old;
621 679
622 gfs2_log_lock(sdp); 680 gfs2_log_lock(sdp);
623 681
624 sdp->sd_log_commited_buf += tr->tr_num_buf_new - tr->tr_num_buf_rm; 682 sdp->sd_log_commited_buf += tr->tr_num_buf_new - tr->tr_num_buf_rm;
625 gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_buf) >= 0); 683 sdp->sd_log_commited_databuf += tr->tr_num_databuf_new -
684 tr->tr_num_databuf_rm;
685 gfs2_assert_withdraw(sdp, (((int)sdp->sd_log_commited_buf) >= 0) ||
686 (((int)sdp->sd_log_commited_databuf) >= 0));
626 sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; 687 sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm;
627 gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0); 688 gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0);
628 689 reserved = calc_reserved(sdp);
629 if (sdp->sd_log_commited_buf)
630 reserved += sdp->sd_log_commited_buf;
631 if (sdp->sd_log_commited_revoke)
632 reserved += gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke,
633 sizeof(u64));
634 if (reserved)
635 reserved++;
636
637 old = sdp->sd_log_blks_free; 690 old = sdp->sd_log_blks_free;
638 sdp->sd_log_blks_free += tr->tr_reserved - 691 sdp->sd_log_blks_free += tr->tr_reserved -
639 (reserved - sdp->sd_log_blks_reserved); 692 (reserved - sdp->sd_log_blks_reserved);
640 693
641 gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old); 694 gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old);
642 gfs2_assert_withdraw(sdp, 695 gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <=
643 sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks + 696 sdp->sd_jdesc->jd_blocks);
644 sdp->sd_log_num_hdrs);
645 697
646 sdp->sd_log_blks_reserved = reserved; 698 sdp->sd_log_blks_reserved = reserved;
647 699
@@ -687,13 +739,13 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp)
687 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); 739 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke);
688 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg); 740 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg);
689 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf); 741 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf);
690 gfs2_assert_withdraw(sdp, !sdp->sd_log_num_hdrs);
691 gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list)); 742 gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list));
692 743
693 sdp->sd_log_flush_head = sdp->sd_log_head; 744 sdp->sd_log_flush_head = sdp->sd_log_head;
694 sdp->sd_log_flush_wrapped = 0; 745 sdp->sd_log_flush_wrapped = 0;
695 746
696 log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, 0); 747 log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT,
748 (sdp->sd_log_tail == current_tail(sdp)) ? 0 : PULL);
697 749
698 gfs2_assert_warn(sdp, sdp->sd_log_blks_free == sdp->sd_jdesc->jd_blocks); 750 gfs2_assert_warn(sdp, sdp->sd_log_blks_free == sdp->sd_jdesc->jd_blocks);
699 gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); 751 gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail);