]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.fixes/xfs_file_last_byte-needs-to-acquire-ilock.patch
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.fixes / xfs_file_last_byte-needs-to-acquire-ilock.patch
1 From: Lachlan McIlroy <lmcilroy@redhat.com>
2 Date: Fri, 24 Apr 2009 02:18:00 +0000 (-0400)
3 Subject: xfs_file_last_byte() needs to acquire ilock
4 Patch-mainline: 2.6.30-rc5
5 Git-commit: def6b3ba56b637d58126ef67fc19bab57945fcc4
6 References: SGI:PV963454 bnc#487987
7
8 xfs_file_last_byte() needs to acquire ilock
9
10 We 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
23 The problem here is that xfs_file_last_byte() does not acquire the
24 inode lock and can therefore race with another thread that is modifying
25 the extext list. While xfs_bmap_last_offset() is trying to lookup
26 what was the last extent some extents were merged and the extent list
27 shrunk so the index we lookup is now beyond the end of the extent list
28 and potentially in a freed buffer.
29
30 Signed-off-by: Lachlan McIlroy <lmcilroy@redhat.com>
31 Reviewed-by: Christoph Hellwig <hch@lst.de>
32 Reviewed-by: Felix Blyakher <felixb@sgi.com>
33 Signed-off-by: Felix Blyakher <felixb@sgi.com>
34 Acked-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 }