return ERR_PTR(error);
 
        attr = kzalloc(sizeof(struct xfs_attr_intent) +
-                       sizeof(struct xfs_da_args), GFP_NOFS | __GFP_NOFAIL);
+                       sizeof(struct xfs_da_args), GFP_KERNEL | __GFP_NOFAIL);
        args = (struct xfs_da_args *)(attr + 1);
 
        attr->xattri_da_args = args;
 
        if (error)
                return ERR_PTR(error);
 
-       bi = kmem_cache_zalloc(xfs_bmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
+       bi = kmem_cache_zalloc(xfs_bmap_intent_cache,
+                       GFP_KERNEL | __GFP_NOFAIL);
        bi->bi_whichfork = (map->me_flags & XFS_BMAP_EXTENT_ATTR_FORK) ?
                        XFS_ATTR_FORK : XFS_DATA_FORK;
        bi->bi_type = map->me_flags & XFS_BMAP_EXTENT_TYPE_MASK;
 
  * part of recovery so that the root and real-time bitmap inodes can be read in
  * from disk in between the two stages.  This is necessary so that we can free
  * space in the real-time portion of the file system.
+ *
+ * We run this whole process under GFP_NOFS allocation context. We do a
+ * combination of non-transactional and transactional work, yet we really don't
+ * want to recurse into the filesystem from direct reclaim during any of this
+ * processing. This allows all the recovery code run here not to care about the
+ * memory allocation context it is running in.
  */
 int
 xlog_recover_finish(
        struct xlog     *log)
 {
-       int     error;
+       unsigned int    nofs_flags = memalloc_nofs_save();
+       int             error;
 
        error = xlog_recover_process_intents(log);
        if (error) {
                xlog_recover_cancel_intents(log);
                xfs_alert(log->l_mp, "Failed to recover intents");
                xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR);
-               return error;
+               goto out_error;
        }
 
        /*
                if (error < 0) {
                        xfs_alert(log->l_mp,
        "Failed to clear log incompat features on recovery");
-                       return error;
+                       goto out_error;
                }
        }
 
                 * and AIL.
                 */
                xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR);
+               goto out_error;
        }
 
-       return 0;
+out_error:
+       memalloc_nofs_restore(nofs_flags);
+       return error;
 }
 
 void
 
        struct xfs_refcount_intent      *ri;
 
        ri = kmem_cache_alloc(xfs_refcount_intent_cache,
-                       GFP_NOFS | __GFP_NOFAIL);
+                       GFP_KERNEL | __GFP_NOFAIL);
        ri->ri_type = pmap->pe_flags & XFS_REFCOUNT_EXTENT_TYPE_MASK;
        ri->ri_startblock = pmap->pe_startblock;
        ri->ri_blockcount = pmap->pe_len;
 
 {
        struct xfs_rmap_intent          *ri;
 
-       ri = kmem_cache_alloc(xfs_rmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);
+       ri = kmem_cache_alloc(xfs_rmap_intent_cache, GFP_KERNEL | __GFP_NOFAIL);
 
        switch (map->me_flags & XFS_RMAP_EXTENT_TYPE_MASK) {
        case XFS_RMAP_EXTENT_MAP: