Skip to content

Commit fe2c8d0

Browse files
author
Andreas Gruenbacher
committed
gfs2: add some missing log locking
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>
1 parent f4e4c4e commit fe2c8d0

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
@@ -1053,22 +1053,22 @@ void gfs2_remove_from_journal(struct buffer_head *bh, int meta)
10531053
}
10541054

10551055
/**
1056-
* gfs2_log_flush - flush incore transaction(s)
1056+
* __gfs2_log_flush - flush incore transaction(s)
10571057
* @sdp: The filesystem
10581058
* @gl: The glock structure to flush. If NULL, flush the whole incore log
10591059
* @flags: The log header flags: GFS2_LOG_HEAD_FLUSH_* and debug flags
10601060
*
10611061
*/
10621062

1063-
void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
1063+
static void __gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl,
1064+
u32 flags)
10641065
{
10651066
struct gfs2_trans *tr = NULL;
10661067
unsigned int reserved_blocks = 0, used_blocks = 0;
10671068
bool frozen = test_bit(SDF_FROZEN, &sdp->sd_flags);
10681069
unsigned int first_log_head;
10691070
unsigned int reserved_revokes = 0;
10701071

1071-
down_write(&sdp->sd_log_flush_lock);
10721072
trace_gfs2_log_flush(sdp, 1, flags);
10731073

10741074
repeat:
@@ -1180,7 +1180,6 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
11801180
gfs2_assert_withdraw(sdp, used_blocks < reserved_blocks);
11811181
gfs2_log_release(sdp, reserved_blocks - used_blocks);
11821182
}
1183-
up_write(&sdp->sd_log_flush_lock);
11841183
gfs2_trans_free(sdp, tr);
11851184
trace_gfs2_log_flush(sdp, 0, flags);
11861185
return;
@@ -1201,6 +1200,13 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
12011200
goto out_end;
12021201
}
12031202

1203+
void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
1204+
{
1205+
down_write(&sdp->sd_log_flush_lock);
1206+
__gfs2_log_flush(sdp, gl, flags);
1207+
up_write(&sdp->sd_log_flush_lock);
1208+
}
1209+
12041210
/**
12051211
* gfs2_merge_trans - Merge a new transaction into a cached transaction
12061212
* @sdp: the filesystem
@@ -1332,19 +1338,25 @@ int gfs2_logd(void *data)
13321338
break;
13331339

13341340
if (gfs2_jrnl_flush_reqd(sdp) || t == 0) {
1341+
down_write(&sdp->sd_log_flush_lock);
13351342
gfs2_ail1_empty(sdp, 0);
1336-
gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
1337-
GFS2_LFC_LOGD_JFLUSH_REQD);
1343+
__gfs2_log_flush(sdp, NULL,
1344+
GFS2_LOG_HEAD_FLUSH_NORMAL |
1345+
GFS2_LFC_LOGD_JFLUSH_REQD);
1346+
up_write(&sdp->sd_log_flush_lock);
13381347
}
13391348

13401349
if (test_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags) ||
13411350
gfs2_ail_flush_reqd(sdp)) {
13421351
clear_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags);
1352+
down_write(&sdp->sd_log_flush_lock);
13431353
gfs2_ail1_start(sdp);
13441354
gfs2_ail1_wait(sdp);
13451355
gfs2_ail1_empty(sdp, 0);
1346-
gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL |
1347-
GFS2_LFC_LOGD_AIL_FLUSH_REQD);
1356+
__gfs2_log_flush(sdp, NULL,
1357+
GFS2_LOG_HEAD_FLUSH_NORMAL |
1358+
GFS2_LFC_LOGD_AIL_FLUSH_REQD);
1359+
up_write(&sdp->sd_log_flush_lock);
13481360
}
13491361

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

0 commit comments

Comments
 (0)