* know that this is a new incore inode.
         */
        error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, imap_flags, XFS_BUF_LOCK);
-       if (error) {
-               xfs_idestroy(ip);
-               return error;
-       }
+       if (error)
+               goto out_destroy_inode;
 
        /*
         * If we got something that isn't an inode it means someone
         * (nfs or dmi) has a stale handle.
         */
        if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC) {
-               xfs_idestroy(ip);
-               xfs_trans_brelse(tp, bp);
 #ifdef DEBUG
                xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: "
                                "dip->di_core.di_magic (0x%x) != "
                                be16_to_cpu(dip->di_core.di_magic),
                                XFS_DINODE_MAGIC);
 #endif /* DEBUG */
-               return XFS_ERROR(EINVAL);
+               error = XFS_ERROR(EINVAL);
+               goto out_brelse;
        }
 
        /*
                xfs_dinode_from_disk(&ip->i_d, &dip->di_core);
                error = xfs_iformat(ip, dip);
                if (error)  {
-                       xfs_idestroy(ip);
-                       xfs_trans_brelse(tp, bp);
 #ifdef DEBUG
                        xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: "
                                        "xfs_iformat() returned error %d",
                                        error);
 #endif /* DEBUG */
-                       return error;
+                       goto out_brelse;
                }
        } else {
                ip->i_d.di_magic = be16_to_cpu(dip->di_core.di_magic);
        xfs_trans_brelse(tp, bp);
        *ipp = ip;
        return 0;
+
+ out_brelse:
+       xfs_trans_brelse(tp, bp);
+ out_destroy_inode:
+       xfs_destroy_inode(ip);
+       return error;
 }
 
 /*
 
        return &ip->i_vnode;
 }
 
+/*
+ * Get rid of a partially initialized inode.
+ *
+ * We have to go through destroy_inode to make sure allocations
+ * from init_inode_always like the security data are undone.
+ *
+ * We mark the inode bad so that it takes the short cut in
+ * the reclaim path instead of going through the flush path
+ * which doesn't make sense for an inode that has never seen the
+ * light of day.
+ */
+static inline void xfs_destroy_inode(struct xfs_inode *ip)
+{
+       make_bad_inode(VFS_I(ip));
+       return destroy_inode(VFS_I(ip));
+}
+
 /*
  * i_flags helper functions
  */