linux-stable/fs/xfs
Jie Liu 58e59854a3 xfs: fix assertion failure in xfs_vm_write_failed()
In xfs_vm_write_failed(), we evaluate the block_offset of pos with
PAGE_MASK which is an unsigned long.  That is fine on 64-bit platforms
regardless of whether the request pos is 32-bit or 64-bit.  However, on
32-bit platforms the value is 0xfffff000 and so the high 32 bits in it
will be masked off with (pos & PAGE_MASK) for a 64-bit pos.

As a result, the evaluated block_offset is incorrect which will cause
this failure ASSERT(block_offset + from == pos); and potentially pass
the wrong block to xfs_vm_kill_delalloc_range().

In this case, we can get a kernel panic if CONFIG_XFS_DEBUG is enabled:

XFS: Assertion failed: block_offset + from == pos, file: fs/xfs/xfs_aops.c, line: 1504

------------[ cut here ]------------
 kernel BUG at fs/xfs/xfs_message.c:100!
 invalid opcode: 0000 [#1] SMP
 ........
 Pid: 4057, comm: mkfs.xfs Tainted: G           O 3.9.0-rc2 #1
 EIP: 0060:[<f94a7e8b>] EFLAGS: 00010282 CPU: 0
 EIP is at assfail+0x2b/0x30 [xfs]
 EAX: 00000056 EBX: f6ef28a0 ECX: 00000007 EDX: f57d22a4
 ESI: 1c2fb000 EDI: 00000000 EBP: ea6b5d30 ESP: ea6b5d1c
 DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
 CR0: 8005003b CR2: 094f3ff4 CR3: 2bcb4000 CR4: 000006f0
 DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
 DR6: ffff0ff0 DR7: 00000400
 Process mkfs.xfs (pid: 4057, ti=ea6b4000 task=ea5799e0 task.ti=ea6b4000)
 Stack:
 00000000 f9525c48 f951fa80 f951f96b 000005e4 ea6b5d7c f9494b34 c19b0ea2
 00000066 f3d6c620 c19b0ea2 00000000 e9a91458 00001000 00000000 00000000
 00000000 c15c7e89 00000000 1c2fb000 00000000 00000000 1c2fb000 00000080
 Call Trace:
 [<f9494b34>] xfs_vm_write_failed+0x74/0x1b0 [xfs]
 [<c15c7e89>] ? printk+0x4d/0x4f
 [<f9494d7d>] xfs_vm_write_begin+0x10d/0x170 [xfs]
 [<c110a34c>] generic_file_buffered_write+0xdc/0x210
 [<f949b669>] xfs_file_buffered_aio_write+0xf9/0x190 [xfs]
 [<f949b7f3>] xfs_file_aio_write+0xf3/0x160 [xfs]
 [<c115e504>] do_sync_write+0x94/0xd0
 [<c115ed1f>] vfs_write+0x8f/0x160
 [<c115e470>] ? wait_on_retry_sync_kiocb+0x50/0x50
 [<c115f017>] sys_write+0x47/0x80
 [<c15d860d>] sysenter_do_call+0x12/0x28
 .............
 EIP: [<f94a7e8b>] assfail+0x2b/0x30 [xfs] SS:ESP 0068:ea6b5d1c
 ---[ end trace cdd9af4f4ecab42f ]---
 Kernel panic - not syncing: Fatal exception

In order to avoid this, we can evaluate the block_offset of the start
of the page by using shifts rather than masks the mismatch problem.

Thanks Dave Chinner for help finding and fixing this bug.

Reported-by: Michael L. Semon <mlsemon35@gmail.com>
Reviewed-by: Dave Chinner <david@fromorbit.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Jie Liu <jeff.liu@oracle.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
2013-07-22 13:12:19 -05:00
..
Kconfig xfs: introduce CONFIG_XFS_WARN 2013-05-07 18:45:36 -05:00
kmem.c xfs: switch to proper __bitwise type for KM_... flags 2012-05-29 23:28:32 -04:00
kmem.h xfs: switch to proper __bitwise type for KM_... flags 2012-05-29 23:28:32 -04:00
Makefile xfs: Inode create log items 2013-06-27 13:34:12 -05:00
mrlock.h xfs: introduce CONFIG_XFS_WARN 2013-05-07 18:45:36 -05:00
time.h
uuid.c
uuid.h xfs: add CRC infrastructure 2012-11-19 20:11:24 -06:00
xfs.h xfs: introduce CONFIG_XFS_WARN 2013-05-07 18:45:36 -05:00
xfs_acl.c xfs: increase number of ACL entries for V5 superblocks 2013-06-06 10:52:15 -05:00
xfs_acl.h xfs: increase number of ACL entries for V5 superblocks 2013-06-06 10:52:15 -05:00
xfs_ag.h xfs: add CRC checks to the AGI 2013-04-21 14:57:43 -05:00
xfs_alloc.c xfs: Avoid pathological backwards allocation 2013-05-20 13:09:11 -05:00
xfs_alloc.h xfs: convert buffer verifiers to an ops structure. 2012-11-15 21:35:12 -06:00
xfs_alloc_btree.c xfs: introduce CONFIG_XFS_WARN 2013-05-07 18:45:36 -05:00
xfs_alloc_btree.h xfs: add support for large btree blocks 2013-04-21 14:53:46 -05:00
xfs_aops.c xfs: fix assertion failure in xfs_vm_write_failed() 2013-07-22 13:12:19 -05:00
xfs_aops.h Prefix IO_XX flags with XFS_IO_XX to avoid namespace colision. 2012-07-22 11:00:55 -05:00
xfs_attr.c xfs: split remote attribute code out 2013-04-27 12:49:32 -05:00
xfs_attr.h xfs: split remote attribute code out 2013-04-27 12:49:32 -05:00
xfs_attr_leaf.c xfs: remove local fork format handling from xfs_bmapi_write() 2013-07-09 16:40:22 -05:00
xfs_attr_leaf.h xfs: fix implicit padding in directory and attr CRC formats 2013-06-14 15:59:16 -05:00
xfs_attr_remote.c xfs: rework remote attr CRCs 2013-05-30 17:26:31 -05:00
xfs_attr_remote.h xfs: rework remote attr CRCs 2013-05-30 17:26:31 -05:00
xfs_attr_sf.h
xfs_bit.c
xfs_bit.h
xfs_bmap.c xfs: remove local fork format handling from xfs_bmapi_write() 2013-07-09 16:40:22 -05:00
xfs_bmap.h xfs: remove local fork format handling from xfs_bmapi_write() 2013-07-09 16:40:22 -05:00
xfs_bmap_btree.c xfs: introduce CONFIG_XFS_WARN 2013-05-07 18:45:36 -05:00
xfs_bmap_btree.h xfs: check on-disk (not incore) btree root size in dfrag.c 2013-06-20 13:26:09 -05:00
xfs_btree.c xfs: ensure btree root split sets blkno correctly 2013-06-14 15:59:31 -05:00
xfs_btree.h xfs: introduce CONFIG_XFS_WARN 2013-05-07 18:45:36 -05:00
xfs_buf.c xfs: rework remote attr CRCs 2013-05-30 17:26:31 -05:00
xfs_buf.h xfs: use b_maps[] for discontiguous buffers 2013-01-16 16:07:11 -06:00
xfs_buf_item.c xfs: Use inode create transaction 2013-06-27 14:27:18 -05:00
xfs_buf_item.h xfs: Introduce an ordered buffer item 2013-06-27 13:33:11 -05:00
xfs_cksum.h xfs: add CRC infrastructure 2012-11-19 20:11:24 -06:00
xfs_da_btree.c xfs: xfs_da3_node_read_verify() doesn't handle XFS_ATTR3_LEAF_MAGIC 2013-05-24 16:29:37 -05:00
xfs_da_btree.h xfs: add buffer types to directory and attribute buffers 2013-04-27 13:01:06 -05:00
xfs_dfrag.c xfs: check on-disk (not incore) btree root size in dfrag.c 2013-06-20 13:26:09 -05:00
xfs_dfrag.h
xfs_dinode.h xfs: use XFS_BMAP_BMDR_SPACE vs. XFS_BROOT_SIZE_ADJ 2013-07-09 13:21:15 -05:00
xfs_dir2.c [readdir] convert xfs 2013-06-29 12:57:00 +04:00
xfs_dir2.h
xfs_dir2_block.c xfs: update (#2) for 3.11-rc1 2013-07-13 11:40:24 -07:00
xfs_dir2_data.c xfs: buffer type overruns blf_flags field 2013-04-27 13:01:58 -05:00
xfs_dir2_format.h xfs: fix implicit padding in directory and attr CRC formats 2013-06-14 15:59:16 -05:00
xfs_dir2_leaf.c xfs: update for 3.11-rc1 2013-07-09 12:29:12 -07:00
xfs_dir2_node.c xfs: fix dir3 freespace block corruption 2013-05-30 17:22:54 -05:00
xfs_dir2_priv.h [readdir] convert xfs 2013-06-29 12:57:00 +04:00
xfs_dir2_sf.c [readdir] convert xfs 2013-06-29 12:57:00 +04:00
xfs_discard.c xfs: check for possible overflow in xfs_ioc_trim 2012-08-23 14:48:44 -05:00
xfs_discard.h
xfs_dquot.c xfs: Add pquota fields where gquota is used. 2013-07-11 10:35:32 -05:00
xfs_dquot.h xfs: Add pquota fields where gquota is used. 2013-07-11 10:35:32 -05:00
xfs_dquot_item.c xfs: clean up xfs_bit.h includes 2012-05-14 16:21:00 -05:00
xfs_dquot_item.h
xfs_error.c xfs: increase hexdump output in xfs_corruption_error 2013-04-21 14:48:41 -05:00
xfs_error.h
xfs_export.c fs: encode_fh: return FILEID_INVALID if invalid fid_type 2013-02-26 02:46:10 -05:00
xfs_export.h
xfs_extent_busy.c xfs: make xfs_extent_busy_trim not static 2012-05-14 16:21:04 -05:00
xfs_extent_busy.h xfs: make xfs_extent_busy_trim not static 2012-05-14 16:21:04 -05:00
xfs_extfree_item.c xfs: Don't reference the EFI after it is freed 2013-05-24 16:27:57 -05:00
xfs_extfree_item.h xfs: don't free EFIs before the EFDs are committed 2013-04-05 13:25:35 -05:00
xfs_file.c vfs: export lseek_execute() to modules 2013-07-03 16:23:27 +04:00
xfs_filestream.c xfs: rename allocation range fields in struct xfs_bmalloca 2011-10-11 21:15:06 -05:00
xfs_filestream.h
xfs_fs.h xfs: add fsgeom flag for v5 superblock support. 2013-05-30 17:19:45 -05:00
xfs_fsops.c xfs: Remove redundant error variable from xfs_growfs_data_private() 2013-06-17 17:43:04 -05:00
xfs_fsops.h
xfs_globals.c xfs: add background scanning to clear eofblocks inodes 2012-11-08 15:34:59 -06:00
xfs_ialloc.c xfs: Use inode create transaction 2013-06-27 14:27:18 -05:00
xfs_ialloc.h xfs: Inode create item recovery 2013-06-27 14:26:21 -05:00
xfs_ialloc_btree.c xfs: introduce CONFIG_XFS_WARN 2013-05-07 18:45:36 -05:00
xfs_ialloc_btree.h xfs: add support for large btree blocks 2013-04-21 14:53:46 -05:00
xfs_icache.c xfs: Add pquota fields where gquota is used. 2013-07-11 10:35:32 -05:00
xfs_icache.h xfs: Remove dead function prototype xfs_sync_inode_grab() 2013-06-26 12:29:27 -05:00
xfs_icreate_item.c xfs: Inode create log items 2013-06-27 13:34:12 -05:00
xfs_icreate_item.h xfs: Inode create log items 2013-06-27 13:34:12 -05:00
xfs_inode.c xfs: use XFS_BMAP_BMDR_SPACE vs. XFS_BROOT_SIZE_ADJ 2013-07-09 13:21:15 -05:00
xfs_inode.h xfs: Add pquota fields where gquota is used. 2013-07-11 10:35:32 -05:00
xfs_inode_item.c xfs: add version 3 inode format with CRCs 2013-04-21 15:03:33 -05:00
xfs_inode_item.h xfs remove the XFS_TRANS_DEBUG routines 2012-12-17 16:29:00 -06:00
xfs_inum.h xfs: move xfsagino_t to xfs_types.h 2012-05-14 16:20:54 -05:00
xfs_ioctl.c xfs: Add pquota fields where gquota is used. 2013-07-11 10:35:32 -05:00
xfs_ioctl.h
xfs_ioctl32.c xfs: fallback to vmalloc for large buffers in xfs_compat_attrlist_by_handle 2013-05-07 19:00:10 -05:00
xfs_ioctl32.h
xfs_iomap.c xfs: don't use speculative prealloc for small files 2013-06-27 13:27:37 -05:00
xfs_iomap.h
xfs_iops.c xfs: Add pquota fields where gquota is used. 2013-07-11 10:35:32 -05:00
xfs_iops.h
xfs_itable.c xfs: clean up unused codes at xfs_bulkstat() 2013-07-09 15:36:21 -05:00
xfs_itable.h
xfs_linux.h xfs: introduce CONFIG_XFS_WARN 2013-05-07 18:45:36 -05:00
xfs_log.c xfs: Introduce ordered log vector support 2013-06-27 13:32:08 -05:00
xfs_log.h xfs: Inode create log items 2013-06-27 13:34:12 -05:00
xfs_log_cil.c xfs: Introduce ordered log vector support 2013-06-27 13:32:08 -05:00
xfs_log_priv.h xfs: Remove the obsolete XLOG_CIL_HARD_SPACE_LIMIT() macros 2013-04-16 13:18:33 -05:00
xfs_log_recover.c xfs: Inode create item recovery 2013-06-27 14:26:21 -05:00
xfs_log_recover.h
xfs_message.c xfs: introduce CONFIG_XFS_WARN 2013-05-07 18:45:36 -05:00
xfs_message.h xfs: introduce CONFIG_XFS_WARN 2013-05-07 18:45:36 -05:00
xfs_mount.c xfs: Remove incore use of XFS_OQUOTA_ENFD and XFS_OQUOTA_CHKD 2013-06-28 17:39:22 -05:00
xfs_mount.h xfs: Remove XFS_MOUNT_RETERR 2013-06-19 14:54:17 -05:00
xfs_mru_cache.c
xfs_mru_cache.h
xfs_qm.c xfs: Add pquota fields where gquota is used. 2013-07-11 10:35:32 -05:00
xfs_qm.h xfs: Add pquota fields where gquota is used. 2013-07-11 10:35:32 -05:00
xfs_qm_bhv.c xfs: Add pquota fields where gquota is used. 2013-07-11 10:35:32 -05:00
xfs_qm_syscalls.c xfs: Fix the logic check for all quotas being turned off 2013-07-11 16:49:10 -05:00
xfs_quota.h xfs: Fix the logic check for all quotas being turned off 2013-07-11 16:49:10 -05:00
xfs_quota_priv.h xfs: use per-filesystem radix trees for dquot lookup 2012-03-14 11:09:06 -05:00
xfs_quotaops.c xfs: Remove incore use of XFS_OQUOTA_ENFD and XFS_OQUOTA_CHKD 2013-06-28 17:39:22 -05:00
xfs_rename.c xfs: move xfsagino_t to xfs_types.h 2012-05-14 16:20:54 -05:00
xfs_rtalloc.c xfs: uncached buffer reads need to return an error 2012-11-15 21:34:05 -06:00
xfs_rtalloc.h
xfs_sb.h xfs: Define a new function xfs_is_quota_inode() 2013-06-28 13:03:49 -05:00
xfs_stats.c xfs: use common code for quota statistics 2012-03-14 11:09:06 -05:00
xfs_stats.h xfs: use common code for quota statistics 2012-03-14 11:09:06 -05:00
xfs_super.c xfs: Remove incore use of XFS_OQUOTA_ENFD and XFS_OQUOTA_CHKD 2013-06-28 17:39:22 -05:00
xfs_super.h xfs: xfs_sync_data is redundant. 2012-10-17 12:01:25 -05:00
xfs_symlink.c xfs: Add pquota fields where gquota is used. 2013-07-11 10:35:32 -05:00
xfs_symlink.h xfs: fix the symbolic link assert in xfs_ifree 2013-06-19 14:14:43 -05:00
xfs_sysctl.c xfs: Convert use of typedef ctl_table to struct ctl_table 2013-06-17 17:42:25 -05:00
xfs_sysctl.h xfs: add background scanning to clear eofblocks inodes 2012-11-08 15:34:59 -06:00
xfs_trace.c xfs: add CRCs to dir2/da node blocks 2013-04-27 12:33:38 -05:00
xfs_trace.h xfs: update for 3.11-rc1 2013-07-09 12:29:12 -07:00
xfs_trans.c xfs: Inode create transaction reservations 2013-06-27 13:36:37 -05:00
xfs_trans.h xfs: Inode create log items 2013-06-27 13:34:12 -05:00
xfs_trans_ail.c xfs remove the XFS_TRANS_DEBUG routines 2012-12-17 16:29:00 -06:00
xfs_trans_buf.c xfs: Introduce an ordered buffer item 2013-06-27 13:33:11 -05:00
xfs_trans_dquot.c xfs: Add pquota fields where gquota is used. 2013-07-11 10:35:32 -05:00
xfs_trans_extfree.c xfs: move xfsagino_t to xfs_types.h 2012-05-14 16:20:54 -05:00
xfs_trans_inode.c xfs: implement inode change count 2013-06-28 13:00:05 -05:00
xfs_trans_priv.h xfs: re-enable xfsaild idle mode and fix associated races 2012-07-29 16:27:57 -05:00
xfs_trans_space.h
xfs_types.h xfs: Remove boolean_t typedef completely. 2013-01-17 17:32:57 -06:00
xfs_utils.c xfs: remove the alloc_done argument to xfs_dialloc 2012-07-29 16:00:31 -05:00
xfs_utils.h xfs: propagate umode_t 2012-01-03 22:55:00 -05:00
xfs_vnode.h xfs: remove remaining scraps of struct xfs_iomap 2012-03-15 13:40:16 -05:00
xfs_vnodeops.c xfs: Add pquota fields where gquota is used. 2013-07-11 10:35:32 -05:00
xfs_vnodeops.h [readdir] convert xfs 2013-06-29 12:57:00 +04:00
xfs_xattr.c