#include <linux/backing-dev.h>
 #include <linux/bug.h>
 #include <linux/module.h>
+#include <linux/sched/mm.h>
 
 #include <trace/events/jbd2.h>
 
 
        rwsem_acquire_read(&journal->j_trans_commit_map, 0, 0, _THIS_IP_);
        jbd2_journal_free_transaction(new_transaction);
+       /*
+        * Ensure that no allocations done while the transaction is open are
+        * going to recurse back to the fs layer.
+        */
+       handle->saved_alloc_context = memalloc_nofs_save();
        return 0;
 }
 
        trace_jbd2_handle_start(journal->j_fs_dev->bd_dev,
                                handle->h_transaction->t_tid, type,
                                line_no, nblocks);
+
        return handle;
 }
 EXPORT_SYMBOL(jbd2__journal_start);
        if (handle->h_rsv_handle)
                jbd2_journal_free_reserved(handle->h_rsv_handle);
 free_and_exit:
+       /*
+        * Scope of the GFP_NOFS context is over here and so we can restore the
+        * original alloc context.
+        */
+       memalloc_nofs_restore(handle->saved_alloc_context);
        jbd2_free_handle(handle);
        return err;
 }