xfs: remove filestream item xfs_inode reference
authorChristoph Hellwig <hch@lst.de>
Mon, 9 Apr 2018 17:23:39 +0000 (10:23 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Mon, 9 Apr 2018 17:23:39 +0000 (10:23 -0700)
commit7fcd3efa1e9ebebf71f9c65f6c0a8ce993122424
treee4dfef92b192690508139570f1388e9695570f6a
parent0612d1166330697d91b8d2d1e71e41485bb0b18e
xfs: remove filestream item xfs_inode reference

The filestreams allocator stores an xfs_fstrm_item structure in the MRU to
cache inode number to agno mappings for a particular length of time.  Each
xfs_fstrm_item contains the internal MRU structure, an inode pointer and
agno value.

The inode pointer stored in the xfs_fstrm_item is not referenced, however,
which means the inode itself can be removed and reclaimed before the MRU
item is freed. If this occurs, xfs_fstrm_free_func() can access freed or
unrelated memory through xfs_fstrm_item->ip and crash.

The obvious solution is to grab an inode reference for xfs_fstrm_item.
The filestream mechanism only actually uses the inode pointer as a means
to access the xfs_mount, however.  Rather than add unnecessary
complexity, simplify the implementation to store an xfs_mount pointer in
struct xfs_mru_cache, and pass it to the free callback.  This also
requires updates to the tracepoint class to provide the associated data
via parameters rather than the inode and a minor hack to peek at the MRU
key to establish the inode number at free time.

Based on debugging work and an earlier patch from Brian Foster, who
also wrote most of this changelog.

Reported-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
fs/xfs/xfs_filestream.c
fs/xfs/xfs_mru_cache.c
fs/xfs/xfs_mru_cache.h
fs/xfs/xfs_trace.h