--- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -987,13 +987,23 @@ * If cleaning the entire object do a pass to mark the pages read-only. * If everything worked out ok, clear OBJ_WRITEABLE and * OBJ_MIGHTBEDIRTY. + * + * NOTE: The PG_CLEANCHK marking pass must always run over the + * requested range, not just for wholescan, because pass2 and + * vm_object_page_collect_flush() ignore any page that does not + * have PG_CLEANCHK set. Restricting pass1 to wholescan made + * every partial-range clean a silent no-op (e.g. msync() of a + * sub-range, or of a mapping smaller than the object - on + * filesystems whose vnode objects are sized beyond EOF by + * nvnode_pager_setsize(), such as hammer2, that is every + * msync() range expressible on the file). */ - if (wholescan) { - info.error = 0; - info.count = 0; - vm_page_rb_tree_RB_SCAN(&object->rb_memq, rb_vm_page_scancmp, - vm_object_page_clean_pass1, &info); - if (info.error == 0) { + info.error = 0; + info.count = 0; + vm_page_rb_tree_RB_SCAN(&object->rb_memq, rb_vm_page_scancmp, + vm_object_page_clean_pass1, &info); + { + if (wholescan && info.error == 0) { vm_object_clear_flag(object, OBJ_WRITEABLE|OBJ_MIGHTBEDIRTY); if (object->type == OBJT_VNODE &&