diff options
author | Mark Brown <broonie@kernel.org> | 2020-10-06 16:19:24 +0100 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2020-10-06 16:19:24 +0100 |
commit | fd6b519a30a7179026d22c98d6bf10bb5ca8ca27 (patch) | |
tree | e4a6bc4d8548a5b8db7148a18eb257b84e72d48b /fs/gfs2/log.c | |
parent | 43499134f50a77844f0503df2c995f43b858f4c3 (diff) | |
parent | 856deb866d16e29bd65952e0289066f6078af773 (diff) | |
download | linux-stable-fd6b519a30a7179026d22c98d6bf10bb5ca8ca27.tar.gz linux-stable-fd6b519a30a7179026d22c98d6bf10bb5ca8ca27.tar.bz2 linux-stable-fd6b519a30a7179026d22c98d6bf10bb5ca8ca27.zip |
Merge tag 'v5.9-rc5' into asoc-5.10
Linux 5.9-rc5
Diffstat (limited to 'fs/gfs2/log.c')
-rw-r--r-- | fs/gfs2/log.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index a58333e3980d..3763c9ff1406 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c @@ -902,6 +902,36 @@ static void empty_ail1_list(struct gfs2_sbd *sdp) } /** + * drain_bd - drain the buf and databuf queue for a failed transaction + * @tr: the transaction to drain + * + * When this is called, we're taking an error exit for a log write that failed + * but since we bypassed the after_commit functions, we need to remove the + * items from the buf and databuf queue. + */ +static void trans_drain(struct gfs2_trans *tr) +{ + struct gfs2_bufdata *bd; + struct list_head *head; + + if (!tr) + return; + + head = &tr->tr_buf; + while (!list_empty(head)) { + bd = list_first_entry(head, struct gfs2_bufdata, bd_list); + list_del_init(&bd->bd_list); + kmem_cache_free(gfs2_bufdata_cachep, bd); + } + head = &tr->tr_databuf; + while (!list_empty(head)) { + bd = list_first_entry(head, struct gfs2_bufdata, bd_list); + list_del_init(&bd->bd_list); + kmem_cache_free(gfs2_bufdata_cachep, bd); + } +} + +/** * gfs2_log_flush - flush incore transaction(s) * @sdp: the filesystem * @gl: The glock structure to flush. If NULL, flush the whole incore log @@ -1005,6 +1035,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags) out: if (gfs2_withdrawn(sdp)) { + trans_drain(tr); /** * If the tr_list is empty, we're withdrawing during a log * flush that targets a transaction, but the transaction was |