gfs2: Add common helper for holding and releasing the freeze glock

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>
This commit is contained in:
Bob Peterson 2020-12-22 14:43:27 -06:00 committed by Andreas Gruenbacher
parent 7703f46f2c
commit c77b52c0a1
5 changed files with 47 additions and 37 deletions

View 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) {

View 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);

View 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);
}

View 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;

View 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__)