diff options
author | Maksym Planeta <mcsim.planeta@gmail.com> | 2012-10-08 16:46:28 +0200 |
---|---|---|
committer | Maksym Planeta <mcsim.planeta@gmail.com> | 2012-10-28 12:23:37 +0100 |
commit | 5fb4561e864d834cf7c637f6c798f04aea26c23e (patch) | |
tree | b0d15670d4eef7f456526e8d97f726f2c8764c52 /vm | |
parent | 2cf980488c7ffafae4036dddefa92d9a8cf2b0db (diff) |
Add special treatment in memory_object_data_error RPC.
This commit add possibility for server to inform kernel that server has no
some data requested by kernel. This possibility should be used when kernel
asks for cluster of data, but server can't return all the data.
* include/mach/kern_return.h (KERN_NO_DATA): New macro. Using this value
server may notify kernel that not all data in requested by kernel cluster
are available at the moment.
* vm/memory_object.c (memory_object_data_error): Add special treatment for
error code KERN_NO_DATA.
Diffstat (limited to 'vm')
-rw-r--r-- | vm/memory_object.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/vm/memory_object.c b/vm/memory_object.c index 090b58eb..8836c290 100644 --- a/vm/memory_object.c +++ b/vm/memory_object.c @@ -337,11 +337,6 @@ kern_return_t memory_object_data_error(object, offset, size, error_value) if (size != round_page(size)) return(KERN_INVALID_ARGUMENT); -#ifdef lint - /* Error value is ignored at this time */ - error_value++; -#endif - vm_object_lock(object); offset -= object->paging_offset; @@ -349,16 +344,28 @@ kern_return_t memory_object_data_error(object, offset, size, error_value) register vm_page_t m; m = vm_page_lookup(object, offset); - if ((m != VM_PAGE_NULL) && m->busy && m->absent) { - m->error = TRUE; - m->absent = FALSE; - vm_object_absent_release(object); - PAGE_WAKEUP_DONE(m); - - vm_page_lock_queues(); - vm_page_activate(m); - vm_page_unlock_queues(); + switch (error_value) { + case KERN_NO_DATA: + if ((m != VM_PAGE_NULL) && m->busy && m->absent) { + vm_page_lock_queues(); + vm_page_free(m); + vm_page_unlock_queues(); + } + break; + default: + if ((m != VM_PAGE_NULL) && m->busy && m->absent) { + m->error = TRUE; + m->absent = FALSE; + vm_object_absent_release(object); + + PAGE_WAKEUP_DONE(m); + + vm_page_lock_queues(); + vm_page_activate(m); + vm_page_unlock_queues(); + } + break; } size -= PAGE_SIZE; |