diff options
author | Bob Peterson <rpeterso@redhat.com> | 2013-09-04 12:08:02 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2013-09-05 04:03:57 -0400 |
commit | 1d12d175ea3b56fdf2573bf6f168cce8f39b19e3 (patch) | |
tree | 2ab6f78a34ab951ba2a13f0c85ec637d30728c99 /fs/gfs2 | |
parent | 068213f7d3378d3e33d0f1b9415b2fdc3e9efa14 (diff) |
GFS2: Don't flag consistency error if first mounter is a spectator
This patch checks for the first mounter being a specator. If so, it
makes sure all the journals are clean. If there's a dirty journal,
the mount fails.
Testing results:
# insmod gfs2.ko
# mount -tgfs2 -o spectator /dev/sasdrives/scratch /mnt/gfs2
mount: permission denied
# dmesg | tail -2
[ 3390.655996] GFS2: fsid=MUSKETEER:home: Now mounting FS...
[ 3390.841336] GFS2: fsid=MUSKETEER:home.s: jid=0: Journal is dirty, so the first mounter must not be a spectator.
# mount -tgfs2 /dev/sasdrives/scratch /mnt/gfs2
# umount /mnt/gfs2
# mount -tgfs2 -o spectator /dev/sasdrives/scratch /mnt/gfs2
# ls /mnt/gfs2|wc -l
352
# umount /mnt/gfs2
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/ops_fstype.c | 53 |
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 | */ | ||
656 | static 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 | |||
686 | out_unlock: | ||
687 | gfs2_glock_dq_uninit(&j_gh); | ||
688 | return error; | ||
689 | } | ||
690 | |||
649 | static int init_journal(struct gfs2_sbd *sdp, int undo) | 691 | static 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); |