if (error)
                goto err_inode;
 
+       if (VFS_I(ip)->i_nlink == 0)
+               xfs_iflags_set(ip, XFS_IRECOVERY);
        xfs_defer_init(&dfops, &firstfsb);
 
        /* Process deferred bmap item. */
 
        }
 
        mp = ip->i_mount;
+       ASSERT(!xfs_iflags_test(ip, XFS_IRECOVERY));
 
        /* If this is a read-only mount, don't do this (would generate I/O) */
        if (mp->m_flags & XFS_MOUNT_RDONLY)
 
 #define XFS_IPINNED            (1 << __XFS_IPINNED_BIT)
 #define XFS_IDONTCACHE         (1 << 9) /* don't cache the inode long term */
 #define XFS_IEOFBLOCKS         (1 << 10)/* has the preallocblocks tag set */
+/*
+ * If this unlinked inode is in the middle of recovery, don't let drop_inode
+ * truncate and free the inode.  This can happen if we iget the inode during
+ * log recovery to replay a bmap operation on the inode.
+ */
+#define XFS_IRECOVERY          (1 << 11)
 
 /*
  * Per-lifetime flags need to be reset when re-using a reclaimable inode during
 
        if (error)
                goto fail_iput;
 
+       xfs_iflags_clear(ip, XFS_IRECOVERY);
        ASSERT(VFS_I(ip)->i_nlink == 0);
        ASSERT(VFS_I(ip)->i_mode != 0);
 
 
                }
        }
 
+       /*
+        * During the second phase of log recovery, we need iget and
+        * iput to behave like they do for an active filesystem.
+        * xfs_fs_drop_inode needs to be able to prevent the deletion
+        * of inodes before we're done replaying log items on those
+        * inodes.
+        */
+       mp->m_super->s_flags |= MS_ACTIVE;
+
        /*
         * Finish recovering the file system.  This part needed to be delayed
         * until after the root and real-time bitmap inodes were consistently
 
 {
        struct xfs_inode        *ip = XFS_I(inode);
 
+       /*
+        * If this unlinked inode is in the middle of recovery, don't
+        * drop the inode just yet; log recovery will take care of
+        * that.  See the comment for this inode flag.
+        */
+       if (ip->i_flags & XFS_IRECOVERY) {
+               ASSERT(ip->i_mount->m_log->l_flags & XLOG_RECOVERY_NEEDED);
+               return 0;
+       }
+
        return generic_drop_inode(inode) || (ip->i_flags & XFS_IDONTCACHE);
 }