gfs2: Add common helper for holding and releasing the freeze glock
authorBob Peterson <rpeterso@redhat.com>
Tue, 22 Dec 2020 20:43:27 +0000 (14:43 -0600)
committerAndreas Gruenbacher <agruenba@redhat.com>
Tue, 22 Dec 2020 23:54:13 +0000 (00:54 +0100)
Many places in the gfs2 code queued and dequeued the freeze glock.
Almost all of them acquire it in SHARED mode, and need to specify the
same LM_FLAG_NOEXP and GL_EXACT flags.

This patch adds common helper functions gfs2_freeze_lock and gfs2_freeze_unlock
to make the code more readable, and to prepare for the next patch.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
fs/gfs2/ops_fstype.c
fs/gfs2/recovery.c
fs/gfs2/super.c
fs/gfs2/util.c
fs/gfs2/util.h

index 61fce59..4ee56f5 100644 (file)
@@ -1198,14 +1198,12 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
        if (sb_rdonly(sb)) {
                struct gfs2_holder freeze_gh;
 
-               error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED,
-                                          LM_FLAG_NOEXP | GL_EXACT,
-                                          &freeze_gh);
+               error = gfs2_freeze_lock(sdp, &freeze_gh, 0);
                if (error) {
                        fs_err(sdp, "can't make FS RO: %d\n", error);
                        goto fail_per_node;
                }
-               gfs2_glock_dq_uninit(&freeze_gh);
+               gfs2_freeze_unlock(&freeze_gh);
        } else {
                error = gfs2_make_fs_rw(sdp);
                if (error) {
index c26c68e..74ab1fc 100644 (file)
@@ -470,9 +470,7 @@ void gfs2_recover_func(struct work_struct *work)
 
                /* Acquire a shared hold on the freeze lock */
 
-               error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED,
-                                          LM_FLAG_NOEXP | LM_FLAG_PRIORITY |
-                                          GL_EXACT, &thaw_gh);
+               error = gfs2_freeze_lock(sdp, &thaw_gh, LM_FLAG_PRIORITY);
                if (error)
                        goto fail_gunlock_ji;
 
@@ -522,7 +520,7 @@ void gfs2_recover_func(struct work_struct *work)
                clean_journal(jd, &head);
                up_read(&sdp->sd_log_flush_lock);
 
-               gfs2_glock_dq_uninit(&thaw_gh);
+               gfs2_freeze_unlock(&thaw_gh);
                t_rep = ktime_get();
                fs_info(sdp, "jid=%u: Journal replayed in %lldms [jlck:%lldms, "
                        "jhead:%lldms, tlck:%lldms, replay:%lldms]\n",
@@ -544,7 +542,7 @@ void gfs2_recover_func(struct work_struct *work)
        goto done;
 
 fail_gunlock_thaw:
-       gfs2_glock_dq_uninit(&thaw_gh);
+       gfs2_freeze_unlock(&thaw_gh);
 fail_gunlock_ji:
        if (jlocked) {
                gfs2_glock_dq_uninit(&ji_gh);
index 2f56acc..ea312a9 100644 (file)
@@ -173,9 +173,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
        if (error)
                return error;
 
-       error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED,
-                                  LM_FLAG_NOEXP | GL_EXACT,
-                                  &freeze_gh);
+       error = gfs2_freeze_lock(sdp, &freeze_gh, 0);
        if (error)
                goto fail_threads;
 
@@ -205,12 +203,12 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
 
        set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
 
-       gfs2_glock_dq_uninit(&freeze_gh);
+       gfs2_freeze_unlock(&freeze_gh);
 
        return 0;
 
 fail:
-       gfs2_glock_dq_uninit(&freeze_gh);
+       gfs2_freeze_unlock(&freeze_gh);
 fail_threads:
        if (sdp->sd_quotad_process)
                kthread_stop(sdp->sd_quotad_process);
@@ -452,7 +450,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp)
        }
 
        if (error)
