diff options
author | Bob Peterson <rpeterso@redhat.com> | 2020-02-17 14:14:13 -0600 |
---|---|---|
committer | Bob Peterson <rpeterso@redhat.com> | 2020-02-27 07:53:18 -0600 |
commit | 019dd669bde14bc0748bc43af2f96e2c5e37d3f8 (patch) | |
tree | 1dbcf3a5bb0d50fd9f5bdf3f6465ddea2f733779 /fs/gfs2/aops.c | |
parent | ca399c96e96e3f372f901a698a6fd17796b8ed32 (diff) | |
download | linux-019dd669bde14bc0748bc43af2f96e2c5e37d3f8.tar.bz2 |
gfs2: don't allow releasepage to free bd still used for revokes
Before this patch, function gfs2_releasepage would free any bd
elements that had been used for the page being released. However,
those bd elements may still be queued to the sd_log_revokes list,
in which case we cannot free them until the revoke has been issued.
This patch adds additional checks for bds that are still being
used for revokes.
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Diffstat (limited to 'fs/gfs2/aops.c')
-rw-r--r-- | fs/gfs2/aops.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index ba83b49ce18c..786c1ce8f030 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -805,11 +805,16 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) bd = bh->b_private; if (bd) { gfs2_assert_warn(sdp, bd->bd_bh == bh); - if (!list_empty(&bd->bd_list)) - list_del_init(&bd->bd_list); bd->bd_bh = NULL; bh->b_private = NULL; - kmem_cache_free(gfs2_bufdata_cachep, bd); + /* + * The bd may still be queued as a revoke, in which + * case we must not dequeue nor free it. + */ + if (!bd->bd_blkno && !list_empty(&bd->bd_list)) + list_del_init(&bd->bd_list); + if (list_empty(&bd->bd_list)) + kmem_cache_free(gfs2_bufdata_cachep, bd); } bh = bh->b_this_page; |