On Wed, Jul 06, 2022 at 04:22:37PM +0800, Jianglei Nie wrote: > xfs_bmap_add_attrfork() allocates a memory chunk for ip->i_afp with > xfs_ifork_alloc(). When some error occurs, the function goto trans_cancel; > without releasing the ip->i_afp, which will lead to a memory leak. > > We should release the ip->i_afp with kmem_cache_free() and set "ip->i_afp > = NULL" if ip->i_afp is not NULL pointer. > > Signed-off-by: Jianglei Nie <niejianglei2021@xxxxxxx> > --- > fs/xfs/libxfs/xfs_bmap.c | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > index 6833110d1bd4..0c99726c0968 100644 > --- a/fs/xfs/libxfs/xfs_bmap.c > +++ b/fs/xfs/libxfs/xfs_bmap.c > @@ -1088,6 +1088,10 @@ xfs_bmap_add_attrfork( > trans_cancel: > xfs_trans_cancel(tp); > xfs_iunlock(ip, XFS_ILOCK_EXCL); > + if (ip->i_afp) { > + kmem_cache_free(xfs_ifork_cache, ip->i_afp); > + ip->a_afp = NULL; > + } I don't think this is correct. If xfs_bmap_add_attrfork_* fail without dirtying the transaction, this function cancels the transaction without shutting down the filesystem, and return the error code to the caller. However, i_forkoff is not reset to zero, which means that the inode still has an attr fork, so i_afp must not be freed. Freeing the memory and nulling out the pointer without resetting i_forkoff results in inconsistent incore state, which will probably lead to a crash somewhere. In the end, inode reclaim will free i_afp. I think this is mooted by[1], right? --D [1] https://lore.kernel.org/linux-xfs/165705898555.2826746.14913566803667615290.stgit@magnolia/T/#u > return error; > } > > -- > 2.25.1 >