aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/log.c46
-rw-r--r--fs/gfs2/log.h2
-rw-r--r--fs/gfs2/recovery.c59
3 files changed, 43 insertions, 64 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index f72c44231406..27e97d3de1e0 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -648,49 +648,67 @@ out_of_blocks:
648} 648}
649 649
650/** 650/**
651 * log_write_header - Get and initialize a journal header buffer 651 * write_log_header - Write a journal log header buffer at sd_log_flush_head
652 * @sdp: The GFS2 superblock 652 * @sdp: The GFS2 superblock
653 * @seq: sequence number
654 * @tail: tail of the log
655 * @flags: log header flags
656 * @op_flags: flags to pass to the bio
653 * 657 *
654 * Returns: the initialized log buffer descriptor 658 * Returns: the initialized log buffer descriptor
655 */ 659 */
656 660
657static void log_write_header(struct gfs2_sbd *sdp, u32 flags) 661void gfs2_write_log_header(struct gfs2_sbd *sdp, u64 seq, u32 tail,
662 u32 flags, int op_flags)
658{ 663{
659 struct gfs2_log_header *lh; 664 struct gfs2_log_header *lh;
660 unsigned int tail;
661 u32 hash; 665 u32 hash;
662 int op_flags = REQ_PREFLUSH | REQ_FUA | REQ_META | REQ_SYNC;
663 struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO); 666 struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
664 enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state); 667
665 lh = page_address(page); 668 lh = page_address(page);
666 clear_page(lh); 669 clear_page(lh);
667 670
668 gfs2_assert_withdraw(sdp, (state != SFS_FROZEN));
669
670 tail = current_tail(sdp);
671
672 lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC); 671 lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
673 lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH); 672 lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH);
674 lh->lh_header.__pad0 = cpu_to_be64(0); 673 lh->lh_header.__pad0 = cpu_to_be64(0);
675 lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH); 674 lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH);
676 lh->lh_header.mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid); 675 lh->lh_header.mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid);
677 lh->lh_sequence = cpu_to_be64(sdp->sd_log_sequence++); 676 lh->lh_sequence = cpu_to_be64(seq);
678 lh->lh_flags = cpu_to_be32(flags); 677 lh->lh_flags = cpu_to_be32(flags);
679 lh->lh_tail = cpu_to_be32(tail); 678 lh->lh_tail = cpu_to_be32(tail);
680 lh->lh_blkno = cpu_to_be32(sdp->sd_log_flush_head); 679 lh->lh_blkno = cpu_to_be32(sdp->sd_log_flush_head);
681 hash = gfs2_disk_hash(page_address(page), sizeof(struct gfs2_log_header)); 680 hash = gfs2_disk_hash(page_address(page), sizeof(struct gfs2_log_header));
682 lh->lh_hash = cpu_to_be32(hash); 681 lh->lh_hash = cpu_to_be32(hash);
683 682
683 gfs2_log_write_page(sdp, page);
684 gfs2_log_flush_bio(sdp, REQ_OP_WRITE, op_flags);
685 log_flush_wait(sdp);
686}
687
688/**
689 * log_write_header - Get and initialize a journal header buffer
690 * @sdp: The GFS2 superblock
691 *
692 * Returns: the initialized log buffer descriptor
693 */
694
695static void log_write_header(struct gfs2_sbd *sdp, u32 flags)
696{
697 unsigned int tail;
698 int op_flags = REQ_PREFLUSH | REQ_FUA | REQ_META | REQ_SYNC;
699 enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state);
700
701 gfs2_assert_withdraw(sdp, (state != SFS_FROZEN));
702 tail = current_tail(sdp);
703
684 if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) { 704 if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) {
685 gfs2_ordered_wait(sdp); 705 gfs2_ordered_wait(sdp);
686 log_flush_wait(sdp); 706 log_flush_wait(sdp);
687 op_flags = REQ_SYNC | REQ_META | REQ_PRIO; 707 op_flags = REQ_SYNC | REQ_META | REQ_PRIO;
688 } 708 }
689
690 sdp->sd_log_idle = (tail == sdp->sd_log_flush_head); 709 sdp->sd_log_idle = (tail == sdp->sd_log_flush_head);
691 gfs2_log_write_page(sdp, page); 710 gfs2_write_log_header(sdp, sdp->sd_log_sequence++, tail, flags,
692 gfs2_log_flush_bio(sdp, REQ_OP_WRITE, op_flags); 711 op_flags);
693 log_flush_wait(sdp);
694 712
695 if (sdp->sd_log_tail != tail) 713 if (sdp->sd_log_tail != tail)
696 log_pull_tail(sdp, tail); 714 log_pull_tail(sdp, tail);
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h
index 9499a6049212..619de9a1ff4f 100644
--- a/fs/gfs2/log.h
+++ b/fs/gfs2/log.h
@@ -71,6 +71,8 @@ enum gfs2_flush_type {
71 SHUTDOWN_FLUSH, 71 SHUTDOWN_FLUSH,
72 FREEZE_FLUSH 72 FREEZE_FLUSH
73}; 73};
74extern void gfs2_write_log_header(struct gfs2_sbd *sdp, u64 seq, u32 tail,
75 u32 flags, int op_flags);
74extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, 76extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl,
75 enum gfs2_flush_type type); 77 enum gfs2_flush_type type);
76extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); 78extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans);
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c
index 9395a3db1a60..5d3431219425 100644
--- a/fs/gfs2/recovery.c
+++ b/fs/gfs2/recovery.c
@@ -20,6 +20,7 @@
20#include "bmap.h" 20#include "bmap.h"
21#include "glock.h" 21#include "glock.h"
22#include "glops.h" 22#include "glops.h"
23#include "log.h"
23#include "lops.h" 24#include "lops.h"
24#include "meta_io.h" 25#include "meta_io.h"
25#include "recovery.h" 26#include "recovery.h"
@@ -370,62 +371,22 @@ static int foreach_descriptor(struct gfs2_jdesc *jd, unsigned int start,
370 371
371/** 372/**
372 * clean_journal - mark a dirty journal as being clean 373 * clean_journal - mark a dirty journal as being clean
373 * @sdp: the filesystem
374 * @jd: the journal 374 * @jd: the journal
375 * @gl: the journal's glock
376 * @head: the head journal to start from 375 * @head: the head journal to start from
377 * 376 *
378 * Returns: errno 377 * Returns: errno
379 */ 378 */
380 379
381static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head) 380static void clean_journal(struct gfs2_jdesc *jd,
381 struct gfs2_log_header_host *head)
382{ 382{
383 struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
384 struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); 383 struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
385 unsigned int lblock;
386 struct gfs2_log_header *lh;
387 u32 hash;
388 struct buffer_head *bh;
389 int error;
390 struct buffer_head bh_map = { .b_state = 0, .b_blocknr = 0 };
391
392 lblock = head->lh_blkno;
393 gfs2_replay_incr_blk(jd, &lblock);
394 bh_map.b_size = 1 << ip->i_inode.i_blkbits;
395 error = gfs2_block_map(&ip->i_inode, lblock, &bh_map, 0);
396 if (error)
397 return error;
398 if (!bh_map.b_blocknr) {
399 gfs2_consist_inode(ip);
400 return -EIO;
401 }
402
403 bh = sb_getblk(sdp->sd_vfs, bh_map.b_blocknr);
404 lock_buffer(bh);
405 memset(bh->b_data, 0, bh->b_size);
406 set_buffer_uptodate(bh);
407 clear_buffer_dirty(bh);
408 unlock_buffer(bh);
409
410 lh = (struct gfs2_log_header *)bh->b_data;
411 memset(lh, 0, sizeof(struct gfs2_log_header));
412 lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
413 lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH);
414 lh->lh_header.__pad0 = cpu_to_be64(0);
415 lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH);
416 lh->lh_header.mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid);
417 lh->lh_sequence = cpu_to_be64(head->lh_sequence + 1);
418 lh->lh_flags = cpu_to_be32(GFS2_LOG_HEAD_UNMOUNT);
419 lh->lh_blkno = cpu_to_be32(lblock);
420 hash = gfs2_disk_hash((const char *)lh, sizeof(struct gfs2_log_header));
421 lh->lh_hash = cpu_to_be32(hash);
422
423 set_buffer_dirty(bh);
424 if (sync_dirty_buffer(bh))
425 gfs2_io_error_bh(sdp, bh);
426 brelse(bh);
427 384
428 return error; 385 sdp->sd_log_flush_head = head->lh_blkno;
386 gfs2_replay_incr_blk(jd, &sdp->sd_log_flush_head);
387 gfs2_write_log_header(sdp, head->lh_sequence + 1, 0,
388 GFS2_LOG_HEAD_UNMOUNT, REQ_PREFLUSH |
389 REQ_FUA | REQ_META | REQ_SYNC);
429} 390}
430 391
431 392
@@ -552,9 +513,7 @@ void gfs2_recover_func(struct work_struct *work)
552 goto fail_gunlock_thaw; 513 goto fail_gunlock_thaw;
553 } 514 }
554 515
555 error = clean_journal(jd, &head); 516 clean_journal(jd, &head);
556 if (error)
557 goto fail_gunlock_thaw;
558 517
559 gfs2_glock_dq_uninit(&thaw_gh); 518 gfs2_glock_dq_uninit(&thaw_gh);
560 t = DIV_ROUND_UP(jiffies - t, HZ); 519 t = DIV_ROUND_UP(jiffies - t, HZ);