From c08ca9ec372d107bb7c8b82ef8ae2334d0136a12 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Wed, 7 Mar 2012 04:50:25 +0000 Subject: [PATCH] --- yaml --- r: 294635 b: refs/heads/master c: f30d500f809eca67a21704347ab14bb35877b5ee h: refs/heads/master i: 294633: 34ffb1bfd241567b0371559bbf24e2faabe1adf8 294631: 994263f79a91d2dd38960b0c7321191433527979 v: v3 --- [refs] | 2 +- trunk/fs/xfs/xfs_iget.c | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/[refs] b/[refs] index 48f1dfc3e424..e39382b7c8e0 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8d2a5e6ee37f205b3d76c223d4f3f88ba1d06220 +refs/heads/master: f30d500f809eca67a21704347ab14bb35877b5ee diff --git a/trunk/fs/xfs/xfs_iget.c b/trunk/fs/xfs/xfs_iget.c index af3f30a3d9c2..a98cb4524e6c 100644 --- a/trunk/fs/xfs/xfs_iget.c +++ b/trunk/fs/xfs/xfs_iget.c @@ -349,9 +349,20 @@ xfs_iget_cache_miss( BUG(); } - spin_lock(&pag->pag_ici_lock); + /* + * These values must be set before inserting the inode into the radix + * tree as the moment it is inserted a concurrent lookup (allowed by the + * RCU locking mechanism) can find it and that lookup must see that this + * is an inode currently under construction (i.e. that XFS_INEW is set). + * The ip->i_flags_lock that protects the XFS_INEW flag forms the + * memory barrier that ensures this detection works correctly at lookup + * time. + */ + ip->i_udquot = ip->i_gdquot = NULL; + xfs_iflags_set(ip, XFS_INEW); /* insert the new inode */ + spin_lock(&pag->pag_ici_lock); error = radix_tree_insert(&pag->pag_ici_root, agino, ip); if (unlikely(error)) { WARN_ON(error != -EEXIST); @@ -359,11 +370,6 @@ xfs_iget_cache_miss( error = EAGAIN; goto out_preload_end; } - - /* These values _must_ be set before releasing the radix tree lock! */ - ip->i_udquot = ip->i_gdquot = NULL; - xfs_iflags_set(ip, XFS_INEW); - spin_unlock(&pag->pag_ici_lock); radix_tree_preload_end();