linux/fs/xfs
Dave Chinner f30d500f80 xfs: fix inode lookup race
When we get concurrent lookups of the same inode that is not in the
per-AG inode cache, there is a race condition that triggers warnings
in unlock_new_inode() indicating that we are initialising an inode
that isn't in a the correct state for a new inode.

When we do an inode lookup via a file handle or a bulkstat, we don't
serialise lookups at a higher level through the dentry cache (i.e.
pathless lookup), and so we can get concurrent lookups of the same
inode.

The race condition is between the insertion of the inode into the
cache in the case of a cache miss and a concurrently lookup:

Thread 1			Thread 2
xfs_iget()
  xfs_iget_cache_miss()
    xfs_iread()
    lock radix tree
    radix_tree_insert()
				rcu_read_lock
				radix_tree_lookup
				lock inode flags
				XFS_INEW not set
				igrab()
				unlock inode flags
				rcu_read_unlock
				use uninitialised inode
				.....
    lock inode flags
    set XFS_INEW
    unlock inode flags
    unlock radix tree
  xfs_setup_inode()
    inode flags = I_NEW
    unlock_new_inode()
      WARNING as inode flags != I_NEW

This can lead to inode corruption, inode list corruption, etc, and
is generally a bad thing to occur.

Fix this by setting XFS_INEW before inserting the inode into the
radix tree. This will ensure any concurrent lookup will find the new
inode with XFS_INEW set and that forces the lookup to wait until the
XFS_INEW flag is removed before allowing the lookup to succeed.

