xfs_file_last_byte() needs to acquire ilock
We had some systems crash with this stack: [<a00000010000cb20>] ia64_leave_kernel+0x0/0x280 [<a00000021291ca00>] xfs_bmbt_get_startoff+0x0/0x20 [xfs] [<a0000002129080b0>] xfs_bmap_last_offset+0x210/0x280 [xfs] [<a00000021295b010>] xfs_file_last_byte+0x70/0x1a0 [xfs] [<a00000021295b200>] xfs_itruncate_start+0xc0/0x1a0 [xfs] [<a0000002129935f0>] xfs_inactive_free_eofblocks+0x290/0x460 [xfs] [<a000000212998fb0>] xfs_release+0x1b0/0x240 [xfs] [<a0000002129ad930>] xfs_file_release+0x70/0xa0 [xfs] [<a000000100162ea0>] __fput+0x1a0/0x420 [<a000000100163160>] fput+0x40/0x60 The problem here is that xfs_file_last_byte() does not acquire the inode lock and can therefore race with another thread that is modifying the extext list. While xfs_bmap_last_offset() is trying to lookup what was the last extent some extents were merged and the extent list shrunk so the index we lookup is now beyond the end of the extent list and potentially in a freed buffer. Signed-off-by: Lachlan McIlroy <lmcilroy@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Felix Blyakher <felixb@sgi.com> Signed-off-by: Felix Blyakher <felixb@sgi.com>
This commit is contained in:
Родитель
dc2a5536d6
Коммит
def6b3ba56
|
@ -1258,8 +1258,10 @@ xfs_file_last_byte(
|
|||
* necessary.
|
||||
*/
|
||||
if (ip->i_df.if_flags & XFS_IFEXTENTS) {
|
||||
xfs_ilock(ip, XFS_ILOCK_SHARED);
|
||||
error = xfs_bmap_last_offset(NULL, ip, &last_block,
|
||||
XFS_DATA_FORK);
|
||||
xfs_iunlock(ip, XFS_ILOCK_SHARED);
|
||||
if (error) {
|
||||
last_block = 0;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче