summaryrefslogtreecommitdiffstats
path: root/fs/gfs2/util.c
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2019-02-18 08:37:25 -0700
committerBob Peterson <rpeterso@redhat.com>2020-02-10 07:39:51 -0600
commit0d91061a372671aec1af729686ad9241a59fc328 (patch)
tree1d380e5c0a7c428fdf16b5f6f184c780f3f2df5e /fs/gfs2/util.c
parent03678a99d13831b938fdc9d81b5a7608fc6ef416 (diff)
downloadlinux-0d91061a372671aec1af729686ad9241a59fc328.tar.gz
linux-0d91061a372671aec1af729686ad9241a59fc328.tar.bz2
linux-0d91061a372671aec1af729686ad9241a59fc328.zip
gfs2: move check_journal_clean to util.c for future use
Before this patch function check_journal_clean was in ops_fstype.c. This patch moves it to util.c so we can make use of it elsewhere in a future patch. Signed-off-by: Bob Peterson <rpeterso@redhat.com> Reviewed-by: Andreas Gruenbacher <agruenba@redhat.com>
Diffstat (limited to 'fs/gfs2/util.c')
-rw-r--r--fs/gfs2/util.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
index 47cd40de08b1..86965e6089c6 100644
--- a/fs/gfs2/util.c
+++ b/fs/gfs2/util.c
@@ -16,7 +16,10 @@
#include "gfs2.h"
#include "incore.h"
#include "glock.h"
+#include "lops.h"
+#include "recovery.h"
#include "rgrp.h"
+#include "super.h"
#include "util.h"
struct kmem_cache *gfs2_glock_cachep __read_mostly;
@@ -33,6 +36,48 @@ void gfs2_assert_i(struct gfs2_sbd *sdp)
fs_emerg(sdp, "fatal assertion failed\n");
}
+/**
+ * check_journal_clean - Make sure a journal is clean for a spectator mount
+ * @sdp: The GFS2 superblock
+ * @jd: The journal descriptor
+ *
+ * Returns: 0 if the journal is clean or locked, else an error
+ */
+int check_journal_clean(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd)
+{
+ int error;
+ struct gfs2_holder j_gh;
+ struct gfs2_log_header_host head;
+ struct gfs2_inode *ip;
+
+ ip = GFS2_I(jd->jd_inode);
+ error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_NOEXP |
+ GL_EXACT | GL_NOCACHE, &j_gh);
+ if (error) {
+ fs_err(sdp, "Error locking journal for spectator mount.\n");
+ return -EPERM;
+ }
+ error = gfs2_jdesc_check(jd);
+ if (error) {
+ fs_err(sdp, "Error checking journal for spectator mount.\n");
+ goto out_unlock;
+ }
+ error = gfs2_find_jhead(jd, &head, false);
+ if (error) {
+ fs_err(sdp, "Error parsing journal for spectator mount.\n");
+ goto out_unlock;
+ }
+ if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) {
+ error = -EPERM;
+ fs_err(sdp, "jid=%u: Journal is dirty, so the first mounter "
+ "must not be a spectator.\n", jd->jd_jid);
+ }
+
+out_unlock:
+ gfs2_glock_dq_uninit(&j_gh);
+ return error;
+}
+
void gfs2_lm(struct gfs2_sbd *sdp, const char *fmt, ...)
{
struct va_format vaf;