cc: <stable@vger.kernel.org> # for 3.0.x, 3.2.x
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Ben Myers <bpm@sgi.com>
2012-03-15 13:16:42 -05:00
..
Kconfig quota: Make QUOTACTL config be selected by its users 2010-10-05 12:16:37 +02:00
kmem.c xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
kmem.h xfs: use a normal shrinker for the dquot freelist 2012-02-10 12:38:09 -06:00
Makefile xfs: use common code for quota statistics 2012-03-14 11:09:06 -05:00
mrlock.h xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
time.h xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
uuid.c xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
uuid.h xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_acl.c xfs: fix acl count validation in xfs_acl_from_disk() 2011-12-16 15:17:42 -06:00
xfs_acl.h xfs: Fix build breakage in xfs_iops.c when CONFIG_FS_POSIX_ACL is not set 2011-08-01 02:35:04 -04:00
xfs_ag.h xfs: Remove the macro XFS_BUF_PTR 2011-07-25 15:03:13 -05:00
xfs_alloc_btree.c xfs: remove leftovers of the old btree tracing code 2011-07-13 13:43:50 +02:00
xfs_alloc_btree.h
xfs_alloc.c xfs: remove XFS_BUF_SET_VTYPE and XFS_BUF_SET_VTYPE_REF 2011-10-11 21:15:09 -05:00
xfs_alloc.h xfs: do not discard alloc btree blocks 2011-05-24 11:17:22 -05:00
xfs_aops.c xfs: log file size updates at I/O completion time 2012-03-13 16:30:49 -05:00
xfs_aops.h xfs: log file size updates at I/O completion time 2012-03-13 16:30:49 -05:00
xfs_attr_leaf.c xfs: remove the if_ext_max field in struct xfs_ifork 2012-01-17 15:02:28 -06:00
xfs_attr_leaf.h
xfs_attr_sf.h xfs: convert attr to use unsigned names 2010-01-20 10:47:48 +11:00
xfs_attr.c xfs: remove xfs_itruncate_data 2012-01-13 12:11:45 -06:00
xfs_attr.h xfs: convert attr to use unsigned names 2010-01-20 10:47:48 +11:00
xfs_bit.c
xfs_bit.h
xfs_bmap_btree.c xfs: remove leftovers of the old btree tracing code 2011-07-13 13:43:50 +02:00
xfs_bmap_btree.h xfs: make several more functions static 2010-01-15 15:31:38 -06:00
xfs_bmap.c xfs: remove the i_size field in struct xfs_inode 2012-01-17 15:08:53 -06:00
xfs_bmap.h xfs: cleanup xfs_bmap.h 2011-10-11 21:15:07 -05:00
xfs_btree.c xfs: remove XFS_BUF_SET_VTYPE and XFS_BUF_SET_VTYPE_REF 2011-10-11 21:15:09 -05:00
xfs_btree.h xfs: Remove the macro XFS_BUF_PTR 2011-07-25 15:03:13 -05:00
xfs_buf_item.c xfs: constify xfs_item_ops 2011-11-08 10:48:23 -06:00
xfs_buf_item.h xfs: use struct list_head for the buf cancel table 2010-12-16 16:05:22 -06:00
xfs_buf.c xfs: use per-filesystem I/O completion workqueues 2012-03-05 11:07:42 -06:00
xfs_buf.h xfs: remove unused XBT_FORCE_SLEEP bit 2011-12-16 15:12:33 -06:00
xfs_da_btree.c xfs: remove XFS_BUF_SET_VTYPE and XFS_BUF_SET_VTYPE_REF 2011-10-11 21:15:09 -05:00
xfs_da_btree.h xfs: remove the dead XFS_DABUF_DEBUG code 2011-07-13 13:43:50 +02:00
xfs_dfrag.c xfs: split in-core and on-disk inode log item fields 2012-03-13 17:08:17 -05:00
xfs_dfrag.h xfs: clean up inconsistent variable naming in xfs_swap_extent 2010-01-15 15:31:23 -06:00
xfs_dinode.h xfs: Remove the macro XFS_BUF_PTR 2011-07-25 15:03:13 -05:00
xfs_dir2_block.c xfs: clean up minor sparse warnings 2012-03-14 13:21:17 -05:00
xfs_dir2_data.c xfs: reshuffle dir2 headers 2011-07-13 13:43:48 +02:00
xfs_dir2_format.h xfs: cleanup struct xfs_dir2_free 2011-07-13 13:43:48 +02:00
xfs_dir2_leaf.c xfs: introduce xfs_bmapi_read() 2011-10-11 21:15:03 -05:00
xfs_dir2_node.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2011-07-25 13:56:39 -07:00
xfs_dir2_priv.h xfs: reshuffle dir2 headers 2011-07-13 13:43:48 +02:00
xfs_dir2_sf.c xfs: reshuffle dir2 headers 2011-07-13 13:43:48 +02:00
xfs_dir2.c xfs: get rid of open-coded S_ISREG(), etc. 2011-07-26 15:05:16 -04:00
xfs_dir2.h xfs: reshuffle dir2 headers 2011-07-13 13:43:48 +02:00
xfs_discard.c xfs: fix endian conversion issue in discard code 2012-01-03 11:39:55 -06:00
xfs_discard.h xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_dquot_item.c xfs: cleanup dquot locking helpers 2011-12-12 17:28:20 -06:00
xfs_dquot_item.h xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_dquot.c xfs: remove the global xfs_Gqm structure 2012-03-14 12:06:32 -05:00
xfs_dquot.h xfs: remove the per-filesystem list of dquots 2012-03-14 11:53:34 -05:00
xfs_error.c xfs: Convert remaining cmn_err() callers to new API 2011-03-07 10:08:35 +11:00
xfs_error.h xfs: kill support/debug.[ch] 2011-03-07 10:09:35 +11:00
xfs_export.c xfs: fix nfs export of 64-bit inodes numbers on 32-bit kernels 2011-12-06 10:46:23 -06:00
xfs_export.h xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_extfree_item.c xfs: constify xfs_item_ops 2011-11-08 10:48:23 -06:00
xfs_extfree_item.h xfs: Pull EFI/EFD handling out from under the AIL lock 2010-12-20 11:59:49 +11:00
xfs_file.c xfs: reimplement fdatasync support 2012-03-13 17:18:14 -05: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: clean up filestreams helpers 2010-07-26 13:16:51 -05:00
xfs_fs_subr.c xfs: remove the i_size field in struct xfs_inode 2012-01-17 15:08:53 -06:00
xfs_fs.h xfs: consolidate & clarify mount sanity checks 2011-07-08 11:32:51 -05:00
xfs_fsops.c xfs: Check the return value of xfs_buf_get() 2011-10-11 21:15:01 -05:00
xfs_fsops.h xfs: ensure log covering transactions are synchronous 2011-01-11 20:28:17 -06:00
xfs_globals.c xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_ialloc_btree.c xfs: remove leftovers of the old btree tracing code 2011-07-13 13:43:50 +02:00
xfs_ialloc_btree.h
xfs_ialloc.c xfs: propagate umode_t 2012-01-03 22:55:00 -05:00
xfs_ialloc.h xfs: propagate umode_t 2012-01-03 22:55:00 -05:00
xfs_iget.c xfs: fix inode lookup race 2012-03-15 13:16:42 -05:00
xfs_inode_item.c xfs: reimplement fdatasync support 2012-03-13 17:18:14 -05:00
xfs_inode_item.h xfs: reimplement fdatasync support 2012-03-13 17:18:14 -05:00
xfs_inode.c xfs: split in-core and on-disk inode log item fields 2012-03-13 17:08:17 -05:00
xfs_inode.h xfs: log timestamp updates 2012-03-13 17:01:15 -05:00
xfs_inum.h xfs: cleanup shortform directory inode number handling 2011-07-08 14:35:03 +02:00
xfs_ioctl32.c xfs: clean up minor sparse warnings 2012-03-14 13:21:17 -05:00
xfs_ioctl32.h xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_ioctl.c vfs: mnt_drop_write_file() 2012-01-03 22:52:40 -05:00
xfs_ioctl.h xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_iomap.c xfs: log file size updates as part of unwritten extent conversion 2012-03-05 11:53:16 -06:00
xfs_iomap.h xfs: kill xfs_iomap 2010-12-16 16:05:51 -06:00
xfs_iops.c xfs: clean up minor sparse warnings 2012-03-14 13:21:17 -05:00
xfs_iops.h xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_itable.c xfs: log timestamp updates 2012-03-13 17:01:15 -05:00
xfs_itable.h xfs: remove block number from inode lookup code 2010-06-24 11:35:17 +10:00
xfs_linux.h xfs: revert to using a kthread for AIL pushing 2011-10-11 11:02:49 -05:00
xfs_log_cil.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2012-01-08 13:21:22 -08:00
xfs_log_priv.h xfs: split and cleanup xfs_log_reserve 2012-02-22 22:37:04 -06:00
xfs_log_recover.c xfs: add the xlog_grant_head structure 2012-02-22 22:19:53 -06:00
xfs_log_recover.h xfs: Clean up XFS_BLI_* flag namespace 2010-05-24 10:33:39 -05:00
xfs_log.c xfs: split and cleanup xfs_log_reserve 2012-02-22 22:37:04 -06:00
xfs_log.h xfs: split and cleanup xfs_log_reserve 2012-02-22 22:37:04 -06:00
xfs_message.c xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_message.h treewide: use __printf not __attribute__((format(printf,...))) 2011-10-31 17:30:54 -07:00
xfs_mount.c Change xfs_sb_from_disk() interface to take a mount pointer 2012-02-03 11:21:33 -06:00
xfs_mount.h xfs: use per-filesystem I/O completion workqueues 2012-03-05 11:07:42 -06:00
xfs_mru_cache.c xfs: convert to alloc_workqueue() 2011-02-01 11:42:43 +01:00
xfs_mru_cache.h xfs: Kill filestreams cache flush 2010-01-15 15:34:22 -06:00
xfs_qm_bhv.c xfs: remove the global xfs_Gqm structure 2012-03-14 12:06:32 -05:00
xfs_qm_syscalls.c xfs: remove the per-filesystem list of dquots 2012-03-14 11:53:34 -05:00
xfs_qm.c xfs: remove the global xfs_Gqm structure 2012-03-14 12:06:32 -05:00
xfs_qm.h xfs: remove the global xfs_Gqm structure 2012-03-14 12:06:32 -05:00
xfs_quota_priv.h xfs: use per-filesystem radix trees for dquot lookup 2012-03-14 11:09:06 -05:00
xfs_quota.h Define new macro XFS_ALL_QUOTA_ACTIVE and simply some usage 2012-02-03 11:32:20 -06:00
xfs_quotaops.c xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_rename.c xfs: simplify xfs_trans_ijoin* again 2011-10-11 21:15:08 -05:00
xfs_rtalloc.c xfs: simplify xfs_trans_ijoin* again 2011-10-11 21:15:08 -05:00
xfs_rtalloc.h xfs: Remove the macro XFS_BUF_PTR 2011-07-25 15:03:13 -05:00
xfs_rw.c xfs: clean up xfs_ioerror_alert 2011-10-11 21:15:10 -05:00
xfs_rw.h xfs: clean up xfs_ioerror_alert 2011-10-11 21:15:10 -05:00
xfs_sb.h xfs: kill the unused XFS_BB_FSB_OFFSET macro 2012-02-02 17:08:04 -06: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 the global xfs_Gqm structure 2012-03-14 12:06:32 -05:00
xfs_super.h xfs: remove the global xfs_Gqm structure 2012-03-14 12:06:32 -05:00
xfs_sync.c xfs: log timestamp updates 2012-03-13 17:01:15 -05:00
xfs_sync.h xfs: log timestamp updates 2012-03-13 17:01:15 -05:00
xfs_sysctl.c xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_sysctl.h xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_trace.c xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_trace.h xfs: use per-filesystem radix trees for dquot lookup 2012-03-14 11:09:06 -05:00
xfs_trans_ail.c xfs: cleanup xfs_log_space_wake 2012-02-22 22:17:00 -06:00
xfs_trans_buf.c xfs: remove xfs_trans_unlocked_item 2012-02-22 22:17:00 -06:00
xfs_trans_dquot.c xfs: remove the global xfs_Gqm structure 2012-03-14 12:06:32 -05:00
xfs_trans_extfree.c xfs: Pull EFI/EFD handling out from under the AIL lock 2010-12-20 11:59:49 +11:00
xfs_trans_inode.c xfs: split in-core and on-disk inode log item fields 2012-03-13 17:08:17 -05:00
xfs_trans_priv.h xfs: remove xfs_trans_unlocked_item 2012-02-22 22:17:00 -06:00
xfs_trans_space.h
xfs_trans.c xfs: split and cleanup xfs_log_reserve 2012-02-22 22:37:04 -06:00
xfs_trans.h xfs: remove the lid_size field in struct log_item_desc 2011-12-08 13:53:30 -06:00
xfs_types.h xfs: exact busy extent tracking 2011-04-28 13:18:04 -05:00
xfs_utils.c xfs: propagate umode_t 2012-01-03 22:55:00 -05:00
xfs_utils.h xfs: propagate umode_t 2012-01-03 22:55:00 -05:00
xfs_vnode.h xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs_vnodeops.c xfs: Fix missing xfs_iunlock() on error recovery path in xfs_readlink() 2012-01-25 11:01:31 -06:00
xfs_vnodeops.h xfs: propagate umode_t 2012-01-03 22:55:00 -05:00
xfs_xattr.c xfs: remove subdirectories 2011-08-12 16:21:35 -05:00
xfs.h xfs: don't expect xfs headers to be in subdirectories 2011-08-12 13:57:55 -05:00