* vm_object_page_clean * * Clean all dirty pages in the specified range of object. Leaves page * on whatever queue it is currently on. If NOSYNC is set then do not * write out pages with PGA_NOSYNC set (originally comes from MAP_NOSYNC), * leaving the object dirty. * * For swap objects backing tmpfs regular files, do not flush anything, * but remove write protection on the mapped page
| 1018 | * reported by the pager, and TRUE otherwise. |
| 1019 | */ |
| 1020 | boolean_t |
| 1021 | vm_object_page_clean(vm_object_t object, vm_ooffset_t start, vm_ooffset_t end, |
| 1022 | int flags) |
| 1023 | { |
| 1024 | vm_page_t np, p; |
| 1025 | vm_pindex_t pi, tend, tstart; |
| 1026 | int curgeneration, n, pagerflags; |
| 1027 | boolean_t eio, res, allclean; |
| 1028 | |
| 1029 | VM_OBJECT_ASSERT_WLOCKED(object); |
| 1030 | |
| 1031 | if (!vm_object_mightbedirty(object) || object->resident_page_count == 0) |
| 1032 | return (TRUE); |
| 1033 | |
| 1034 | pagerflags = (flags & (OBJPC_SYNC | OBJPC_INVAL)) != 0 ? |
| 1035 | VM_PAGER_PUT_SYNC : VM_PAGER_CLUSTER_OK; |
| 1036 | pagerflags |= (flags & OBJPC_INVAL) != 0 ? VM_PAGER_PUT_INVAL : 0; |
| 1037 | |
| 1038 | tstart = OFF_TO_IDX(start); |
| 1039 | tend = (end == 0) ? object->size : OFF_TO_IDX(end + PAGE_MASK); |
| 1040 | allclean = tstart == 0 && tend >= object->size; |
| 1041 | res = TRUE; |
| 1042 | |
| 1043 | rescan: |
| 1044 | curgeneration = object->generation; |
| 1045 | |
| 1046 | for (p = vm_page_find_least(object, tstart); p != NULL; p = np) { |
| 1047 | pi = p->pindex; |
| 1048 | if (pi >= tend) |
| 1049 | break; |
| 1050 | np = TAILQ_NEXT(p, listq); |
| 1051 | if (vm_page_none_valid(p)) |
| 1052 | continue; |
| 1053 | if (vm_page_busy_acquire(p, VM_ALLOC_WAITFAIL) == 0) { |
| 1054 | if (object->generation != curgeneration && |
| 1055 | (flags & OBJPC_SYNC) != 0) |
| 1056 | goto rescan; |
| 1057 | np = vm_page_find_least(object, pi); |
| 1058 | continue; |
| 1059 | } |
| 1060 | if (!vm_object_page_remove_write(p, flags, &allclean)) { |
| 1061 | vm_page_xunbusy(p); |
| 1062 | continue; |
| 1063 | } |
| 1064 | if (object->type == OBJT_VNODE) { |
| 1065 | n = vm_object_page_collect_flush(object, p, pagerflags, |
| 1066 | flags, &allclean, &eio); |
| 1067 | if (eio) { |
| 1068 | res = FALSE; |
| 1069 | allclean = FALSE; |
| 1070 | } |
| 1071 | if (object->generation != curgeneration && |
| 1072 | (flags & OBJPC_SYNC) != 0) |
| 1073 | goto rescan; |
| 1074 | |
| 1075 | /* |
| 1076 | * If the VOP_PUTPAGES() did a truncated write, so |
| 1077 | * that even the first page of the run is not fully |
no test coverage detected