Skip to content

Commit 1d12d17

Browse files
AstralBobswhiteho
authored andcommitted
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>
1 parent 068213f commit 1d12d17

File tree

1 file changed

+51
-2
lines changed

1 file changed

+51
-2
lines changed

fs/gfs2/ops_fstype.c

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,48 @@ static int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
646646
return error;
647647
}
648648

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+
649691
static int init_journal(struct gfs2_sbd *sdp, int undo)
650692
{
651693
struct inode *master = sdp->sd_master_dir->d_inode;
@@ -732,8 +774,15 @@ static int init_journal(struct gfs2_sbd *sdp, int undo)
732774
if (sdp->sd_lockstruct.ls_first) {
733775
unsigned int x;
734776
for (x = 0; x < sdp->sd_journals; x++) {
735-
error = gfs2_recover_journal(gfs2_jdesc_find(sdp, x),
736-
true);
777+
struct gfs2_jdesc *jd = gfs2_jdesc_find(sdp, x);
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);
737786
if (error) {
738787
fs_err(sdp, "error recovering journal %u: %d\n",
739788
x, error);

0 commit comments

Comments
 (0)