summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaksym Planeta <mcsim.planeta@gmail.com>2012-10-08 16:46:28 +0200
committerMaksym Planeta <mcsim.planeta@gmail.com>2012-10-08 16:46:28 +0200
commitf017df8013d6920ad42c1911a7bcef6b5778ebdd (patch)
treebd244118807ab663f92707ec9fcbc566a8cd581c
parent3b197f103ae74a0a2fb8f54510dca9195bf637c8 (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.
-rw-r--r--include/mach/kern_return.h6
-rw-r--r--vm/memory_object.c35
2 files changed, 27 insertions, 14 deletions
diff --git a/include/mach/kern_return.h b/include/mach/kern_return.h
index 2274328b..22161e3c 100644
--- a/include/mach/kern_return.h
+++ b/include/mach/kern_return.h
@@ -157,4 +157,10 @@
/* Object has been terminated and is no longer available.
*/
+#define KERN_NO_DATA 27
+ /* The address range specified does not contain data
+ * at the moment. This value should be provided after
+ * m_o_data_request call.
+ */
+
#endif /* _MACH_KERN_RETURN_H_ */
diff --git a/vm/memory_object.c b/vm/memory_object.c
index 57c42cd5..c49d8061 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;