-               gfs2_glock_dq_uninit(&sdp->sd_freeze_gh);
+               gfs2_freeze_unlock(&sdp->sd_freeze_gh);
 
 out:
        while (!list_empty(&list)) {
@@ -616,21 +614,12 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
        gfs2_holder_mark_uninitialized(&freeze_gh);
        if (sdp->sd_freeze_gl &&
            !gfs2_glock_is_locked_by_me(sdp->sd_freeze_gl)) {
-               if (!log_write_allowed) {
-                       error = gfs2_glock_nq_init(sdp->sd_freeze_gl,
-                                                  LM_ST_SHARED, LM_FLAG_TRY |
-                                                  LM_FLAG_NOEXP | GL_EXACT,
-                                                  &freeze_gh);
-                       if (error == GLR_TRYFAILED)
-                               error = 0;
-               } else {
-                       error = gfs2_glock_nq_init(sdp->sd_freeze_gl,
-                                                  LM_ST_SHARED,
-                                                  LM_FLAG_NOEXP | GL_EXACT,
-                                                  &freeze_gh);
-                       if (error && !gfs2_withdrawn(sdp))
-                               return error;
-               }
+               error = gfs2_freeze_lock(sdp, &freeze_gh,
+                                        log_write_allowed ? 0 : LM_FLAG_TRY);
+               if (error == GLR_TRYFAILED)
+                       error = 0;
+               if (error && !gfs2_withdrawn(sdp))
+                       return error;
        }
 
        gfs2_flush_delete_work(sdp);
@@ -661,8 +650,7 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
                                   atomic_read(&sdp->sd_reserving_log) == 0,
                                   HZ * 5);
        }
-       if (gfs2_holder_initialized(&freeze_gh))
-               gfs2_glock_dq_uninit(&freeze_gh);
+       gfs2_freeze_unlock(&freeze_gh);
 
        gfs2_quota_cleanup(sdp);
 
@@ -772,10 +760,8 @@ void gfs2_freeze_func(struct work_struct *work)
        struct super_block *sb = sdp->sd_vfs;
 
        atomic_inc(&sb->s_active);
-       error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED,
-                                  LM_FLAG_NOEXP | GL_EXACT, &freeze_gh);
+       error = gfs2_freeze_lock(sdp, &freeze_gh, 0);
        if (error) {
-               fs_info(sdp, "GFS2: couldn't get freeze lock : %d\n", error);
                gfs2_assert_withdraw(sdp, 0);
        } else {
                atomic_set(&sdp->sd_freeze_state, SFS_UNFROZEN);
@@ -785,7 +771,7 @@ void gfs2_freeze_func(struct work_struct *work)
                                error);
                        gfs2_assert_withdraw(sdp, 0);
                }
-               gfs2_glock_dq_uninit(&freeze_gh);
+               gfs2_freeze_unlock(&freeze_gh);
        }
        deactivate_super(sb);
        clear_bit_unlock(SDF_FS_FROZEN, &sdp->sd_flags);
@@ -853,7 +839,7 @@ static int gfs2_unfreeze(struct super_block *sb)
                 return 0;
        }
 
-       gfs2_glock_dq_uninit(&sdp->sd_freeze_gh);
+       gfs2_freeze_unlock(&sdp->sd_freeze_gh);
        mutex_unlock(&sdp->sd_freeze_mutex);
        return wait_on_bit(&sdp->sd_flags, SDF_FS_FROZEN, TASK_INTERRUPTIBLE);
 }
index a374397..a115c44 100644 (file)
@@ -91,6 +91,31 @@ out_unlock:
        return error;
 }
 
+/**
+ * gfs2_freeze_lock - hold the freeze glock
+ * @sdp: the superblock
+ * @freeze_gh: pointer to the requested holder
+ * @caller_flags: any additional flags needed by the caller
+ */
+int gfs2_freeze_lock(struct gfs2_sbd *sdp, struct gfs2_holder *freeze_gh,
+                    int caller_flags)
+{
+       int flags = LM_FLAG_NOEXP | GL_EXACT | caller_flags;
+       int error;
+
+       error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED, flags,
+                                  freeze_gh);
+       if (error && error != GLR_TRYFAILED)
+               fs_err(sdp, "can't lock the freeze lock: %d\n", error);
+       return error;
+}
+
+void gfs2_freeze_unlock(struct gfs2_holder *freeze_gh)
+{
+       if (gfs2_holder_initialized(freeze_gh))
+               gfs2_glock_dq_uninit(freeze_gh);
+}
+
 static void signal_our_withdraw(struct gfs2_sbd *sdp)
 {
        struct gfs2_glock *gl = sdp->sd_live_gh.gh_gl;
index a4443dd..69e1a0a 100644 (file)
@@ -149,6 +149,9 @@ int gfs2_io_error_i(struct gfs2_sbd *sdp, const char *function,
 
 extern int check_journal_clean(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
                               bool verbose);
+extern int gfs2_freeze_lock(struct gfs2_sbd *sdp,
+                           struct gfs2_holder *freeze_gh, int caller_flags);
+extern void gfs2_freeze_unlock(struct gfs2_holder *freeze_gh);
 
 #define gfs2_io_error(sdp) \
 gfs2_io_error_i((sdp), __func__, __FILE__, __LINE__)