Skip to content

Commit c230a4a

Browse files
dgchinnerdchinner
authored andcommitted
xfs: fix potential log item leak
Ever since we added shadown format buffers to the log items, log items need to handle the item being released with shadow buffers attached. Due to the fact this requirement was added at the same time we added new rmap/reflink intents, we missed the cleanup of those items. In theory, this means shadow buffers can be leaked in a very small window when a shutdown is initiated. Testing with KASAN shows this leak does not happen in practice - we haven't identified a single leak in several years of shutdown testing since ~v4.8 kernels. However, the intent whiteout cleanup mechanism results in every cancelled intent in exactly the same state as this tiny race window creates and so if intents down clean up shadow buffers on final release we will leak the shadow buffer for just about every intent we create. Hence we start with this patch to close this condition off and ensure that when whiteouts start to be used we don't leak lots of memory. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Allison Henderson <allison.henderson@oracle.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
1 parent cb512c9 commit c230a4a

4 files changed

Lines changed: 7 additions & 0 deletions

File tree

fs/xfs/xfs_bmap_item.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ STATIC void
3939
xfs_bui_item_free(
4040
struct xfs_bui_log_item *buip)
4141
{
42+
kmem_free(buip->bui_item.li_lv_shadow);
4243
kmem_cache_free(xfs_bui_cache, buip);
4344
}
4445

@@ -198,6 +199,7 @@ xfs_bud_item_release(
198199
struct xfs_bud_log_item *budp = BUD_ITEM(lip);
199200

200201
xfs_bui_release(budp->bud_buip);
202+
kmem_free(budp->bud_item.li_lv_shadow);
201203
kmem_cache_free(xfs_bud_cache, budp);
202204
}
203205

fs/xfs/xfs_icreate_item.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ STATIC void
6363
xfs_icreate_item_release(
6464
struct xfs_log_item *lip)
6565
{
66+
kmem_free(ICR_ITEM(lip)->ic_item.li_lv_shadow);
6667
kmem_cache_free(xfs_icreate_cache, ICR_ITEM(lip));
6768
}
6869

fs/xfs/xfs_refcount_item.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ STATIC void
3535
xfs_cui_item_free(
3636
struct xfs_cui_log_item *cuip)
3737
{
38+
kmem_free(cuip->cui_item.li_lv_shadow);
3839
if (cuip->cui_format.cui_nextents > XFS_CUI_MAX_FAST_EXTENTS)
3940
kmem_free(cuip);
4041
else
@@ -204,6 +205,7 @@ xfs_cud_item_release(
204205
struct xfs_cud_log_item *cudp = CUD_ITEM(lip);
205206

206207
xfs_cui_release(cudp->cud_cuip);
208+
kmem_free(cudp->cud_item.li_lv_shadow);
207209
kmem_cache_free(xfs_cud_cache, cudp);
208210
}
209211

fs/xfs/xfs_rmap_item.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ STATIC void
3535
xfs_rui_item_free(
3636
struct xfs_rui_log_item *ruip)
3737
{
38+
kmem_free(ruip->rui_item.li_lv_shadow);
3839
if (ruip->rui_format.rui_nextents > XFS_RUI_MAX_FAST_EXTENTS)
3940
kmem_free(ruip);
4041
else
@@ -227,6 +228,7 @@ xfs_rud_item_release(
227228
struct xfs_rud_log_item *rudp = RUD_ITEM(lip);
228229

229230
xfs_rui_release(rudp->rud_ruip);
231+
kmem_free(rudp->rud_item.li_lv_shadow);
230232
kmem_cache_free(xfs_rud_cache, rudp);
231233
}
232234

0 commit comments

Comments
 (0)