Monitor mapped file modification

I want to monitor filesystem changes, so I created a minifilter.
How can I determine if a process is modifying a mapped file?

When a process performs the following actions:

CreateFile
CreateFileMapping
MapViewOfFileEx
Write data to file
UnmapViewOfFile
Close CreateFileMapping Handle
Close CreateFile Handle

I get the following IRP callbacks:

CreateFile
IRP_MJ_CREATE
IRP_MJ_QUERY_INFORMATION

CreateFileMapping
IRP_MJ_QUERY_INFORMATION
IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION
IRP_MJ_RELEASE_FOR_SECTION_SYNCHRONIZATION

MapViewOfFileEx
No IRP

Write data to file
No IRP

UnmapViewOfFile
No IRP

Close Handles
IRP_MJ_CLEANUP
IRP_MJ_CLOSE (this IRP comes from the system process)

After a few seconds I get the following IRP, probably from the cache manager.
IRP_MJ_ACQUIRE_FOR_MOD_WRITE (this IRP comes from the system process)
IRP_MJ_WRITE (this IRP comes from the system process)
IRP_MJ_RELEASE_FOR_MOD_WRITE (this IRP comes from the system process)

When the application creates a section using CreateFileMapping, I get a IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION callback and can check the section permissions (read only or read write),
but I can’t tell the difference between a scenario with modifying the file, and opening a mapped file with read-write permissions but without modifying the file.

I thought of several options to solve the problem, so far I haven’t been able to move forward with any of them.

Idea 1:
On IRP_MJ_CLEANUP callback, I can check whether there is pending IO for writing on this file object.
But I haven’t found how to do it.

Idea 2:
When the application unmapps the page, check if the page is marked “dirty”, if so then the application has changed the contents of the file.
The problem is I haven’t found how to get a kernel callback when the application calls UnmapViewOfFile.
I do not want to use user-mode hooks.

Idea 3:
When the cache manager sends IRP_MJ_WRITE, I can somehow correlate it with the process that actually made the change.
But I haven’t found a reliable way to do it. Think of a situation where a process wrote to the file named file1 and then immediately changed the name of file1 to file2,
although the writing was to the file file1, the IRP_MJ_WRITE will be on file2.