From a2d2574eac3eb153f8503f91197898101d3c86d2 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Thu, 30 Oct 2008 11:09:15 +0200 Subject: [PATCH] Added VM_DIRTY flag for file-backed objects and their pages. Now file flushing in both munmap() and fsync() caters for VM_DIRTY. Also write_cache_pages() and write faults set this bit on pages and their objects. --- tasks/mm0/include/vm_area.h | 4 ++-- tasks/mm0/src/fault.c | 8 +++++++- tasks/mm0/src/file.c | 7 +++++++ tasks/mm0/src/munmap.c | 5 ++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/tasks/mm0/include/vm_area.h b/tasks/mm0/include/vm_area.h index e7b803b..f424755 100644 --- a/tasks/mm0/include/vm_area.h +++ b/tasks/mm0/include/vm_area.h @@ -51,8 +51,8 @@ enum VM_FILE_TYPE { }; /* Defines the type of object. A file? Just a standalone object? */ -#define VM_OBJ_SHADOW (1 << 8) /* Anonymous pages, swap_pager */ -#define VM_OBJ_FILE (1 << 9) /* VFS file and device pages */ +#define VM_OBJ_SHADOW (1 << 10) /* Anonymous pages, swap_pager */ +#define VM_OBJ_FILE (1 << 11) /* VFS file and device pages */ struct page { int refcnt; /* Refcount */ diff --git a/tasks/mm0/src/fault.c b/tasks/mm0/src/fault.c index fa3d468..cc187e5 100644 --- a/tasks/mm0/src/fault.c +++ b/tasks/mm0/src/fault.c @@ -677,7 +677,13 @@ int __do_page_fault(struct fault_data *fault) BUG(); } } - BUG_ON(!page); + + /* + * Page and object are now dirty. Currently it's + * only relevant for file-backed shared objects. + */ + page->flags |= VM_DIRTY; + page->owner->flags |= VM_DIRTY; } else BUG(); } diff --git a/tasks/mm0/src/file.c b/tasks/mm0/src/file.c index f49f35c..6f21fa0 100644 --- a/tasks/mm0/src/file.c +++ b/tasks/mm0/src/file.c @@ -338,6 +338,13 @@ int write_file_pages(struct vm_file *f, unsigned long pfn_start, { int err; + /* We have only thought of vfs files for this */ + BUG_ON(f->type != VM_FILE_VFS); + + /* Need not flush files that haven't been written */ + if (!(f->vm_obj.flags & VM_DIRTY)) + return 0; + BUG_ON(pfn_end != __pfn(page_align_up(f->length))); for (int f_offset = pfn_start; f_offset < pfn_end; f_offset++) { err = f->vm_obj.pager->ops.page_out(&f->vm_obj, f_offset); diff --git a/tasks/mm0/src/munmap.c b/tasks/mm0/src/munmap.c index 7f44fa6..1394667 100644 --- a/tasks/mm0/src/munmap.c +++ b/tasks/mm0/src/munmap.c @@ -90,7 +90,6 @@ int vma_flush_pages(struct vm_area *vma) int err; /* Read-only vmas need not flush objects */ - /* FIXME: Ensure pf_handler sets VM_DIRTY on write-faulted pages */ if (!(vma->flags & VM_WRITE)) return 0; @@ -101,6 +100,10 @@ int vma_flush_pages(struct vm_area *vma) BUG_ON(list_empty(&vma->list)); vmo = list_entry(vma->list.next, struct vm_object, list); + /* Only dirty objects would need flushing */ + if (!(vmo->flags & VM_DIRTY)) + return 0; + /* Only vfs file objects are flushed */ if (vmo->flags & VM_OBJ_FILE && vmo->flags & VMA_SHARED &&