aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/ops_fstype.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 0262c190b6f9..19ff5e8c285c 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -646,6 +646,48 @@ static int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
646 return error; 646 return error;
647} 647}
648 648
649/**
650 * check_journal_clean - Make sure a journal is clean for a spectator mount
651 * @sdp: The GFS2 superblock
652 * @jd: The journal descriptor
653 *
654 * Returns: 0 if the journal is clean or locked, else an error
655 */
656static int check_journal_clean(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd)
657{
658 int error;
659 struct gfs2_holder j_gh;
660 struct gfs2_log_header_host head;
661 struct gfs2_inode *ip;
662
663 ip = GFS2_I(jd->jd_inode);
664 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_NOEXP |
665 GL_EXACT | GL_NOCACHE, &j_gh);
666 if (error) {
667 fs_err(sdp, "Error locking journal for spectator mount.\n");
668 return -EPERM;
669 }
670 error = gfs2_jdesc_check(jd);
671 if (error) {
672 fs_err(sdp, "Error checking journal for spectator mount.\n");
673 goto out_unlock;
674 }
675 error = gfs2_find_jhead(jd, &head);
676 if (error) {
677 fs_err(sdp, "Error parsing journal for spectator mount.\n");
678 goto out_unlock;
679 }
680 if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) {
681 error = -EPERM;
682 fs_err(sdp, "jid=%u: Journal is dirty, so the first mounter "
683 "must not be a spectator.\n", jd->jd_jid);
684 }
685
686out_unlock:
687 gfs2_glock_dq_uninit(&j_gh);
688 return error;
689}
690
649static int init_journal(struct gfs2_sbd *sdp, int undo) 691static int init_journal(struct gfs2_sbd *sdp, int undo)
650{ 692{
651 struct inode *master = sdp->sd_master_dir->d_inode; 693 struct inode *master = sdp->sd_master_dir->d_inode;
@@ -732,8 +774,15 @@ static int init_journal(struct gfs2_sbd *sdp, int undo)
732 if (sdp->sd_lockstruct.ls_first) { 774 if (sdp->sd_lockstruct.ls_first) {
733 unsigned int x; 775 unsigned int x;
734 for (x = 0; x < sdp->sd_journals; x++) { 776 for (x = 0; x < sdp->sd_journals; x++) {
735 error = gfs2_recover_journal(gfs2_jdesc_find(sdp, x), 777 struct gfs2_jdesc *jd = gfs2_jdesc_find(sdp, x);
736 true); 778
779 if (sdp->sd_args.ar_spectator) {
780 error = check_journal_clean(sdp, jd);
781 if (error)
782 goto fail_jinode_gh;
783 continue;
784 }
785 error = gfs2_recover_journal(jd, true);
737 if (error) { 786 if (error) {
738 fs_err(sdp, "error recovering journal %u: %d\n", 787 fs_err(sdp, "error recovering journal %u: %d\n",
739 x, error); 788 x, error);