summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_iget.c
diff options
context:
space:
mode:
authorFelix Blyakher <felixb@sgi.com>2009-04-09 14:12:07 -0500
committerFelix Blyakher <felixb@sgi.com>2009-04-09 14:12:07 -0500
commitdc2a5536d633dd2318f82f3d5ad3c9e43cfc21d7 (patch)
tree20b68d90d175eb9f07cf19b2e8be4011a8e8e6e5 /fs/xfs/xfs_iget.c
parentf36345ff9a4a77f2cc576a2777b6256d5c8798fa (diff)
parent8de2bf937a6bea8f0f775fd5399ba20c1a0c3d77 (diff)
downloadop-kernel-dev-dc2a5536d633dd2318f82f3d5ad3c9e43cfc21d7.zip
op-kernel-dev-dc2a5536d633dd2318f82f3d5ad3c9e43cfc21d7.tar.gz
Merge branch 'master' into for-linus
Diffstat (limited to 'fs/xfs/xfs_iget.c')
-rw-r--r--fs/xfs/xfs_iget.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 478e587..89b81ee 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -69,15 +69,6 @@ xfs_inode_alloc(
ASSERT(!spin_is_locked(&ip->i_flags_lock));
ASSERT(completion_done(&ip->i_flush));
- /*
- * initialise the VFS inode here to get failures
- * out of the way early.
- */
- if (!inode_init_always(mp->m_super, VFS_I(ip))) {
- kmem_zone_free(xfs_inode_zone, ip);
- return NULL;
- }
-
/* initialise the xfs inode */
ip->i_ino = ino;
ip->i_mount = mp;
@@ -113,6 +104,20 @@ xfs_inode_alloc(
#ifdef XFS_DIR2_TRACE
ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS);
#endif
+ /*
+ * Now initialise the VFS inode. We do this after the xfs_inode
+ * initialisation as internal failures will result in ->destroy_inode
+ * being called and that will pass down through the reclaim path and
+ * free the XFS inode. This path requires the XFS inode to already be
+ * initialised. Hence if this call fails, the xfs_inode has already
+ * been freed and we should not reference it at all in the error
+ * handling.
+ */
+ if (!inode_init_always(mp->m_super, VFS_I(ip)))
+ return NULL;
+
+ /* prevent anyone from using this yet */
+ VFS_I(ip)->i_state = I_NEW|I_LOCK;
return ip;
}
OpenPOWER on IntegriCloud