Skip to content

Commit 49d9be0

Browse files
Andreas Gruenbachergregkh
authored andcommitted
gfs2: add some missing log locking
[ Upstream commit fe2c8d0 ] Function gfs2_logd() calls the log flushing functions gfs2_ail1_start(), gfs2_ail1_wait(), and gfs2_ail1_empty() without holding sdp->sd_log_flush_lock, but these functions require exclusion against concurrent transactions. To fix that, add a non-locking __gfs2_log_flush() function. Then, in gfs2_logd(), take sdp->sd_log_flush_lock before calling the above mentioned log flushing functions and __gfs2_log_flush(). Fixes: 5e4c763 ("gfs2: Issue revokes more intelligently") Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 3f90bfd commit 49d9be0

1 file changed

Lines changed: 20 additions & 8 deletions

File tree

fs/gfs2/log.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,22 +1027,22 @@ static void trans_drain(struct gfs2_trans *tr)
10271027
}
10281028

10291029
/**
1030-
* gfs2_log_flush - flush incore transaction(s)
1030+
* __gfs2_log_flush - flush incore transaction(s)
10311031
* @sdp: The filesystem
10321032
* @gl: The glock structure to flush. If NULL, flush the whole incore log
10331033
* @flags: The log header flags: GFS2_LOG_HEAD_FLUSH_* and debug flags
10341034
*
10351035
*/
10361036

1037-
void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
1037+
static void __gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl,
1038+
u32 flags)
10381039
{
10391040
struct gfs2_trans *tr = NULL;
10401041
unsigned int reserved_blocks = 0, used_blocks = 0;
10411042
bool frozen = test_bit(SDF_FROZEN, &sdp->sd_flags);
10421043
unsigned int first_log_head;
10431044
unsigned int reserved_revokes = 0;
10441045

1045-
down_write(&sdp->sd_log_flush_lock);
10461046
trace_gfs2_log_flush(sdp, 1, flags);
10471047

10481048
repeat:
@@ -1154,7 +1154,6 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
11541154
gfs2_assert_withdraw_delayed(sdp, used_blocks < reserved_blocks);
11551155
gfs2_log_release(sdp, reserved_blocks - used_blocks);
11561156
}
1157-
up_write(&sdp->sd_log_flush_lock);
11581157
gfs2_trans_free(sdp, tr);
11591158
if (gfs2_withdrawing(sdp))
11601159
gfs2_withdraw(sdp);
@@ -1177,6 +1176,13 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
11771176
goto out_end;
11781177
}
11791178

1179+
void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
1180+
{
1181+
down_write(&sdp->sd_log_flush_lock);
1182+
__gfs2_log_flush(sdp, gl, flags);
1183+
up_write(&sdp->sd_log_flush_lock);
1184+
}
1185+
11801186
/**
11811187
* gfs2_merge_trans - Merge a new transaction into a cached transaction
11821188
* @sdp: the filesystem
@@ -1319,19 +1325,25 @@ int gfs2_logd(void *data)
13191325
}
13201326

13211327
if (gfs2_jrnl_flush_reqd(sdp) || t == 0) {
1328+
down_write(&sdp->sd_log_flush_lock);
13221329
gfs2_ail1_empty(sdp, 0);
1323-
gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
1324-
GFS2_LFC_LOGD_JFLUSH_REQD);
1330+
__gfs2_log_flush(sdp, NULL,
1331+
GFS2_LOG_HEAD_FLUSH_NORMAL |
1332+
GFS2_LFC_LOGD_JFLUSH_REQD);
1333+
up_write(&sdp->sd_log_flush_lock);
13251334
}
13261335

13271336
if (test_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags) ||
13281337
gfs2_ail_flush_reqd(sdp)) {
13291338
clear_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags);
1339+
down_write(&sdp->sd_log_flush_lock);
13301340
gfs2_ail1_start(sdp);
13311341
gfs2_ail1_wait(sdp);
13321342
gfs2_ail1_empty(sdp, 0);
1333-
gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
1334-
GFS2_LFC_LOGD_AIL_FLUSH_REQD);
1343+
__gfs2_log_flush(sdp, NULL,
1344+
GFS2_LOG_HEAD_FLUSH_NORMAL |
1345+
GFS2_LFC_LOGD_AIL_FLUSH_REQD);
1346+
up_write(&sdp->sd_log_flush_lock);
13351347
}
13361348

13371349
t = gfs2_tune_get(sdp, gt_logd_secs) * HZ;

0 commit comments

Comments
 (0)