]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.31/patches.fixes/xfs_file_last_byte-needs-to-acquire-ilock.patch
Move xen patchset to new version's subdir.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.fixes / xfs_file_last_byte-needs-to-acquire-ilock.patch
CommitLineData
00e5a55c
BS
1From: Lachlan McIlroy <lmcilroy@redhat.com>
2Date: Fri, 24 Apr 2009 02:18:00 +0000 (-0400)
3Subject: xfs_file_last_byte() needs to acquire ilock
4Patch-mainline: 2.6.30-rc5
5Git-commit: def6b3ba56b637d58126ef67fc19bab57945fcc4
6References: SGI:PV963454 bnc#487987
7
8xfs_file_last_byte() needs to acquire ilock
9
10We had some systems crash with this stack:
11
12[<a00000010000cb20>] ia64_leave_kernel+0x0/0x280
13[<a00000021291ca00>] xfs_bmbt_get_startoff+0x0/0x20 [xfs]
14[<a0000002129080b0>] xfs_bmap_last_offset+0x210/0x280 [xfs]
15[<a00000021295b010>] xfs_file_last_byte+0x70/0x1a0 [xfs]
16[<a00000021295b200>] xfs_itruncate_start+0xc0/0x1a0 [xfs]
17[<a0000002129935f0>] xfs_inactive_free_eofblocks+0x290/0x460 [xfs]
18[<a000000212998fb0>] xfs_release+0x1b0/0x240 [xfs]
19[<a0000002129ad930>] xfs_file_release+0x70/0xa0 [xfs]
20[<a000000100162ea0>] __fput+0x1a0/0x420
21[<a000000100163160>] fput+0x40/0x60
22
23The problem here is that xfs_file_last_byte() does not acquire the
24inode lock and can therefore race with another thread that is modifying
25the extext list. While xfs_bmap_last_offset() is trying to lookup
26what was the last extent some extents were merged and the extent list
27shrunk so the index we lookup is now beyond the end of the extent list
28and potentially in a freed buffer.
29
30Signed-off-by: Lachlan McIlroy <lmcilroy@redhat.com>
31Reviewed-by: Christoph Hellwig <hch@lst.de>
32Reviewed-by: Felix Blyakher <felixb@sgi.com>
33Signed-off-by: Felix Blyakher <felixb@sgi.com>
34Acked-by: Jeff Mahoney <jeffm@suse.com>
35---
36
37 fs/xfs/xfs_inode.c | 2 ++
38 1 file changed, 2 insertions(+)
39
40--- a/fs/xfs/xfs_inode.c
41+++ b/fs/xfs/xfs_inode.c
42@@ -1306,8 +1306,10 @@ xfs_file_last_byte(
43 * necessary.
44 */
45 if (ip->i_df.if_flags & XFS_IFEXTENTS) {
46+ xfs_ilock(ip, XFS_ILOCK_SHARED);
47 error = xfs_bmap_last_offset(NULL, ip, &last_block,
48 XFS_DATA_FORK);
49+ xfs_iunlock(ip, XFS_ILOCK_SHARED);
50 if (error) {
51 last_block = 0;
52 }