|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22:
23: #include <sys/errno.h>
24: #include <kern/host.h>
25: #include <mach/mach_types.h>
26: #include <vm/vm_map.h>
27: #include <vm/vm_kern.h>
28: #include <vm/vm_pageout.h>
29: #include <mach/kern_return.h>
30: #include <mach/memory_object_types.h>
31: #include <mach/port.h>
32: #include <mach/policy.h>
33: #include <ipc/ipc_port.h>
34: #include <ipc/ipc_space.h>
35: #include <kern/thread.h>
36: #include <vm/vm_pageout.h>
37:
38:
39: /* BSD VM COMPONENT INTERFACES */
40: int
41: get_map_nentries(
42: vm_map_t);
43:
44: vm_offset_t
45: get_map_start(
46: vm_map_t);
47:
48: vm_offset_t
49: get_map_end(
50: vm_map_t);
51:
52: void
53: map_ref_fixup(
54: vm_map_t,
55: vm_map_t);
56:
57: /*
58: *
59: */
60: int
61: get_map_nentries(
62: vm_map_t map)
63: {
64: return(map->hdr.nentries);
65: }
66:
67: /*
68: *
69: */
70: vm_offset_t
71: get_map_start(
72: vm_map_t map)
73: {
74: return(vm_map_first_entry(map)->vme_start);
75: }
76:
77: /*
78: *
79: */
80: vm_offset_t
81: get_map_end(
82: vm_map_t map)
83: {
84: return(vm_map_last_entry(map)->vme_end);
85: }
86:
87: /*
88: * TODO: TO BE REMOVED
89: */
90: void
91: map_ref_fixup(
92: vm_map_t old_map,
93: vm_map_t new_map)
94: {
95: if (old_map->ref_count >1)
96: old_map->ref_count = 1;
97: new_map->ref_count =2;
98: }
99:
100: /*
101: * BSD VNODE PAGER
102: */
103:
104: /* until component support available */
105: int vnode_pager_workaround;
106:
107: typedef int vnode_port_t;
108:
109: typedef struct vnode_pager {
110: ipc_port_t pager; /* pager */
111: ipc_port_t pager_handle; /* pager handle */
112: ipc_port_t vm_obj_handle; /* memory object's control handle */
113: vnode_port_t vnode_handle; /* vnode handle */
114: } *vnode_pager_t;
115:
116: typedef struct vnode_port_entry {
117: queue_chain_t links; /* queue links */
118: ipc_port_t name; /* port name */
119: vnode_pager_t pager_rec; /* pager record */
120: } *vnode_port_entry_t;
121:
122:
123: #define VNODE_PORT_HASH_COUNT 127
124: #define vnode_port_hash(name_port) \
125: (((int)(name_port) & 0xffffff) % VNODE_PORT_HASH_COUNT)
126:
127: queue_head_t vnode_port_hashtable[VNODE_PORT_HASH_COUNT];
128: zone_t vnode_port_hash_zone;
129: decl_simple_lock_data(,vnode_port_hash_lock)
130:
131:
132: ipc_port_t
133: trigger_name_to_port(
134: mach_port_t);
135:
136: void
137: vnode_pager_bootstrap(
138: void);
139:
140: void
141: vnode_pager_alloc_map(
142: void);
143:
144: ipc_port_t
145: vnode_pager_setup(
146: vnode_port_t,
147: ipc_port_t);
148:
149: ipc_port_t
150: vnode_pager_lookup(
151: vnode_port_t,
152: ipc_port_t);
153:
154: kern_return_t
155: vnode_pager_init(
156: ipc_port_t,
157: ipc_port_t,
158: vm_size_t);
159:
160: kern_return_t
161: vnode_pager_data_request(
162: ipc_port_t,
163: ipc_port_t,
164: vm_offset_t,
165: vm_size_t,
166: vm_prot_t);
167:
168: kern_return_t
169: vnode_pager_data_return(
170: ipc_port_t,
171: ipc_port_t,
172: vm_offset_t,
173: pointer_t,
174: vm_size_t,
175: boolean_t,
176: boolean_t);
177:
178: void
179: vnode_pager_no_senders(
180: ipc_port_t,
181: mach_port_mscount_t);
182:
183: kern_return_t
184: vnode_pager_terminate(
185: ipc_port_t,
186: ipc_port_t);
187:
188: kern_return_t
189: vnode_pager_cluster_read(
190: vnode_pager_t,
191: vm_offset_t,
192: vm_size_t,
193: vm_object_t);
194:
195: void
196: vnode_pager_cluster_write(
197: vnode_pager_t,
198: vm_offset_t,
199: vm_size_t,
200: vm_object_t);
201:
202: kern_return_t
203: memory_object_change_attributes(
204: vm_object_t,
205: memory_object_flavor_t,
206: memory_object_info_t,
207: mach_msg_type_number_t,
208: ipc_port_t,
209: mach_msg_type_name_t);
210:
211: vnode_pager_t
212: vnode_object_create(
213: vnode_port_t vp);
214:
215: void
216: vnode_port_hash_init(void);
217:
218: void
219: vnode_port_hash_insert(
220: ipc_port_t,
221: vnode_pager_t);
222:
223: vnode_pager_t
224: vnode_port_hash_lookup(
225: ipc_port_t);
226:
227: void
228: vnode_port_hash_delete(
229: ipc_port_t);
230:
231: void
232: vnode_pager_release_from_cache(
233: int *cnt);
234:
235: void
236: vnode_pager_create(
237: vnode_port_t,
238: ipc_port_t);
239:
240: int
241: vnode_pageout(
242: vnode_port_t,
243: vm_offset_t,
244: vm_offset_t,
245: int,
246: int *);
247:
248: int
249: vnode_pagein(
250: vnode_port_t,
251: vm_offset_t,
252: vm_offset_t,
253: int,
254: int *);
255:
256: zone_t vnode_pager_zone;
257:
258:
259: #define VNODE_PAGER_NULL ((vnode_pager_t) 0)
260:
261: /* TODO: Should be set dynamically by vnode_pager_init() */
262: #define CLUSTER_SHIFT 1
263:
264: /* TODO: Should be set dynamically by vnode_pager_bootstrap() */
265: #define MAX_VNODE 10000
266:
267:
268: #if DEBUG
269: int pagerdebug=0;
270:
271: #define PAGER_ALL 0xffffffff
272: #define PAGER_INIT 0x00000001
273: #define PAGER_PAGEIN 0x00000002
274:
275: #define PAGER_DEBUG(LEVEL, A) {if ((pagerdebug & LEVEL)==LEVEL){printf A;}}
276: #else
277: #define PAGER_DEBUG(LEVEL, A)
278: #endif
279:
280: /*
281: * Routine: macx_triggers
282: * Function:
283: * Syscall interface to set the call backs for low and
284: * high water marks.
285: */
286: int
287: macx_triggers(
288: int hi_water,
289: int low_water,
290: int flags,
291: mach_port_t trigger_name)
292: {
293: kern_return_t kr;
294: ipc_port_t default_pager_port = MACH_PORT_NULL;
295: ipc_port_t trigger_port;
296:
297: kr = host_default_memory_manager(realhost.host_priv_self,
298: &default_pager_port, 0);
299: if(kr != KERN_SUCCESS) {
300: return EINVAL;
301: }
302: trigger_port = trigger_name_to_port(trigger_name);
303: if(trigger_port == NULL) {
304: return EINVAL;
305: }
306: /* trigger_port is locked and active */
307: ip_unlock(trigger_port);
308: default_pager_triggers(default_pager_port,
309: hi_water, low_water, flags, trigger_port);
310: ipc_port_make_send(trigger_port);
311:
312: /*
313: * Set thread scheduling priority and policy for the current thread
314: * it is assumed for the time being that the thread setting the alert
315: * is the same one which will be servicing it.
316: */
317: {
318: struct policy_timeshare_base fifo_base;
319: struct policy_timeshare_limit fifo_limit;
320: policy_base_t base;
321: processor_set_t pset;
322: policy_limit_t limit;
323:
324: pset = (current_thread())->processor_set;
325: base = (policy_base_t) &fifo_base;
326: limit = (policy_limit_t) &fifo_limit;
327: fifo_base.base_priority = BASEPRI_KERNEL;
328: fifo_limit.max_priority = BASEPRI_KERNEL;
329: thread_set_policy((current_thread())->top_act, pset, POLICY_FIFO, base, POLICY_TIMESHARE_BASE_COUNT, limit, POLICY_TIMESHARE_LIMIT_COUNT);
330: }
331:
332: current_thread()->vm_privilege = TRUE;
333: }
334:
335: /*
336: *
337: */
338: ipc_port_t
339: trigger_name_to_port(
340: mach_port_t trigger_name)
341: {
342: ipc_port_t trigger_port;
343: ipc_space_t space;
344:
345: if (trigger_name == 0)
346: return (NULL);
347:
348: space = current_space();
349: if(ipc_port_translate_receive(space, (mach_port_name_t)trigger_name,
350: &trigger_port) != KERN_SUCCESS)
351: return (NULL);
352: return trigger_port;
353: }
354:
355: /*
356: *
357: */
358: void
359: vnode_pager_bootstrap(void)
360: {
361: register vm_size_t size;
362:
363: size = (vm_size_t) sizeof(struct vnode_pager);
364: vnode_pager_zone = zinit(size, (vm_size_t) MAX_VNODE*size,
365: PAGE_SIZE, "vnode pager structures");
366: vnode_port_hash_init();
367:
368: return;
369: }
370:
371: /*
372: *
373: */
374: ipc_port_t
375: vnode_pager_setup(
376: vnode_port_t vp,
377: ipc_port_t pager)
378: {
379: vnode_pager_t vnode_object;
380: kern_return_t kr;
381: ipc_port_t previous;
382:
383: if (pager &&
384: (vnode_object = vnode_port_hash_lookup(pager))) {
385: if (vnode_object->vnode_handle == vp)
386: return(pager);
387: }
388:
389: vnode_object = vnode_object_create(vp);
390: if (vnode_object == VNODE_PAGER_NULL)
391: panic("vnode_pager_setup: vnode_object_create() failed");
392:
393: vnode_object->pager = ipc_port_alloc_kernel();
394: assert (vnode_object->pager != IP_NULL);
395: pager_mux_hash_insert(vnode_object->pager,
396: (rpc_subsystem_t)&vnode_pager_workaround);
397:
398: vnode_object->pager_handle = ipc_port_make_send(vnode_object->pager);
399:
400: vnode_port_hash_insert(vnode_object->pager_handle, vnode_object);
401:
402: ipc_port_make_sonce(vnode_object->pager);
403: ip_lock(vnode_object->pager); /* unlocked in nsrequest below */
404: ipc_port_nsrequest(vnode_object->pager, 1, vnode_object->pager, &previous);
405:
406: PAGER_DEBUG(PAGER_INIT, ("vnode_pager_setup: vp %x pager %x vnode_pager %x\n", vp, vnode_object->pager_handle, vnode_object));
407:
408: vnode_pager_create( vp, vnode_object->pager_handle);
409: return(vnode_object->pager_handle);
410: }
411:
412: /*
413: *
414: */
415: ipc_port_t
416: vnode_pager_lookup(
417: vnode_port_t vp,
418: ipc_port_t pager)
419: {
420: vnode_pager_t vnode_object;
421: kern_return_t kr;
422:
423: if (pager &&
424: (vnode_object = vnode_port_hash_lookup(pager))) {
425: if (vnode_object->vnode_handle == vp)
426: return(vnode_object->vm_obj_handle);
427: else
428: return NULL;
429: }
430: else
431: return NULL;
432: }
433:
434: /*
435: *
436: */
437: kern_return_t
438: vnode_pager_init(ipc_port_t pager,
439: ipc_port_t pager_request,
440: vm_size_t pg_size)
441: {
442: vnode_pager_t vnode_object;
443: kern_return_t kr;
444: memory_object_attr_info_data_t attributes;
445: vm_object_t vm_object;
446:
447:
448: PAGER_DEBUG(PAGER_ALL, ("vnode_pager_init: %x, %x, %x\n", pager, pager_request, pg_size));
449:
450: vnode_object = vnode_port_hash_lookup(pager);
451: if (vnode_object == VNODE_PAGER_NULL)
452: panic("vnode_pager_init: lookup failed");
453:
454: vnode_object->vm_obj_handle = pager_request;
455:
456: vm_object = vm_object_lookup(pager_request);
457:
458: if (vm_object == VM_OBJECT_NULL)
459: panic("vnode_pager_init: vm_object_lookup() failed");
460:
461: attributes.copy_strategy = MEMORY_OBJECT_COPY_DELAY;
462: attributes.cluster_size = (1 << (CLUSTER_SHIFT + PAGE_SHIFT));
463: attributes.may_cache_object = TRUE;
464: attributes.temporary = TRUE;
465:
466: kr = memory_object_change_attributes(
467: vm_object,
468: MEMORY_OBJECT_ATTRIBUTE_INFO,
469: (memory_object_info_t) &attributes,
470: MEMORY_OBJECT_ATTR_INFO_COUNT,
471: MACH_PORT_NULL, 0);
472: if (kr != KERN_SUCCESS)
473: panic("vnode_pager_init: memory_object_change_attributes() failed");
474:
475: return(KERN_SUCCESS);
476: }
477:
478: /*
479: *
480: */
481: kern_return_t
482: vnode_pager_data_return(
483: ipc_port_t mem_obj,
484: ipc_port_t control_port,
485: vm_offset_t offset,
486: pointer_t addr,
487: vm_size_t data_cnt,
488: boolean_t dirty,
489: boolean_t kernel_copy)
490: {
491: register vnode_pager_t vnode_object;
492:
493: vnode_object = vnode_port_hash_lookup(mem_obj);
494: if (vnode_object == VNODE_PAGER_NULL)
495: panic("vnode_pager_data_return: lookup failed");
496:
497: vnode_pager_cluster_write(vnode_object, offset, data_cnt, (vm_object_t)control_port->ip_kobject);
498:
499: return KERN_SUCCESS;
500: }
501:
502: /*
503: *
504: */
505: kern_return_t
506: vnode_pager_data_request(
507: ipc_port_t mem_obj,
508: ipc_port_t mem_obj_control,
509: vm_offset_t offset,
510: vm_size_t length,
511: vm_prot_t protection_required)
512: {
513: register vnode_pager_t vnode_object;
514:
515: PAGER_DEBUG(PAGER_ALL, ("vnode_pager_data_request: %x, %x, %x, %x, %x\n", mem_obj, mem_obj_control, offset, length, protection_required));
516:
517: vnode_object = vnode_port_hash_lookup(mem_obj);
518:
519: PAGER_DEBUG(PAGER_PAGEIN, ("vnode_pager_data_request: %x, %x, %x, %x, %x, vnode_object %x\n", mem_obj, mem_obj_control, offset, length, protection_required, vnode_object));
520:
521: if (vnode_object == VNODE_PAGER_NULL)
522: panic("vnode_pager_data_request: lookup failed");
523:
524: vnode_pager_cluster_read(vnode_object, offset, length, (vm_object_t)mem_obj_control->ip_kobject);
525:
526: return KERN_SUCCESS;
527: }
528:
529: /*
530: *
531: */
532: void
533: vnode_pager_no_senders(
534: ipc_port_t mem_obj,
535: mach_port_mscount_t mscount)
536: {
537: register vnode_pager_t vnode_object;
538: boolean_t funnel_state;
539:
540: PAGER_DEBUG(PAGER_ALL, ("vnode_pager_nosenders: %x, %x\n", mem_obj, mscount));
541:
542: vnode_object = vnode_port_hash_lookup(mem_obj);
543: if (vnode_object == VNODE_PAGER_NULL)
544: panic("vnode_pager_no_senders: lookup failed");
545:
546: assert(vnode_object->pager_handle == mem_obj);
547:
548: pager_mux_hash_delete((ipc_port_t) vnode_object->pager_handle);
549: ipc_port_dealloc_kernel(vnode_object->pager);
550: vnode_port_hash_delete(vnode_object->pager_handle);
551: if (vnode_object->vnode_handle != (vnode_port_t) NULL) {
552: funnel_state = thread_set_funneled(TRUE);
553: vrele(vnode_object->vnode_handle);
554: (void) thread_set_funneled(funnel_state);
555: }
556: zfree(vnode_pager_zone, (vm_offset_t) vnode_object);
557:
558: return;
559: }
560:
561: /*
562: *
563: */
564: kern_return_t
565: vnode_pager_terminate(
566: ipc_port_t mem_obj,
567: ipc_port_t mem_obj_control)
568: {
569: register vnode_pager_t vnode_object;
570:
571: PAGER_DEBUG(PAGER_ALL, ("vnode_pager_terminate: %x, %x\n", mem_obj, mem_obj_control));
572:
573: vnode_object = vnode_port_hash_lookup(mem_obj);
574: if (vnode_object == VNODE_PAGER_NULL)
575: panic("vnode_pager_terminate: lookup failed");
576:
577: assert(vnode_object->pager_handle == mem_obj);
578:
579: /* release extra send right created by the fact that the caller */
580: /* of vnode_pager_setup does not establish a mapping between a */
581: /* cache object and the mem_obj (AMO). When a subsequent vm_map */
582: /* is done, vm_map will bump the send right count */
583: ipc_port_release_send(mem_obj);
584:
585: /* release a send right because terminate is called directly and */
586: /* not through IPC, the right won't disappear quietly */
587: ipc_port_release_send(mem_obj);
588:
589: ipc_port_dealloc_kernel(mem_obj_control);
590:
591: return(KERN_SUCCESS);
592: }
593:
594: /*
595: *
596: */
597: kern_return_t
598: vnode_pager_synchronize(
599: ipc_port_t pager,
600: ipc_port_t pager_request,
601: vm_offset_t offset,
602: vm_offset_t length,
603: vm_sync_t sync_flags)
604: {
605: memory_object_synchronize_completed(vm_object_lookup(pager_request), offset, length);
606:
607: return (KERN_SUCCESS);
608: }
609:
610: /*
611: *
612: */
613: void
614: vnode_pager_cluster_write(
615: vnode_pager_t vnode_object,
616: vm_offset_t offset,
617: vm_size_t cnt,
618: vm_object_t object)
619: {
620: vm_offset_t data;
621: upl_t page_list;
622: int error = 0;
623: int size;
624:
625: upl_system_list_request(object, offset,
626: cnt, cnt, &page_list, NULL, 0,
627: (UPL_CLEAN_IN_PLACE | UPL_NO_SYNC | UPL_COPYOUT_FROM));
628: upl_map(kernel_map, page_list, &data);
629:
630: error = vnode_pageout(
631: vnode_object->vnode_handle, data, offset, cnt, NULL);
632:
633: upl_un_map(kernel_map, page_list);
634: if (error == 0) {
635: upl_commit(page_list, NULL);
636: } else {
637: upl_abort(page_list, 0);
638: }
639:
640: return;
641: }
642:
643:
644: /*
645: *
646: */
647: kern_return_t
648: vnode_pager_cluster_read(
649: vnode_pager_t vnode_object,
650: vm_offset_t offset,
651: vm_size_t cnt,
652: vm_object_t object)
653: {
654: vm_offset_t buffer;
655: int error = 0;
656: int local_error = 0;
657: int kret;
658: int size;
659: upl_t page_list;
660: vm_offset_t base, orig_offset;
661: kern_return_t kr;
662:
663: size = PAGE_SIZE;
664: orig_offset = offset;
665: base = offset;
666:
667: kr = upl_system_list_request(object, offset,
668: cnt, cnt, &page_list, NULL, 0,
669: UPL_CLEAN_IN_PLACE | UPL_NO_SYNC);
670: if(kr != KERN_SUCCESS) {
671: panic("VNODE_PAGER_CLUSTER_READ: upl_system_list_request failed");
672: }
673: kr = upl_map(kernel_map, page_list, &buffer);
674: if(kr != KERN_SUCCESS) {
675: upl_abort(page_list, UPL_ABORT_RESTART);
676: return KERN_SUCCESS;
677: }
678:
679: while (cnt) {
680:
681: kret = vnode_pagein(vnode_object->vnode_handle, buffer, offset, size, &local_error);
682:
683: PAGER_DEBUG(PAGER_PAGEIN, ("vnode_pagein ret: vp %x, buf %x buf[0] %x\n", vnode_object->vnode_handle, buffer, *((int *)buffer)));
684:
685: if (local_error != 0) {
686: error = local_error;
687: local_error = 0;
688: if(offset > base) {
689: upl_un_map(kernel_map, page_list);
690: upl_commit_range(page_list, base - orig_offset,
691: offset - base, FALSE, NULL);
692: upl_map(kernel_map, page_list, &buffer);
693: }
694: base = offset+size;
695: }
696:
697: cnt -= size;
698: offset += size;
699: }
700:
701: if(error != 0) {
702: upl_un_map(kernel_map, page_list);
703: if(offset > base) {
704: upl_commit_range(page_list, base - orig_offset,
705: offset - base, FALSE, NULL);
706: }
707: upl_abort(page_list, UPL_ABORT_ERROR);
708: return(KERN_FAILURE);
709: }
710: upl_un_map(kernel_map, page_list);
711: upl_commit(page_list, NULL);
712:
713: return(KERN_SUCCESS);
714: }
715:
716:
717: /*
718: *
719: */
720: void
721: vnode_pager_release_from_cache(
722: int *cnt)
723: {
724: memory_object_free_from_cache(
725: &realhost, (int)&vnode_pager_workaround, cnt);
726: }
727:
728: /*
729: *
730: */
731: vnode_pager_t
732: vnode_object_create(
733: vnode_port_t vp)
734: {
735: register vnode_pager_t vnode_object;
736:
737: vnode_object = (struct vnode_pager *) zalloc(vnode_pager_zone);
738: if (vnode_object == VNODE_PAGER_NULL)
739: return(VNODE_PAGER_NULL);
740: vnode_object->pager_handle = IP_NULL;
741: vnode_object->vm_obj_handle = IP_NULL;
742: vnode_object->vnode_handle = vp;
743:
744: return(vnode_object);
745: }
746:
747: /*
748: *
749: */
750: void
751: vnode_port_hash_init(void)
752: {
753: register vm_size_t size;
754: register int i;
755:
756:
757: size = (vm_size_t) sizeof(struct vnode_port_entry);
758:
759: vnode_port_hash_zone = zinit(size,
760: (vm_size_t) MAX_VNODE * size,
761: PAGE_SIZE, "vnode_pager port hash");
762:
763: for (i = 0; i < VNODE_PORT_HASH_COUNT; i++)
764: queue_init(&vnode_port_hashtable[i]);
765:
766: simple_lock_init(&vnode_port_hash_lock,ETAP_NO_TRACE);
767: }
768:
769: /*
770: *
771: */
772: void
773: vnode_port_hash_insert(
774: ipc_port_t name_port,
775: vnode_pager_t rec)
776: {
777: register vnode_port_entry_t new_entry;
778:
779: new_entry = (vnode_port_entry_t) zalloc(vnode_port_hash_zone);
780: /*
781: * TODO: Delete the following check once MAX_VNODE is removed
782: */
783: if (!new_entry)
784: panic("vnode_port_hash_insert: no space");
785: new_entry->name = name_port;
786: new_entry->pager_rec = rec;
787:
788: simple_lock(&vnode_port_hash_lock);
789: queue_enter(&vnode_port_hashtable[vnode_port_hash(name_port)],
790: new_entry, vnode_port_entry_t, links);
791: simple_unlock(&vnode_port_hash_lock);
792: }
793:
794: /*
795: *
796: */
797: vnode_pager_t
798: vnode_port_hash_lookup(
799: ipc_port_t name_port)
800: {
801: register queue_t bucket;
802: register vnode_port_entry_t entry;
803: vnode_pager_t rec;
804:
805: bucket = (queue_t) &vnode_port_hashtable[vnode_port_hash(name_port)];
806:
807: simple_lock(&vnode_port_hash_lock);
808: entry = (vnode_port_entry_t) queue_first(bucket);
809: while (!queue_end(bucket,&entry->links)) {
810: if (entry->name == name_port) {
811: rec = entry->pager_rec;
812: simple_unlock(&vnode_port_hash_lock);
813: return(rec);
814: }
815: entry = (vnode_port_entry_t)queue_next(&entry->links);
816: }
817: simple_unlock(&vnode_port_hash_lock);
818: return(VNODE_PAGER_NULL);
819: }
820:
821: /*
822: *
823: */
824: void
825: vnode_port_hash_delete(
826: ipc_port_t name_port)
827: {
828: register queue_t bucket;
829: register vnode_port_entry_t entry;
830:
831: bucket = (queue_t) &vnode_port_hashtable[vnode_port_hash(name_port)];
832:
833: simple_lock(&vnode_port_hash_lock);
834: entry = (vnode_port_entry_t) queue_first(bucket);
835: while (!queue_end(bucket,&entry->links)) {
836: if (entry->name == name_port) {
837: queue_remove(bucket, entry, vnode_port_entry_t,links);
838: simple_unlock(&vnode_port_hash_lock);
839: zfree(vnode_port_hash_zone, (vm_offset_t) entry);
840: return;
841: }
842: entry = (vnode_port_entry_t)queue_next(&entry->links);
843: }
844: simple_unlock(&vnode_port_hash_lock);
845: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.