Skip to content

Commit ca399c9

Browse files
committed
gfs2: flesh out delayed withdraw for gfs2_log_flush
Function gfs2_log_flush() had a few places where it tried to withdraw from the file system when errors were encountered. The problem is, it should delay those withdraws until the log flush lock is no longer held. This patch creates a new function just for delayed withdraws for situations like this. If errors=panic was specified on mount, we still want to do it the old fashioned way because the panic it does not help to delay in that situation. Signed-off-by: Bob Peterson <[email protected]> Reviewed-by: Andreas Gruenbacher <[email protected]>
1 parent 1c634f9 commit ca399c9

File tree

3 files changed

+41
-12
lines changed

3 files changed

+41
-12
lines changed

fs/gfs2/log.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -872,13 +872,17 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
872872
INIT_LIST_HEAD(&tr->tr_ail2_list);
873873
tr->tr_first = sdp->sd_log_flush_head;
874874
if (unlikely (state == SFS_FROZEN))
875-
gfs2_assert_withdraw(sdp, !tr->tr_num_buf_new && !tr->tr_num_databuf_new);
875+
if (gfs2_assert_withdraw_delayed(sdp,
876+
!tr->tr_num_buf_new && !tr->tr_num_databuf_new))
877+
goto out;
876878
}
877879

878880
if (unlikely(state == SFS_FROZEN))
879-
gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke);
880-
gfs2_assert_withdraw(sdp,
881-
sdp->sd_log_num_revoke == sdp->sd_log_committed_revoke);
881+
if (gfs2_assert_withdraw_delayed(sdp, !sdp->sd_log_num_revoke))
882+
goto out;
883+
if (gfs2_assert_withdraw_delayed(sdp,
884+
sdp->sd_log_num_revoke == sdp->sd_log_committed_revoke))
885+
goto out;
882886

883887
gfs2_ordered_write(sdp);
884888
if (gfs2_withdrawn(sdp))

fs/gfs2/util.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,13 +318,28 @@ int gfs2_withdraw(struct gfs2_sbd *sdp)
318318
*/
319319

320320
void gfs2_assert_withdraw_i(struct gfs2_sbd *sdp, char *assertion,
321-
const char *function, char *file, unsigned int line)
321+
const char *function, char *file, unsigned int line,
322+
bool delayed)
322323
{
323-
gfs2_lm(sdp,
324-
"fatal: assertion \"%s\" failed\n"
325-
" function = %s, file = %s, line = %u\n",
326-
assertion, function, file, line);
327-
gfs2_withdraw(sdp);
324+
if (gfs2_withdrawn(sdp))
325+
return;
326+
327+
fs_err(sdp,
328+
"fatal: assertion \"%s\" failed\n"
329+
" function = %s, file = %s, line = %u\n",
330+
assertion, function, file, line);
331+
332+
/*
333+
* If errors=panic was specified on mount, it won't help to delay the
334+
* withdraw.
335+
*/
336+
if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC)
337+
delayed = false;
338+
339+
if (delayed)
340+
gfs2_withdraw_delayed(sdp);
341+
else
342+
gfs2_withdraw(sdp);
328343
dump_stack();
329344
}
330345

fs/gfs2/util.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,24 @@ do { \
3737

3838

3939
void gfs2_assert_withdraw_i(struct gfs2_sbd *sdp, char *assertion,
40-
const char *function, char *file, unsigned int line);
40+
const char *function, char *file, unsigned int line,
41+
bool delayed);
4142

4243
#define gfs2_assert_withdraw(sdp, assertion) \
4344
({ \
4445
bool _bool = (assertion); \
4546
if (unlikely(!_bool)) \
4647
gfs2_assert_withdraw_i((sdp), #assertion, \
47-
__func__, __FILE__, __LINE__); \
48+
__func__, __FILE__, __LINE__, false); \
49+
!_bool; \
50+
})
51+
52+
#define gfs2_assert_withdraw_delayed(sdp, assertion) \
53+
({ \
54+
bool _bool = (assertion); \
55+
if (unlikely(!_bool)) \
56+
gfs2_assert_withdraw_i((sdp), #assertion, \
57+
__func__, __FILE__, __LINE__, true); \
4858
!_bool; \
4959
})
5060

0 commit comments

Comments
 (0)