]> git.saurik.com Git - apple/xnu.git/commitdiff
xnu-1228.5.18.tar.gz mac-os-x-1053 v1228.5.18
authorApple <opensource@apple.com>
Fri, 30 May 2008 18:38:01 +0000 (18:38 +0000)
committerApple <opensource@apple.com>
Fri, 30 May 2008 18:38:01 +0000 (18:38 +0000)
105 files changed:
bsd/dev/dtrace/dtrace.c
bsd/dev/dtrace/systrace.c
bsd/dev/i386/fasttrap_isa.c
bsd/dev/ppc/fasttrap_isa.c
bsd/hfs/hfs_catalog.c
bsd/hfs/hfs_cnode.c
bsd/hfs/hfs_endian.c
bsd/hfs/hfs_readwrite.c
bsd/hfs/hfs_vfsops.c
bsd/hfs/hfs_vnops.c
bsd/hfs/hfscommon/Misc/FileExtentMapping.c
bsd/i386/_param.h
bsd/kern/bsd_init.c
bsd/kern/imageboot.c
bsd/kern/kern_descrip.c
bsd/kern/kern_proc.c
bsd/kern/sysv_sem.c
bsd/kern/ubc_subr.c
bsd/net/if.c
bsd/netinet/tcp_input.c
bsd/netinet/tcp_output.c
bsd/netinet/tcp_subr.c
bsd/netinet/tcp_timer.c
bsd/netinet6/icmp6.c
bsd/netinet6/ipcomp_input.c
bsd/nfs/nfs_socket.c
bsd/nfs/nfs_vfsops.c
bsd/ppc/_param.h
bsd/sys/socket.h
bsd/sys/ubc_internal.h
bsd/uxkern/ux_exception.c
bsd/vfs/kpi_vfs.c
bsd/vfs/vfs_cluster.c
bsd/vfs/vfs_fsevents.c
bsd/vfs/vfs_fslog.c
bsd/vfs/vfs_journal.c
bsd/vfs/vfs_subr.c
bsd/vfs/vfs_syscalls.c
bsd/vfs/vfs_vnops.c
bsd/vfs/vfs_xattr.c
bsd/vm/vm_unix.c
bsd/vm/vnode_pager.c
config/MasterVersion
iokit/IOKit/IODMACommand.h
iokit/IOKit/IODMAController.h
iokit/IOKit/IODMAEventSource.h
iokit/IOKit/IONVRAM.h
iokit/IOKit/pwr_mgt/IOPM.h
iokit/Kernel/IOCPU.cpp
iokit/Kernel/IOInterruptController.cpp
iokit/Kernel/IOMemoryDescriptor.cpp
iokit/Kernel/IONVRAM.cpp
iokit/Kernel/IOServicePM.cpp
iokit/Kernel/IOServicePMPrivate.h
iokit/bsddev/IOKitBSDInit.cpp
libsa/catalogue.cpp
makedefs/MakeInc.def
osfmk/console/panic_dialog.c
osfmk/ddb/db_expr.c
osfmk/i386/cpu_threads.c
osfmk/i386/cpu_threads.h
osfmk/i386/hpet.c
osfmk/i386/locore.s
osfmk/i386/machine_check.c
osfmk/i386/machine_routines_asm.s
osfmk/i386/seg.h
osfmk/ipc/ipc_mqueue.h
osfmk/kdp/kdp_internal.h
osfmk/kdp/kdp_udp.c
osfmk/kdp/ml/i386/kdp_machdep.c
osfmk/kern/ast.c
osfmk/kern/kern_types.h
osfmk/kern/kmod.c
osfmk/kern/machine.c
osfmk/kern/printf.c
osfmk/kern/priority.c
osfmk/kern/processor.c
osfmk/kern/processor.h
osfmk/kern/sched_prim.c
osfmk/kern/sync_lock.c
osfmk/kern/sync_sema.c
osfmk/kern/task.c
osfmk/kern/task.h
osfmk/kern/xpr.c
osfmk/mach/memory_object_types.h
osfmk/ppc/pmap.c
osfmk/ppc/ppc_init.c
osfmk/ppc/ppc_vm_init.c
osfmk/ppc/savearea.c
osfmk/vm/vm_fault.c
osfmk/vm/vm_object.c
osfmk/vm/vm_page.h
osfmk/vm/vm_pageout.c
osfmk/vm/vm_purgeable.c
osfmk/vm/vm_purgeable_internal.h
osfmk/vm/vm_resident.c
pexpert/gen/bootargs.c
tools/tests/xnu_quick_test/helpers/arch.c
tools/tests/xnu_quick_test/main.c
tools/tests/xnu_quick_test/makefile
tools/tests/xnu_quick_test/misc.c
tools/tests/xnu_quick_test/sema_tests.c
tools/tests/xnu_quick_test/shared_memory_tests.c
tools/tests/xnu_quick_test/tests.c
tools/tests/xnu_quick_test/tests.h

index 9f2be77c494a6360cefa708cdfb580443dc20136..aa200c11f8a52c3e4a2942aeb2a6a6b6094b1c81 100644 (file)
@@ -1003,6 +1003,11 @@ dtrace_priv_proc_destructive(dtrace_state_t *state)
 {
        int action = state->dts_cred.dcr_action;
 
+#if defined(__APPLE__)
+       if (ISSET(current_proc()->p_lflag, P_LNOATTACH))
+               goto bad;
+#endif /* __APPLE__ */
+
        if (((action & DTRACE_CRA_PROC_DESTRUCTIVE_ALLZONE) == 0) &&
            dtrace_priv_proc_common_zone(state) == 0)
                goto bad;
@@ -1026,6 +1031,11 @@ bad:
 static int
 dtrace_priv_proc_control(dtrace_state_t *state)
 {
+#if defined(__APPLE__)
+       if (ISSET(current_proc()->p_lflag, P_LNOATTACH))
+               goto bad;
+#endif /* __APPLE__ */
+
        if (state->dts_cred.dcr_action & DTRACE_CRA_PROC_CONTROL)
                return (1);
 
@@ -1034,6 +1044,9 @@ dtrace_priv_proc_control(dtrace_state_t *state)
            dtrace_priv_proc_common_nocd())
                return (1);
 
+#if defined(__APPLE__)
+bad:
+#endif /* __APPLE__ */
        cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV;
 
        return (0);
@@ -1042,9 +1055,17 @@ dtrace_priv_proc_control(dtrace_state_t *state)
 static int
 dtrace_priv_proc(dtrace_state_t *state)
 {
+#if defined(__APPLE__)
+       if (ISSET(current_proc()->p_lflag, P_LNOATTACH))
+               goto bad;
+#endif /* __APPLE__ */
+
        if (state->dts_cred.dcr_action & DTRACE_CRA_PROC)
                return (1);
 
+#if defined(__APPLE__)
+bad:
+#endif /* __APPLE__ */
        cpu_core[CPU->cpu_id].cpuc_dtrace_flags |= CPU_DTRACE_UPRIV;
 
        return (0);
@@ -3040,7 +3061,12 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
 
                if (subr == DIF_SUBR_COPYIN) {
                        DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
+#if !defined(__APPLE__)
                        dtrace_copyin(tupregs[0].dttk_value, dest, size);
+#else
+                       if (dtrace_priv_proc(state))
+                               dtrace_copyin(tupregs[0].dttk_value, dest, size);
+#endif /* __APPLE__ */
                        DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
                }
 
@@ -3065,7 +3091,12 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
                }
 
                DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
+#if !defined(__APPLE__)
                dtrace_copyin(tupregs[0].dttk_value, dest, size);
+#else
+               if (dtrace_priv_proc(state))
+                       dtrace_copyin(tupregs[0].dttk_value, dest, size);
+#endif /* __APPLE__ */
                DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
                break;
        }
@@ -3090,7 +3121,12 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
                }
 
                DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
+#if !defined(__APPLE__)
                dtrace_copyinstr(tupregs[0].dttk_value, dest, size);
+#else
+               if (dtrace_priv_proc(state))
+                       dtrace_copyinstr(tupregs[0].dttk_value, dest, size);
+#endif /* __APPLE__ */
                DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
 
                ((char *)dest)[size - 1] = '\0';
@@ -5295,6 +5331,31 @@ __dtrace_probe(dtrace_id_t id, uint64_t arg0, uint64_t arg1,
        now = dtrace_gethrtime(); /* must not precede dtrace_calc_thread_recent_vtime() call! */
 #endif /* __APPLE__ */
 
+#if defined(__APPLE__)
+       /*
+        * A provider may call dtrace_probe_error() in lieu of dtrace_probe() in some circumstances.
+        * See, e.g. fasttrap_isa.c. However the provider has no access to ECB context, so passes
+        * NULL through "arg0" and the probe_id of the ovedrriden probe as arg1. Detect that here
+        * and cons up a viable state (from the probe_id).
+        */
+       if (dtrace_probeid_error == id && NULL == arg0) {
+               dtrace_id_t ftp_id = (dtrace_id_t)arg1;
+               dtrace_probe_t *ftp_probe = dtrace_probes[ftp_id - 1];
+               dtrace_ecb_t *ftp_ecb = ftp_probe->dtpr_ecb;
+
+               if (NULL != ftp_ecb) {
+                       dtrace_state_t *ftp_state = ftp_ecb->dte_state;
+
+                       arg0 = (uint64_t)(uintptr_t)ftp_state;
+                       arg1 = ftp_ecb->dte_epid;
+                       /*
+                        * args[2-4] established by caller.
+                        */
+                       ftp_state->dts_arg_error_illval = -1; /* arg5 */
+               }
+       }
+#endif /* __APPLE__ */
+
        mstate.dtms_probe = probe;
        mstate.dtms_arg[0] = arg0;
        mstate.dtms_arg[1] = arg1;
@@ -5368,16 +5429,6 @@ __dtrace_probe(dtrace_id_t id, uint64_t arg0, uint64_t arg1,
                        }
                }
 
-#if defined(__APPLE__)
-        /*
-         * If the thread on which this probe has fired belongs to a process marked P_LNOATTACH
-         * then this enabling is not permitted to observe it. Move along, nothing to see here.
-         */
-        if (ISSET(current_proc()->p_lflag, P_LNOATTACH)) {
-            continue;
-        }
-#endif /* __APPLE__ */
-
                if (ecb->dte_cond) {
                        /*
                         * If the dte_cond bits indicate that this
index ad19d6df010953d83378f321413254283ad04343..35601e943fec93c912b68554450657e5e7abda5f 100644 (file)
@@ -856,7 +856,7 @@ dtrace_machtrace_syscall(struct mach_call_args *args)
                x86_saved_state_t   *tagged_regs = (x86_saved_state_t *)find_user_regs(current_thread());
 
                if (is_saved_state64(tagged_regs)) {
-                       code = -saved_state64(tagged_regs)->rax & SYSCALL_NUMBER_MASK;
+                       code = saved_state64(tagged_regs)->rax & SYSCALL_NUMBER_MASK;
                } else {
                        code = -saved_state32(tagged_regs)->eax;
                }
index 478429efc051e99ffe90545a64cc034a4a1ca8f0..c96666b0b93db3dbfe6f12fdc93a5940f513f1d1 100644 (file)
@@ -38,6 +38,7 @@
 #include <sys/fasttrap_impl.h>
 #include <sys/dtrace.h>
 #include <sys/dtrace_impl.h>
+extern dtrace_id_t dtrace_probeid_error;
 
 #include "fasttrap_regset.h"
 
@@ -717,7 +718,10 @@ fasttrap_return_common(x86_saved_state_t *regs, user_addr_t pc, pid_t pid,
                    id->fti_probe->ftp_fsize)
                        continue;
 
-               if (p_model == DATAMODEL_LP64) {
+               if (ISSET(current_proc()->p_lflag, P_LNOATTACH)) {
+                       dtrace_probe(dtrace_probeid_error, 0 /* state */, id->fti_probe->ftp_id, 
+                                    1 /* ndx */, -1 /* offset */, DTRACEFLT_UPRIV);
+               } else if (p_model == DATAMODEL_LP64) {
                        dtrace_probe(id->fti_probe->ftp_id,
                                     pc - id->fti_probe->ftp_faddr,
                                     regs64->rax, regs64->rdx, 0, 0);
@@ -1028,7 +1032,10 @@ fasttrap_pid_probe32(x86_saved_state_t *regs)
                for (id = tp->ftt_ids; id != NULL; id = id->fti_next) {
                        fasttrap_probe_t *probe = id->fti_probe;
                        
-                       if (id->fti_ptype == DTFTP_ENTRY) {
+                       if (ISSET(current_proc()->p_lflag, P_LNOATTACH)) {
+                               dtrace_probe(dtrace_probeid_error, 0 /* state */, probe->ftp_id, 
+                                            1 /* ndx */, -1 /* offset */, DTRACEFLT_UPRIV);
+                       } else if (id->fti_ptype == DTFTP_ENTRY) {
                                /*
                                 * We note that this was an entry
                                 * probe to help ustack() find the
@@ -1564,7 +1571,10 @@ fasttrap_pid_probe64(x86_saved_state_t *regs)
                for (id = tp->ftt_ids; id != NULL; id = id->fti_next) {
                        fasttrap_probe_t *probe = id->fti_probe;
                        
-                       if (id->fti_ptype == DTFTP_ENTRY) {
+                       if (ISSET(current_proc()->p_lflag, P_LNOATTACH)) {
+                               dtrace_probe(dtrace_probeid_error, 0 /* state */, probe->ftp_id, 
+                                            1 /* ndx */, -1 /* offset */, DTRACEFLT_UPRIV);
+                       } else if (id->fti_ptype == DTFTP_ENTRY) {
                                /*
                                 * We note that this was an entry
                                 * probe to help ustack() find the
index 33b7ff4d4a7bb6c08ead10ac38ad5f567134bb1e..70cfbe00ea8f76933f693f981d345fcae7d033d8 100644 (file)
@@ -76,6 +76,7 @@
 #include <mach/task.h>
 #include <vm/pmap.h>
 #include <vm/vm_map.h> /* All the bits we care about are guarded by MACH_KERNEL_PRIVATE :-( */
+extern dtrace_id_t dtrace_probeid_error;
 
 #define proc_t struct proc
 
@@ -358,9 +359,15 @@ fasttrap_return_common(ppc_saved_state_t *sv, user_addr_t pc, pid_t pid, user_ad
                        continue;                                                       /* Yeah, skip this one... */
 
                DTRACE_CPUFLAG_SET(CPU_DTRACE_USTACK_FP);
-               dtrace_probe(id->fti_probe->ftp_id,
-                       pc - id->fti_probe->ftp_faddr,
-                       sv->save_r3, sv->save_r4, 0, 0);
+               if (ISSET(current_proc()->p_lflag, P_LNOATTACH)) {
+                       dtrace_probe(dtrace_probeid_error, 0 /* state */, 
+                                    id->fti_probe->ftp_id, 1 /* ndx */, -1 /* offset */, 
+                                    DTRACEFLT_UPRIV);
+               } else {
+                       dtrace_probe(id->fti_probe->ftp_id,
+                               pc - id->fti_probe->ftp_faddr,
+                               sv->save_r3, sv->save_r4, 0, 0);
+               }
                DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_USTACK_FP);
        }
 
@@ -461,7 +468,11 @@ fasttrap_pid_probe(ppc_saved_state_t *sv)
                for (id = tp->ftt_ids; id != NULL; id = id->fti_next) {
                        fasttrap_probe_t *probe = id->fti_probe;
                        
-                       if (id->fti_ptype == DTFTP_ENTRY) {
+                       if (ISSET(current_proc()->p_lflag, P_LNOATTACH)) {
+                               dtrace_probe(dtrace_probeid_error, 0 /* state */, 
+                                    id->fti_probe->ftp_id, 1 /* ndx */, -1 /* offset */, 
+                                    DTRACEFLT_UPRIV);
+                       } else if (id->fti_ptype == DTFTP_ENTRY) {
                                /*
                                 * We note that this was an entry
                                 * probe to help ustack() find the
index b52a0cd22f30dc3c74cfa9c21ad30b28fa23b541..59d20b4efe1e92ea40b23d352900c266ad489edd 100644 (file)
@@ -2627,7 +2627,7 @@ getdirentries_callback(const CatalogKey *ckp, const CatalogRecord *crp,
        u_int8_t type = DT_UNKNOWN;
        u_int8_t is_mangled = 0;
        u_int8_t *nameptr;
-       user_addr_t uiobase = (user_addr_t)NULL;
+       user_addr_t uiobase = USER_ADDR_NULL;
        size_t namelen = 0;
        size_t maxnamelen;
        size_t uiosize = 0;
index c09c058c66cb525e18eb1a882ba198d59165c90e..17a0cba633470ccff9c56cc72a080091f1fd7f07 100644 (file)
@@ -105,14 +105,6 @@ hfs_vnop_inactive(struct vnop_inactive_args *ap)
 
        (void) hfs_lock(cp, HFS_FORCE_LOCK);
 
-       /*
-        * Recycle named streams quickly so that the data fork vnode can
-        * go inactive in a timely manner (so that it can be zero filled
-        * or truncated if needed).
-        */
-       if (vnode_isnamedstream(vp))
-               recycle = 1;
-
        /*
         * We should lock cnode before checking the flags in the 
         * condition below and should unlock the cnode before calling 
@@ -288,7 +280,9 @@ hfs_vnop_inactive(struct vnop_inactive_args *ap)
         */
        if ((cp->c_flag & C_MODIFIED) ||
            cp->c_touch_acctime || cp->c_touch_chgtime || cp->c_touch_modtime) {
-               cp->c_flag |= C_FORCEUPDATE;
+               if ((cp->c_flag & C_MODIFIED) || cp->c_touch_modtime){
+                       cp->c_flag |= C_FORCEUPDATE;
+               }
                hfs_update(vp, 0);
        }
 out:
@@ -429,8 +423,10 @@ hfs_vnop_reclaim(struct vnop_reclaim_args *ap)
         * force the update, or hfs_update will again skip the cat_update.
         */
        if ((cp->c_flag & C_MODIFIED) ||
-           cp->c_touch_acctime || cp->c_touch_chgtime || cp->c_touch_modtime) {
-               cp->c_flag |= C_FORCEUPDATE;
+               cp->c_touch_acctime || cp->c_touch_chgtime || cp->c_touch_modtime) {
+               if ((cp->c_flag & C_MODIFIED) || cp->c_touch_modtime){
+                       cp->c_flag |= C_FORCEUPDATE;
+               }       
                hfs_update(vp, 0);
        }
 
@@ -774,11 +770,14 @@ hfs_getnewvnode(
                 * occurred during the attachment, then cleanup the cnode.
                 */
                if ((cp->c_vp == NULL) && (cp->c_rsrc_vp == NULL)) {
-                       hfs_chash_abort(cp);
+                       hfs_chash_abort(cp);
                        hfs_reclaim_cnode(cp);
-               } else {
-                       hfs_chashwakeup(cp, H_ALLOC | H_ATTACH);
-                       hfs_unlock(cp);
+               } 
+               else {
+                       hfs_chashwakeup(cp, H_ALLOC | H_ATTACH);
+                       if ((flags & GNV_SKIPLOCK) == 0){
+                               hfs_unlock(cp);
+                       }
                }
                *vpp = NULL;
                return (retval);
index 692b598a99789f2b6f17b812787d949312d82622..41251934fce9c1e556e4f4ecd250f7c11cee2577 100644 (file)
@@ -248,15 +248,15 @@ hfs_swap_BTNode (
      */
     if (direction == kSwapBTNodeHostToBig) {
                /*
-                * Sanity check and swap the forkward and backward links.
+                * Sanity check and swap the forward and backward links.
                 */
                if (srcDesc->fLink >= btcb->totalNodes) {
-                       printf("hfs_UNswap_BTNode: invalid forward link (0x%08X)\n", srcDesc->fLink);
+                       panic("hfs_UNswap_BTNode: invalid forward link (0x%08X)\n", srcDesc->fLink);
                        error = fsBTInvalidHeaderErr;
                        goto fail;
                }
                if (srcDesc->bLink >= btcb->totalNodes) {
-                       printf("hfs_UNswap_BTNode: invalid backward link (0x%08X)\n", srcDesc->bLink);
+                       panic("hfs_UNswap_BTNode: invalid backward link (0x%08X)\n", srcDesc->bLink);
                        error = fsBTInvalidHeaderErr;
                        goto fail;
                }
@@ -267,7 +267,7 @@ hfs_swap_BTNode (
                 * Check srcDesc->kind.  Don't swap it because it's only one byte.
                 */
                if (srcDesc->kind < kBTLeafNode || srcDesc->kind > kBTMapNode) {
-                       printf("hfs_UNswap_BTNode: invalid node kind (%d)\n", srcDesc->kind);
+                       panic("hfs_UNswap_BTNode: invalid node kind (%d)\n", srcDesc->kind);
                        error = fsBTInvalidHeaderErr;
                        goto fail;
                }
@@ -276,7 +276,7 @@ hfs_swap_BTNode (
                 * Check srcDesc->height.  Don't swap it because it's only one byte.
                 */
                if (srcDesc->height > btcb->treeDepth) {
-                       printf("hfs_UNswap_BTNode: invalid node height (%d)\n", srcDesc->height);
+                       panic("hfs_UNswap_BTNode: invalid node height (%d)\n", srcDesc->height);
                        error = fsBTInvalidHeaderErr;
                        goto fail;
                }
@@ -293,7 +293,7 @@ hfs_swap_BTNode (
          */
         if ((char *)srcOffs > ((char *)src->buffer + src->blockSize) ||
                (char *)srcOffs < ((char *)src->buffer + sizeof(BTNodeDescriptor))) {
-            printf("hfs_UNswap_BTNode: invalid record count (0x%04X)\n", srcDesc->numRecords);
+            panic("hfs_UNswap_BTNode: invalid record count (0x%04X)\n", srcDesc->numRecords);
             error = fsBTInvalidHeaderErr;
             goto fail;
         }
@@ -309,7 +309,7 @@ hfs_swap_BTNode (
              * This is why we allow the record offset to be zero.
              */
             if ((srcOffs[i] & 1) || (srcOffs[i] < sizeof(BTNodeDescriptor) && srcOffs[i] != 0) || (srcOffs[i] >= src->blockSize)) {
-               printf("hfs_UNswap_BTNode: record #%d invalid offset (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+               panic("hfs_UNswap_BTNode: record #%d invalid offset (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
                error = fsBTInvalidHeaderErr;
                goto fail;
             }
@@ -319,7 +319,7 @@ hfs_swap_BTNode (
              * them backwards, hence the order in the comparison.
              */
             if ((i < srcDesc->numRecords) && (srcOffs[i+1] >= srcOffs[i])) {
-               printf("hfs_UNswap_BTNode: offsets %d and %d out of order (0x%04X, 0x%04X)\n",
+               panic("hfs_UNswap_BTNode: offsets %d and %d out of order (0x%04X, 0x%04X)\n",
                    srcDesc->numRecords-i-2, srcDesc->numRecords-i-1, srcOffs[i+1], srcOffs[i]);
                error = fsBTInvalidHeaderErr;
                goto fail;
@@ -391,14 +391,22 @@ hfs_swap_HFSPlusBTInternalNode (
                         * below.
                         */
                        if ((char *)srcKey + sizeof(HFSPlusExtentKey) + recordSize > nextRecord) {
-                               printf("hfs_swap_HFSPlusBTInternalNode: extents key #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSPlusBTInternalNode: extents key #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               } else {
+                                       printf("hfs_swap_HFSPlusBTInternalNode: extents key #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               }
                                return fsBTInvalidNodeErr;
                        }
                        
             if (direction == kSwapBTNodeBigToHost) 
                srcKey->keyLength = SWAP_BE16 (srcKey->keyLength);
             if (srcKey->keyLength != sizeof(*srcKey) - sizeof(srcKey->keyLength)) {
-                               printf("hfs_swap_HFSPlusBTInternalNode: extents key #%d invalid length (%d)\n", srcDesc->numRecords-i-1, srcKey->keyLength);
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSPlusBTInternalNode: extents key #%d invalid length (%d)\n", srcDesc->numRecords-i-1, srcKey->keyLength);
+                               } else {
+                                       printf("hfs_swap_HFSPlusBTInternalNode: extents key #%d invalid length (%d)\n", srcDesc->numRecords-i-1, srcKey->keyLength);
+                               }
                                return fsBTInvalidNodeErr;
             }
             srcRec = (HFSPlusExtentDescriptor *)((char *)srcKey + srcKey->keyLength + sizeof(srcKey->keyLength));
@@ -440,9 +448,14 @@ hfs_swap_HFSPlusBTInternalNode (
                        nextRecord = (char *)src->buffer + srcOffs[i-1];
 
                        /*
-                        * Make sure we can safely dereference the keyLength and parentID fields. */
+                        * Make sure we can safely dereference the keyLength and parentID fields. 
+                        */
                        if ((char *)srcKey + offsetof(HFSPlusCatalogKey, nodeName.unicode[0]) > nextRecord) {
-                               printf("hfs_swap_HFSPlusBTInternalNode: catalog key #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSPlusBTInternalNode: catalog key #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               } else {
+                                       printf("hfs_swap_HFSPlusBTInternalNode: catalog key #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               }
                                return fsBTInvalidNodeErr;
                        }
 
@@ -457,7 +470,11 @@ hfs_swap_HFSPlusBTInternalNode (
             
             /* Sanity check the key length */
             if (keyLength < kHFSPlusCatalogKeyMinimumLength || keyLength > kHFSPlusCatalogKeyMaximumLength) {
-                               printf("hfs_swap_HFSPlusBTInternalNode: catalog key #%d invalid length (%d)\n", srcDesc->numRecords-i-1, keyLength);
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSPlusBTInternalNode: catalog key #%d invalid length (%d)\n", srcDesc->numRecords-i-1, keyLength);
+                               } else {
+                                       printf("hfs_swap_HFSPlusBTInternalNode: catalog key #%d invalid length (%d)\n", srcDesc->numRecords-i-1, keyLength);
+                               }
                                return fsBTInvalidNodeErr;
             }
 
@@ -467,7 +484,11 @@ hfs_swap_HFSPlusBTInternalNode (
              */
             srcPtr = (int16_t *)((char *)srcKey + keyLength + sizeof(srcKey->keyLength));
             if ((char *)srcPtr + sizeof(u_int32_t) > nextRecord) {
-                               printf("hfs_swap_HFSPlusBTInternalNode: catalog key #%d too big\n", srcDesc->numRecords-i-1);
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSPlusBTInternalNode: catalog key #%d too big\n", srcDesc->numRecords-i-1);
+                               } else {
+                                       printf("hfs_swap_HFSPlusBTInternalNode: catalog key #%d too big\n", srcDesc->numRecords-i-1);
+                               }
                                return fsBTInvalidNodeErr;
             }
 
@@ -481,9 +502,15 @@ hfs_swap_HFSPlusBTInternalNode (
             /* Make sure name length is consistent with key length */
             if (keyLength < sizeof(srcKey->parentID) + sizeof(srcKey->nodeName.length) +
                 srcKey->nodeName.length*sizeof(srcKey->nodeName.unicode[0])) {
-                               printf("hfs_swap_HFSPlusBTInternalNode: catalog record #%d keyLength=%d expected=%lu\n",
-                                       srcDesc->numRecords-i, keyLength, sizeof(srcKey->parentID) + sizeof(srcKey->nodeName.length) +
-                    srcKey->nodeName.length*sizeof(srcKey->nodeName.unicode[0]));
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSPlusBTInternalNode: catalog record #%d keyLength=%d expected=%lu\n",
+                                               srcDesc->numRecords-i, keyLength, sizeof(srcKey->parentID) + sizeof(srcKey->nodeName.length) +
+                       srcKey->nodeName.length*sizeof(srcKey->nodeName.unicode[0]));
+                               } else {
+                                       printf("hfs_swap_HFSPlusBTInternalNode: catalog record #%d keyLength=%d expected=%lu\n",
+                                               srcDesc->numRecords-i, keyLength, sizeof(srcKey->parentID) + sizeof(srcKey->nodeName.length) +
+                       srcKey->nodeName.length*sizeof(srcKey->nodeName.unicode[0]));
+                               }
                                return fsBTInvalidNodeErr;
             }
             for (j = 0; j < srcKey->nodeName.length; j++) {
@@ -508,7 +535,11 @@ hfs_swap_HFSPlusBTInternalNode (
             if (srcPtr[0] == kHFSPlusFolderRecord) {
                 HFSPlusCatalogFolder *srcRec = (HFSPlusCatalogFolder *)srcPtr;
                 if ((char *)srcRec + sizeof(*srcRec) > nextRecord) {
-                                       printf("hfs_swap_HFSPlusBTInternalNode: catalog folder record #%d too big\n", srcDesc->numRecords-i-1);
+                                       if (direction == kSwapBTNodeHostToBig) {
+                                               panic("hfs_swap_HFSPlusBTInternalNode: catalog folder record #%d too big\n", srcDesc->numRecords-i-1);
+                                       } else {
+                                               printf("hfs_swap_HFSPlusBTInternalNode: catalog folder record #%d too big\n", srcDesc->numRecords-i-1);
+                                       }
                                        return fsBTInvalidNodeErr;
                 }
 
@@ -539,7 +570,11 @@ hfs_swap_HFSPlusBTInternalNode (
             } else if (srcPtr[0] == kHFSPlusFileRecord) {
                 HFSPlusCatalogFile *srcRec = (HFSPlusCatalogFile *)srcPtr;
                 if ((char *)srcRec + sizeof(*srcRec) > nextRecord) {
-                                       printf("hfs_swap_HFSPlusBTInternalNode: catalog file record #%d too big\n", srcDesc->numRecords-i-1);
+                                       if (direction == kSwapBTNodeHostToBig) {
+                                               panic("hfs_swap_HFSPlusBTInternalNode: catalog file record #%d too big\n", srcDesc->numRecords-i-1);
+                                       } else {
+                                               printf("hfs_swap_HFSPlusBTInternalNode: catalog file record #%d too big\n", srcDesc->numRecords-i-1);
+                                       }
                                        return fsBTInvalidNodeErr;
                 }
                 
@@ -565,8 +600,8 @@ hfs_swap_HFSPlusBTInternalNode (
                 srcRec->textEncoding           = SWAP_BE32 (srcRec->textEncoding);
                        
                 /* If kHFSHasLinkChainBit is set, reserved1 is hl_FirstLinkID.  
-                * In all other context, it is expected to be zero.
-                */
+                                * In all other context, it is expected to be zero.
+                                */
                 srcRec->reserved1 = SWAP_BE32 (srcRec->reserved1);
 
                 /* Don't swap srcRec->userInfo */
@@ -584,7 +619,11 @@ hfs_swap_HFSPlusBTInternalNode (
                                 */
                 HFSPlusCatalogThread *srcRec = (HFSPlusCatalogThread *)srcPtr;
                                if ((char *) &srcRec->nodeName.unicode[0] > nextRecord) {
-                                       printf("hfs_swap_HFSPlusBTInternalNode: catalog thread record #%d too big\n", srcDesc->numRecords-i-1);
+                                       if (direction == kSwapBTNodeHostToBig) {
+                                               panic("hfs_swap_HFSPlusBTInternalNode: catalog thread record #%d too big\n", srcDesc->numRecords-i-1);
+                                       } else {
+                                               printf("hfs_swap_HFSPlusBTInternalNode: catalog thread record #%d too big\n", srcDesc->numRecords-i-1);
+                                       }
                                        return fsBTInvalidNodeErr;
                                }
 
@@ -600,7 +639,11 @@ hfs_swap_HFSPlusBTInternalNode (
                  * Then swap the characters of the name itself.
                  */
                                if ((char *) &srcRec->nodeName.unicode[srcRec->nodeName.length] > nextRecord) {
-                                       printf("hfs_swap_HFSPlusBTInternalNode: catalog thread record #%d name too big\n", srcDesc->numRecords-i-1);
+                                       if (direction == kSwapBTNodeHostToBig) {
+                                               panic("hfs_swap_HFSPlusBTInternalNode: catalog thread record #%d name too big\n", srcDesc->numRecords-i-1);
+                                       } else {
+                                               printf("hfs_swap_HFSPlusBTInternalNode: catalog thread record #%d name too big\n", srcDesc->numRecords-i-1);
+                                       }
                                        return fsBTInvalidNodeErr;
                                }
                 for (j = 0; j < srcRec->nodeName.length; j++) {
@@ -611,7 +654,11 @@ hfs_swap_HFSPlusBTInternalNode (
                        srcRec->nodeName.length = SWAP_BE16 (srcRec->nodeName.length);
 
             } else {
-               printf("hfs_swap_HFSPlusBTInternalNode: unrecognized catalog record type (0x%04X; record #%d)\n", srcPtr[0], srcDesc->numRecords-i-1);
+                               if (direction == kSwapBTNodeHostToBig) {
+                       panic("hfs_swap_HFSPlusBTInternalNode: unrecognized catalog record type (0x%04X; record #%d)\n", srcPtr[0], srcDesc->numRecords-i-1);
+                               } else {
+                       printf("hfs_swap_HFSPlusBTInternalNode: unrecognized catalog record type (0x%04X; record #%d)\n", srcPtr[0], srcDesc->numRecords-i-1);
+                               }
                                return fsBTInvalidNodeErr;
             }
     
@@ -639,7 +686,11 @@ hfs_swap_HFSPlusBTInternalNode (
 
                /* Make sure there is room in the buffer for a minimal key */
                if ((char *) &srcKey->attrName[1] > nextRecord) {
-                               printf("hfs_swap_HFSPlusBTInternalNode: attr key #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSPlusBTInternalNode: attr key #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               } else {
+                                       printf("hfs_swap_HFSPlusBTInternalNode: attr key #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               }
                                return fsBTInvalidNodeErr;
                }
                
@@ -656,7 +707,11 @@ hfs_swap_HFSPlusBTInternalNode (
              */
                srcRec = (HFSPlusAttrRecord *)((char *)srcKey + keyLength + sizeof(srcKey->keyLength));
                if ((char *)srcRec + sizeof(u_int32_t) > nextRecord) {
-                               printf("hfs_swap_HFSPlusBTInternalNode: attr key #%d too big (%d)\n", srcDesc->numRecords-i-1, keyLength);
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSPlusBTInternalNode: attr key #%d too big (%d)\n", srcDesc->numRecords-i-1, keyLength);
+                               } else {
+                                       printf("hfs_swap_HFSPlusBTInternalNode: attr key #%d too big (%d)\n", srcDesc->numRecords-i-1, keyLength);
+                               }
                                return fsBTInvalidNodeErr;
                }
                
@@ -670,7 +725,11 @@ hfs_swap_HFSPlusBTInternalNode (
                        srcKey->attrNameLen = SWAP_BE16(srcKey->attrNameLen);
                /* Sanity check the attribute name length */
                if (srcKey->attrNameLen > kHFSMaxAttrNameLen || keyLength < (kHFSPlusAttrKeyMinimumLength + sizeof(u_int16_t)*srcKey->attrNameLen)) {
-                               printf("hfs_swap_HFSPlusBTInternalNode: attr key #%d keyLength=%d attrNameLen=%d\n", srcDesc->numRecords-i-1, keyLength, srcKey->attrNameLen);
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSPlusBTInternalNode: attr key #%d keyLength=%d attrNameLen=%d\n", srcDesc->numRecords-i-1, keyLength, srcKey->attrNameLen);
+                               } else {
+                                       printf("hfs_swap_HFSPlusBTInternalNode: attr key #%d keyLength=%d attrNameLen=%d\n", srcDesc->numRecords-i-1, keyLength, srcKey->attrNameLen);
+                               }
                                return fsBTInvalidNodeErr;
                }
                for (j = 0; j < srcKey->attrNameLen; j++)
@@ -694,7 +753,11 @@ hfs_swap_HFSPlusBTInternalNode (
                case kHFSPlusAttrInlineData:
                        /* Is there room for the inline data header? */
                        if ((char *) &srcRec->attrData.attrData[0]  > nextRecord) {
-                                               printf("hfs_swap_HFSPlusBTInternalNode: attr inline #%d too big\n", srcDesc->numRecords-i-1);
+                                               if (direction == kSwapBTNodeHostToBig) {
+                                                       panic("hfs_swap_HFSPlusBTInternalNode: attr inline #%d too big\n", srcDesc->numRecords-i-1);
+                                               } else {
+                                                       printf("hfs_swap_HFSPlusBTInternalNode: attr inline #%d too big\n", srcDesc->numRecords-i-1);
+                                               }
                                                return fsBTInvalidNodeErr;
                        }
                        
@@ -709,7 +772,11 @@ hfs_swap_HFSPlusBTInternalNode (
                                
                        /* Is there room for the inline attribute data? */
                        if ((char *) &srcRec->attrData.attrData[attrSize] > nextRecord) {
-                                               printf("hfs_swap_HFSPlusBTInternalNode: attr inline #%d too big (attrSize=%u)\n", srcDesc->numRecords-i-1, attrSize);
+                                               if (direction == kSwapBTNodeHostToBig) {
+                                                       panic("hfs_swap_HFSPlusBTInternalNode: attr inline #%d too big (attrSize=%u)\n", srcDesc->numRecords-i-1, attrSize);
+                                               } else {
+                                                       printf("hfs_swap_HFSPlusBTInternalNode: attr inline #%d too big (attrSize=%u)\n", srcDesc->numRecords-i-1, attrSize);
+                                               }
                                                return fsBTInvalidNodeErr;
                        }
                        
@@ -719,7 +786,11 @@ hfs_swap_HFSPlusBTInternalNode (
                case kHFSPlusAttrForkData:
                        /* Is there room for the fork data record? */
                        if ((char *)srcRec + sizeof(HFSPlusAttrForkData) > nextRecord) {
-                                               printf("hfs_swap_HFSPlusBTInternalNode: attr fork data #%d too big\n", srcDesc->numRecords-i-1);
+                                               if (direction == kSwapBTNodeHostToBig) {
+                                                       panic("hfs_swap_HFSPlusBTInternalNode: attr fork data #%d too big\n", srcDesc->numRecords-i-1);
+                                               } else {
+                                                       printf("hfs_swap_HFSPlusBTInternalNode: attr fork data #%d too big\n", srcDesc->numRecords-i-1);
+                                               }
                                                return fsBTInvalidNodeErr;
                        }
                        
@@ -731,7 +802,11 @@ hfs_swap_HFSPlusBTInternalNode (
                case kHFSPlusAttrExtents:
                        /* Is there room for an extent record? */
                        if ((char *)srcRec + sizeof(HFSPlusAttrExtents) > nextRecord) {
-                                               printf("hfs_swap_HFSPlusBTInternalNode: attr extents #%d too big\n", srcDesc->numRecords-i-1);
+                                               if (direction == kSwapBTNodeHostToBig) {
+                                                       panic("hfs_swap_HFSPlusBTInternalNode: attr extents #%d too big\n", srcDesc->numRecords-i-1);
+                                               } else {
+                                                       printf("hfs_swap_HFSPlusBTInternalNode: attr extents #%d too big\n", srcDesc->numRecords-i-1);
+                                               }
                                                return fsBTInvalidNodeErr;
                        }
                        
@@ -766,7 +841,11 @@ hfs_swap_HFSPlusBTInternalNode (
 
                        /* Make sure there is room for the key (HotFileKey) and data (u_int32_t) */
                        if ((char *)srcKey + sizeof(HotFileKey) + sizeof(u_int32_t) > nextRecord) {
-                               printf("hfs_swap_HFSPlusBTInternalNode: hotfile #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSPlusBTInternalNode: hotfile #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               } else {
+                                       printf("hfs_swap_HFSPlusBTInternalNode: hotfile #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               }
                                return fsBTInvalidNodeErr;
                        }
                        
@@ -774,7 +853,11 @@ hfs_swap_HFSPlusBTInternalNode (
                        if (direction == kSwapBTNodeBigToHost)
                                srcKey->keyLength = SWAP_BE16 (srcKey->keyLength);
                        if (srcKey->keyLength != sizeof(*srcKey) - sizeof(srcKey->keyLength)) {
-                               printf("hfs_swap_HFSPlusBTInternalNode: hotfile #%d incorrect keyLength %d\n", srcDesc->numRecords-i-1, srcKey->keyLength);
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSPlusBTInternalNode: hotfile #%d incorrect keyLength %d\n", srcDesc->numRecords-i-1, srcKey->keyLength);
+                               } else {
+                                       printf("hfs_swap_HFSPlusBTInternalNode: hotfile #%d incorrect keyLength %d\n", srcDesc->numRecords-i-1, srcKey->keyLength);
+                               }
                                return fsBTInvalidNodeErr;
                        }
                        srcRec = (u_int32_t *)((char *)srcKey + srcKey->keyLength + sizeof(srcKey->keyLength));
@@ -843,13 +926,21 @@ hfs_swap_HFSBTInternalNode (
                         * below.
                         */
                        if ((char *)srcKey + sizeof(HFSExtentKey) + recordSize > nextRecord) {
-                               printf("hfs_swap_HFSBTInternalNode: extents key #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSBTInternalNode: extents key #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               } else {
+                                       printf("hfs_swap_HFSBTInternalNode: extents key #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               }
                                return fsBTInvalidNodeErr;
                        }
                        
             /* Don't swap srcKey->keyLength (it's only one byte), but do sanity check it */
             if (srcKey->keyLength != sizeof(*srcKey) - sizeof(srcKey->keyLength)) {
-                               printf("hfs_swap_HFSBTInternalNode: extents key #%d invalid length (%d)\n", srcDesc->numRecords-i-1, srcKey->keyLength);
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSBTInternalNode: extents key #%d invalid length (%d)\n", srcDesc->numRecords-i-1, srcKey->keyLength);
+                               } else {
+                                       printf("hfs_swap_HFSBTInternalNode: extents key #%d invalid length (%d)\n", srcDesc->numRecords-i-1, srcKey->keyLength);
+                               }
                                return fsBTInvalidNodeErr;
             }
 
@@ -896,13 +987,21 @@ hfs_swap_HFSBTInternalNode (
                         * record start to an even offset, which forms a minimal key.
                         */
                        if ((char *)srcKey + 8 > nextRecord) {
-                               printf("hfs_swap_HFSBTInternalNode: catalog key #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSBTInternalNode: catalog key #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               } else {
+                                       printf("hfs_swap_HFSBTInternalNode: catalog key #%d offset too big (0x%04X)\n", srcDesc->numRecords-i-1, srcOffs[i]);
+                               }
                                return fsBTInvalidNodeErr;
                        }
                        
             /* Don't swap srcKey->keyLength (it's only one byte), but do sanity check it */
             if (srcKey->keyLength < kHFSCatalogKeyMinimumLength || srcKey->keyLength > kHFSCatalogKeyMaximumLength) {
-                               printf("hfs_swap_HFSBTInternalNode: catalog key #%d invalid length (%d)\n", srcDesc->numRecords-i-1, srcKey->keyLength);
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSBTInternalNode: catalog key #%d invalid length (%d)\n", srcDesc->numRecords-i-1, srcKey->keyLength);
+                               } else {
+                                       printf("hfs_swap_HFSBTInternalNode: catalog key #%d invalid length (%d)\n", srcDesc->numRecords-i-1, srcKey->keyLength);
+                               }
                                return fsBTInvalidNodeErr;
             }
             
@@ -918,8 +1017,13 @@ hfs_swap_HFSBTInternalNode (
                        else
                                expectedKeyLength = srcKey->nodeName[0] + kHFSCatalogKeyMinimumLength;
             if (srcKey->keyLength < expectedKeyLength) {
-                               printf("hfs_swap_HFSBTInternalNode: catalog record #%d keyLength=%u expected=%u\n",
-                                       srcDesc->numRecords-i, srcKey->keyLength, expectedKeyLength);
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSBTInternalNode: catalog record #%d keyLength=%u expected=%u\n",
+                                               srcDesc->numRecords-i, srcKey->keyLength, expectedKeyLength);
+                               } else {
+                                       printf("hfs_swap_HFSBTInternalNode: catalog record #%d keyLength=%u expected=%u\n",
+                                               srcDesc->numRecords-i, srcKey->keyLength, expectedKeyLength);
+                               }
                                return fsBTInvalidNodeErr;
             }
 
@@ -931,7 +1035,11 @@ hfs_swap_HFSBTInternalNode (
              * and index node's child node number.
              */
             if ((char *)srcPtr + sizeof(u_int32_t) > nextRecord) {
-                               printf("hfs_swap_HFSBTInternalNode: catalog key #%d too big\n", srcDesc->numRecords-i-1);
+                               if (direction == kSwapBTNodeHostToBig) {
+                                       panic("hfs_swap_HFSBTInternalNode: catalog key #%d too big\n", srcDesc->numRecords-i-1);
+                               } else {
+                                       printf("hfs_swap_HFSBTInternalNode: catalog key #%d too big\n", srcDesc->numRecords-i-1);
+                               }
                                return fsBTInvalidNodeErr;
             }
             
@@ -951,7 +1059,11 @@ hfs_swap_HFSBTInternalNode (
             if (srcPtr[0] == kHFSFolderRecord) {
                 HFSCatalogFolder *srcRec = (HFSCatalogFolder *)srcPtr;
                 if ((char *)srcRec + sizeof(*srcRec) > nextRecord) {
-                                       printf("hfs_swap_HFSBTInternalNode: catalog folder record #%d too big\n", srcDesc->numRecords-i-1);
+                                       if (direction == kSwapBTNodeHostToBig) {
+                                               panic("hfs_swap_HFSBTInternalNode: catalog folder record #%d too big\n", srcDesc->numRecords-i-1);
+                                       } else {
+                                               printf("hfs_swap_HFSBTInternalNode: catalog folder record #%d too big\n", srcDesc->numRecords-i-1);
+                                       }
                                        return fsBTInvalidNodeErr;
                 }
                 
@@ -970,7 +1082,11 @@ hfs_swap_HFSBTInternalNode (
             } else if (srcPtr[0] == kHFSFileRecord) {
                 HFSCatalogFile *srcRec = (HFSCatalogFile *)srcPtr;
                 if ((char *)srcRec + sizeof(*srcRec) > nextRecord) {
-                                       printf("hfs_swap_HFSBTInternalNode: catalog file record #%d too big\n", srcDesc->numRecords-i-1);
+                                       if (direction == kSwapBTNodeHostToBig) {
+                                               panic("hfs_swap_HFSBTInternalNode: catalog file record #%d too big\n", srcDesc->numRecords-i-1);
+                                       } else {
+                                               printf("hfs_swap_HFSBTInternalNode: catalog file record #%d too big\n", srcDesc->numRecords-i-1);
+                                       }
                                        return fsBTInvalidNodeErr;
                 }
                 
@@ -1011,7 +1127,11 @@ hfs_swap_HFSBTInternalNode (
                 
                 /* Make sure there is room for parentID and name length */
                 if ((char *) &srcRec->nodeName[1] > nextRecord) {
-                                       printf("hfs_swap_HFSBTInternalNode: catalog thread record #%d too big\n", srcDesc->numRecords-i-1);
+                                       if (direction == kSwapBTNodeHostToBig) {
+                                               panic("hfs_swap_HFSBTInternalNode: catalog thread record #%d too big\n", srcDesc->numRecords-i-1);
+                                       } else {
+                                               printf("hfs_swap_HFSBTInternalNode: catalog thread record #%d too big\n", srcDesc->numRecords-i-1);
+                                       }
                                        return fsBTInvalidNodeErr;
                 }
     
@@ -1023,11 +1143,19 @@ hfs_swap_HFSBTInternalNode (
                 
                        /* Make sure there is room for the name in the buffer */
                 if ((char *) &srcRec->nodeName[srcRec->nodeName[0]] > nextRecord) {
-                                       printf("hfs_swap_HFSBTInternalNode: catalog thread record #%d name too big\n", srcDesc->numRecords-i-1);
+                                       if (direction == kSwapBTNodeHostToBig) {
+                                               panic("hfs_swap_HFSBTInternalNode: catalog thread record #%d name too big\n", srcDesc->numRecords-i-1);
+                                       } else {
+                                               printf("hfs_swap_HFSBTInternalNode: catalog thread record #%d name too big\n", srcDesc->numRecords-i-1);
+                                       }
                                        return fsBTInvalidNodeErr;
                 }
             } else {
-               printf("hfs_swap_HFSBTInternalNode: unrecognized catalog record type (0x%04X; record #%d)\n", srcPtr[0], srcDesc->numRecords-i-1);
+                               if (direction == kSwapBTNodeHostToBig) {
+                       panic("hfs_swap_HFSBTInternalNode: unrecognized catalog record type (0x%04X; record #%d)\n", srcPtr[0], srcDesc->numRecords-i-1);
+                               } else {
+                       printf("hfs_swap_HFSBTInternalNode: unrecognized catalog record type (0x%04X; record #%d)\n", srcPtr[0], srcDesc->numRecords-i-1);
+                               }
                                return fsBTInvalidNodeErr;
             }
     
index daf533c2e3058de1bb3174358537361f6dad3c16..a667aa364fa2ee84ba7b452e61799700736b0b74 100644 (file)
@@ -1046,7 +1046,7 @@ do_bulk_access_check(struct hfsmount *hfsmp, struct vnode *vp,
        tmp_user_access.num_files = accessp->num_files;
        tmp_user_access.map_size  = 0;
        tmp_user_access.file_ids  = CAST_USER_ADDR_T(accessp->file_ids);
-       tmp_user_access.bitmap    = (user_addr_t)NULL;
+       tmp_user_access.bitmap    = USER_ADDR_NULL;
        tmp_user_access.access    = CAST_USER_ADDR_T(accessp->access);
        tmp_user_access.num_parents = 0;
        user_access_structp = &tmp_user_access;
index c0dc7253d7da460c8887b5b21d5a1c4643eb4167..bf7635ebaba8ce1b01958f17e6c5e65c16da33eb 100644 (file)
@@ -75,6 +75,7 @@
 #include <sys/kauth.h>
 
 #include <sys/ubc.h>
+#include <sys/ubc_internal.h>
 #include <sys/vnode_internal.h>
 #include <sys/mount_internal.h>
 #include <sys/sysctl.h>
@@ -1608,7 +1609,7 @@ hfs_statfs(struct mount *mp, register struct vfsstatfs *sbp, __unused vfs_contex
        freeCNIDs = (u_long)0xFFFFFFFF - (u_long)vcb->vcbNxtCNID;
 
        sbp->f_bsize = (u_int32_t)vcb->blockSize;
-       sbp->f_iosize = (size_t)(MAX_UPL_TRANSFER * PAGE_SIZE);
+       sbp->f_iosize = (size_t)cluster_max_io_size(mp, 0);
        sbp->f_blocks = (u_int64_t)((unsigned long)vcb->totalBlocks);
        sbp->f_bfree = (u_int64_t)((unsigned long )hfs_freeblks(hfsmp, 0));
        sbp->f_bavail = (u_int64_t)((unsigned long )hfs_freeblks(hfsmp, 1));
@@ -4418,7 +4419,7 @@ end_iteration:
                        if (error)
                                break;
                        error = hfs_relocate(rvp, hfsmp->hfs_metazone_end + 1, kauth_cred_get(), current_proc());
-                       vnode_put(rvp);
+                       VTOC(rvp)->c_flag |= C_NEED_RVNODE_PUT;
                        if (error)
                                break;
                }
@@ -4565,7 +4566,7 @@ hfs_vfs_getattr(struct mount *mp, struct vfs_attr *fsap, __unused vfs_context_t
        VFSATTR_RETURN(fsap, f_filecount, (u_int64_t)hfsmp->vcbFilCnt);
        VFSATTR_RETURN(fsap, f_dircount, (u_int64_t)hfsmp->vcbDirCnt);
        VFSATTR_RETURN(fsap, f_maxobjcount, (u_int64_t)0xFFFFFFFF);
-       VFSATTR_RETURN(fsap, f_iosize, (size_t)(MAX_UPL_TRANSFER * PAGE_SIZE));
+       VFSATTR_RETURN(fsap, f_iosize, (size_t)cluster_max_io_size(mp, 0));
        VFSATTR_RETURN(fsap, f_blocks, (u_int64_t)hfsmp->totalBlocks);
        VFSATTR_RETURN(fsap, f_bfree, (u_int64_t)hfs_freeblks(hfsmp, 0));
        VFSATTR_RETURN(fsap, f_bavail, (u_int64_t)hfs_freeblks(hfsmp, 1));
index d8350638aa2f170dcadf3d521c8991efb13cc3cb..45eda09382ff942e4dfa2885307fd15734a1d093 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/param.h>
 #include <sys/file_internal.h>
 #include <sys/dirent.h>
 #include <sys/stat.h>
@@ -292,12 +293,58 @@ hfs_vnop_close(ap)
        struct proc *p = vfs_context_proc(ap->a_context);
        struct hfsmount *hfsmp;
        int busy;
+       int knownrefs = 0;
+       int tooktrunclock = 0;
 
        if ( hfs_lock(VTOC(vp), HFS_EXCLUSIVE_LOCK) != 0)
                return (0);
        cp = VTOC(vp);
        hfsmp = VTOHFS(vp);
 
+       /*
+        * If the rsrc fork is a named stream, it holds a usecount on 
+        * the data fork, which prevents the data fork from getting recycled, which
+        * then prevents the de-allocation of its extra blocks.  
+        * Do checks for truncation on close. Purge extra extents if they
+        * exist.  Make sure the vp is not a directory, that it has a resource
+        * fork, and that rsrc fork is a named stream.
+        */
+       
+       if ((vp->v_type == VREG) && (cp->c_rsrc_vp)
+                       && (vnode_isnamedstream(cp->c_rsrc_vp))) {
+               uint32_t blks;
+
+               blks = howmany(VTOF(vp)->ff_size, VTOVCB(vp)->blockSize);
+               /*
+                *  If there are any extra blocks and there are only 2 refs on 
+                *  this vp (ourselves + rsrc fork holding ref on us), go ahead
+                *  and try to truncate the extra blocks away.
+                */
+               if ((blks < VTOF(vp)->ff_blocks) && (!vnode_isinuse(vp, 2))) {
+                       // release cnode lock ; must acquire truncate lock BEFORE cnode lock
+                       hfs_unlock (cp);
+
+                       hfs_lock_truncate(cp, TRUE);
+                       tooktrunclock = 1;
+                       
+                       if (hfs_lock(VTOC(vp), HFS_EXCLUSIVE_LOCK) != 0) {
+                               hfs_unlock_truncate(cp, TRUE);
+                               return (0);                     
+                       }
+
+                       //now re-test to make sure it's still valid.
+                       if (cp->c_rsrc_vp) {
+                               knownrefs = 1 + vnode_isnamedstream(cp->c_rsrc_vp);
+                               if (!vnode_isinuse(vp, knownrefs)) {
+                                       blks = howmany(VTOF(vp)->ff_size, VTOVCB(vp)->blockSize);
+                                       if (blks < VTOF(vp)->ff_blocks) {
+                                               (void) hfs_truncate(vp, VTOF(vp)->ff_size, IO_NDELAY, 0, ap->a_context);
+                                       }
+                               }
+                       }
+               }
+       }
+
        // if we froze the fs and we're exiting, then "thaw" the fs 
        if (hfsmp->hfs_freezing_proc == p && proc_exiting(p)) {
            hfsmp->hfs_freezing_proc = NULL;
@@ -315,7 +362,10 @@ hfs_vnop_close(ap)
        } else if (vnode_issystem(vp) && !busy) {
                vnode_recycle(vp);
        }
-
+       if (tooktrunclock) {
+               hfs_unlock_truncate(cp, TRUE);
+       }
+       
        hfs_unlock(cp);
        return (0);
 }
@@ -1759,6 +1809,8 @@ hfs_vnop_remove(ap)
        hfs_unlockpair(dcp, cp);
 
        if (recycle_rsrc && vnode_getwithvid(rvp, rvid) == 0) {
+               vnode_ref(rvp);
+               vnode_rele(rvp);
                vnode_recycle(rvp);
                vnode_put(rvp);
        } 
@@ -1880,7 +1932,7 @@ hfs_removefile(struct vnode *dvp, struct vnode *vp, struct componentname *cnp,
                 * until the call to hfs_vnop_inactive() occurs.
                 */
                if (cp->c_rsrc_vp) {
-                       defer_remove = 1;
+                       defer_remove = 1;
                } else {
                        error = hfs_vgetrsrc(hfsmp, vp, &rvp, FALSE);
                        if (error)
@@ -2205,6 +2257,7 @@ hfs_vnop_rename(ap)
        struct vnode *tdvp = ap->a_tdvp;
        struct vnode *fvp = ap->a_fvp;
        struct vnode *fdvp = ap->a_fdvp;
+       struct vnode *rvp = NULLVP;
        struct componentname *tcnp = ap->a_tcnp;
        struct componentname *fcnp = ap->a_fcnp;
        struct proc *p = vfs_context_proc(ap->a_context);
@@ -2222,7 +2275,9 @@ hfs_vnop_rename(ap)
        int took_trunc_lock = 0;
        int lockflags;
        int error;
-
+       int rsrc_vid = 0;
+       int recycle_rsrc = 0;
+       
        /* When tvp exist, take the truncate lock for the hfs_removefile(). */
        if (tvp && (vnode_isreg(tvp) || vnode_islnk(tvp))) {
                hfs_lock_truncate(VTOC(tvp), TRUE);
@@ -2499,7 +2554,22 @@ hfs_vnop_rename(ap)
                if (vnode_isdir(tvp))
                        error = hfs_removedir(tdvp, tvp, tcnp, HFSRM_SKIP_RESERVE);
                else {
+                       if (tcp){
+                               rvp = tcp->c_rsrc_vp;
+                       }
                        error = hfs_removefile(tdvp, tvp, tcnp, 0, HFSRM_SKIP_RESERVE, 0);
+                               
+                       /* If the destination file had a resource fork vnode, we couldn't do 
+                        * anything about it in hfs_removefile because we didn't have a reference on it.  
+                        * We need to take action here to prevent it from leaking blocks.  If removefile 
+                        * succeeded, then squirrel away the vid of the resource fork vnode and force a 
+                        * recycle after dropping all of the locks. The vid is guaranteed not to change 
+                        * at this point because we still hold the cnode lock.
+                        */
+                       if ((error == 0) && (tcp->c_flag & C_DELETED) && rvp && !vnode_isinuse(rvp, 0)) {
+                               rsrc_vid = vnode_vid(rvp);      
+                               recycle_rsrc = 1;
+                       }
                }
 
                if (error)
@@ -2602,6 +2672,19 @@ out:
 
        hfs_unlockfour(fdcp, fcp, tdcp, tcp);
 
+       /* Now that we've dropped locks, see if we need to force recycle on the old
+        * destination's rsrc fork, preventing a leak of the rsrc fork's blocks.  Note that
+        * doing the ref/rele is in order to twiddle the VL_INACTIVE bit to the vnode's flags
+        * so that on the last vnode_put for this vnode, we will force vnop_inactive to be triggered.
+        */
+       if ((recycle_rsrc) && (vnode_getwithvid(rvp, rsrc_vid) == 0)) {         
+               vnode_ref(rvp);
+               vnode_rele(rvp);
+               vnode_recycle(rvp);
+               vnode_put (rvp);
+       }
+
+
        /* After tvp is removed the only acceptable error is EIO */
        if (error && tvp_deleted)
                error = EIO;
@@ -3611,6 +3694,7 @@ int
 hfs_vgetrsrc(struct hfsmount *hfsmp, struct vnode *vp, struct vnode **rvpp, int can_drop_lock)
 {
        struct vnode *rvp;
+       struct vnode *dvp = NULLVP;
        struct cnode *cp = VTOC(vp);
        int error;
        int vid;
@@ -3706,9 +3790,12 @@ restart:
                                                 "%s%s", cp->c_desc.cd_nameptr,
                                                 _PATH_RSRCFORKSPEC);
                }
-               error = hfs_getnewvnode(hfsmp, vnode_parent(vp), cn.cn_pnbuf ? &cn : NULL,
+               dvp = vnode_getparent(vp);
+               error = hfs_getnewvnode(hfsmp, dvp, cn.cn_pnbuf ? &cn : NULL,
                                        &cp->c_desc, GNV_WANTRSRC | GNV_SKIPLOCK, &cp->c_attr,
                                        &rsrcfork, &rvp);
+               if (dvp)
+                       vnode_put(dvp);
                if (cn.cn_pnbuf)
                        FREE_ZONE(cn.cn_pnbuf, cn.cn_pnlen, M_NAMEI);
                if (error)
index bdfe2f2ded44c2fdd38368445e43d25b41b67a54..a732366ca8be9a1bf8dd3efe5c82ee2a3ad84d5d 100644 (file)
@@ -517,7 +517,7 @@ OSErr MapFileBlockC (
        //      offset in sectors from start of allocation block space
        //
        temp = (daddr64_t)((offset - (off_t)((off_t)(firstFABN) * (off_t)(allocBlockSize)))/sectorSize);
-       temp += startBlock * sectorsPerBlock;
+       temp += (daddr64_t)startBlock * (daddr64_t)sectorsPerBlock;
 
        /* Add in any volume offsets */
        if (vcb->vcbSigWord == kHFSPlusSigWord)
index b7cbc128add031983139742d23ab0e11b153564a..71bf279596f3f0abde796d9c50a2402ae5ccc4c6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2004, 2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -37,6 +37,9 @@
  * cast to any desired pointer type.
  */
 #define        __DARWIN_ALIGNBYTES     (sizeof(__darwin_size_t) - 1)
-#define        __DARWIN_ALIGN(p)       ((__darwin_size_t)((char *)(p) + __DARWIN_ALIGNBYTES) &~ __DARWIN_ALIGNBYTES)
+#define        __DARWIN_ALIGN(p)       ((__darwin_size_t)((char *)(__darwin_intptr_t)(p) + __DARWIN_ALIGNBYTES) &~ __DARWIN_ALIGNBYTES)
+
+#define        __DARWIN_ALIGNBYTES32   (sizeof(__uint32_t) - 1)
+#define        __DARWIN_ALIGN32(p)     ((__darwin_size_t)((char *)(__darwin_intptr_t)(p) + __DARWIN_ALIGNBYTES32) &~ __DARWIN_ALIGNBYTES32)
 
 #endif /* _I386__PARAM_H_ */
index 2a04d688caec3fcb294839c60271d9a6ebafd3b8..50d955a3f7ac1729f9944d8da9f7cdc069a40e0c 100644 (file)
@@ -223,7 +223,7 @@ struct      vnode *rootvp;
 int boothowto = RB_DEBUG;
 
 void lightning_bolt(void *);
-extern kern_return_t IOFindBSDRoot(char *, dev_t *, u_int32_t *);
+extern kern_return_t IOFindBSDRoot(char *, unsigned int, dev_t *, u_int32_t *);
 extern void IOSecureBSDRoot(const char * rootName);
 extern kern_return_t IOKitBSDInit(void );
 extern void kminit(void);
@@ -962,7 +962,7 @@ setconf(void)
         * which needs to be under network funnel. Right thing to do
         * here is to drop the funnel alltogether and regrab it afterwards
         */
-       err = IOFindBSDRoot( rootdevice, &rootdev, &flags );
+       err = IOFindBSDRoot(rootdevice, sizeof(rootdevice), &rootdev, &flags);
        if( err) {
                printf("setconf: IOFindBSDRoot returned an error (%d);"
                        "setting rootdevice to 'sd0a'.\n", err); /* XXX DEBUG TEMP */
index 8af10ca2cef81da65ca6e5295f4bc4f93739aad2..6325962b2cfe1fc2b08c0ec248822361a30fffec 100644 (file)
@@ -67,7 +67,7 @@ imageboot_needed(void)
        if (root_path == NULL)
                panic("%s: M_NAMEI zone exhausted", __FUNCTION__);
 
-       if(PE_parse_boot_arg("rp", root_path) == TRUE) {
+       if(PE_parse_boot_argn("rp", root_path, MAXPATHLEN) == TRUE) {
                /* Got it, now verify scheme */
 
                if (strncmp(root_path, kIBFilePrefix,
@@ -105,7 +105,7 @@ imageboot_setup()
        if (root_path == NULL)
                return (ENOMEM);
 
-       if(PE_parse_boot_arg("rp", root_path) == FALSE) {
+       if(PE_parse_boot_argn("rp", root_path, MAXPATHLEN) == FALSE) {
                error = ENOENT;
                goto done;
        }
index d44744be210e78cf978bb935d7ad05118085f4dc..0a67834ff191d0a05bf50976e71c2dd809ecca4c 100644 (file)
@@ -3912,13 +3912,12 @@ fileproc_drain(proc_t p, struct fileproc * fp)
 
                lck_mtx_convert_spin(&p->p_fdmlock);
 
+               if (fp->f_fglob->fg_ops->fo_drain) {
+                       (*fp->f_fglob->fg_ops->fo_drain)(fp, &context);
+               }
                if (((fp->f_flags & FP_INSELECT)== FP_INSELECT)) {
                        wait_queue_wakeup_all((wait_queue_t)fp->f_waddr, &selwait, THREAD_INTERRUPTED);
-               } else  {
-                       if (fp->f_fglob->fg_ops->fo_drain) {
-                               (*fp->f_fglob->fg_ops->fo_drain)(fp, &context);
-                       }
-               }
+               } 
                p->p_fpdrainwait = 1;
 
                msleep(&p->p_fpdrainwait, &p->p_fdmlock, PRIBIO, "fpdrain", NULL);
index 3a44414347f5d9a58020ad21e7e49e7b7901a5a5..a3c81e332aa59bbf89b348778d3174051f4425c9 100644 (file)
@@ -1706,6 +1706,7 @@ csops(__unused proc_t p, struct csops_args *uap, __unused register_t *retval)
                        if (buf == NULL) 
                                return(ENOMEM);
 
+                       bzero(buf, usize);
 
                        error = vnode_getwithvid(tvp, vid);
                        if (error == 0) {
index d244876ab88de0950eee862cce3d07314b99828a..6c90d6485563a85cb622a96e4166e96f6d949ec3 100644 (file)
@@ -1046,6 +1046,14 @@ semop(struct proc *p, struct semop_args *uap, register_t *retval)
                goto semopout;
        }
 
+       if (nsops < 0 || nsops > MAX_SOPS) {
+#ifdef SEM_DEBUG
+               printf("too many sops (max=%d, nsops=%d)\n", MAX_SOPS, nsops);
+#endif
+               eval = E2BIG;
+               goto semopout;
+       }
+
 #if CONFIG_MACF
        /*
         * Initial pass thru sops to see what permissions are needed.
@@ -1064,14 +1072,6 @@ semop(struct proc *p, struct semop_args *uap, register_t *retval)
                goto semopout;
 #endif
 
-       if (nsops < 0 || nsops > MAX_SOPS) {
-#ifdef SEM_DEBUG
-               printf("too many sops (max=%d, nsops=%d)\n", MAX_SOPS, nsops);
-#endif
-               eval = E2BIG;
-               goto semopout;
-       }
-
        /*  OK for LP64, since sizeof(struct sembuf) is currently invariant */
        if ((eval = copyin(uap->sops, &sops, nsops * sizeof(struct sembuf))) != 0) {
 #ifdef SEM_DEBUG
index 75abf3d3961f1505b26127c8e1a62f5096d85e0c..43cd4543136d37aff54111c52143de58ab15a602 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 1999-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -222,6 +222,13 @@ CS_CodeDirectory *findCodeDirectory(
            cs_valid_range(cd, cd + 1, lower_bound, upper_bound) &&
            cs_valid_range(cd, (const char *) cd + ntohl(cd->length),
                           lower_bound, upper_bound) &&
+           cs_valid_range(cd, (const char *) cd + ntohl(cd->hashOffset),
+                          lower_bound, upper_bound) &&
+           cs_valid_range(cd, (const char *) cd +
+                          ntohl(cd->hashOffset) +
+                          (ntohl(cd->nCodeSlots) * SHA1_RESULTLEN),
+                          lower_bound, upper_bound) &&
+           
            ntohl(cd->magic) == CSMAGIC_CODEDIRECTORY) {
                return cd;
        }
@@ -1462,10 +1469,7 @@ ubc_unmap(struct vnode *vp)
        struct ubc_info *uip;
        int     need_rele = 0;
        int     need_wakeup = 0;
-#if NAMEDRSRCFORK 
-       int     named_fork = 0;
-#endif
-
+       
        if (vnode_getwithref(vp))
                return;
 
@@ -1480,30 +1484,15 @@ ubc_unmap(struct vnode *vp)
                }
                SET(uip->ui_flags, UI_MAPBUSY);
 
-#if NAMEDRSRCFORK
-               if ((vp->v_flag & VISNAMEDSTREAM) &&
-                   (vp->v_parent != NULLVP) && 
-                   !(vp->v_parent->v_mount->mnt_kern_flag & MNTK_NAMED_STREAMS)) {
-                       named_fork = 1;
-               }
-#endif
-
                if (ISSET(uip->ui_flags, UI_ISMAPPED)) {
-                       CLR(uip->ui_flags, UI_ISMAPPED);
+               CLR(uip->ui_flags, UI_ISMAPPED);
                        need_rele = 1;
                }
                vnode_unlock(vp);
-               
+       
                if (need_rele) {
-                       (void)VNOP_MNOMAP(vp, vfs_context_current());
-
-#if NAMEDRSRCFORK
-                       if (named_fork) {
-                               vnode_relenamedstream(vp->v_parent, vp, vfs_context_current());
-                       }
-#endif
-
-                       vnode_rele(vp);
+                       (void) VNOP_MNOMAP(vp, vfs_context_current());
+                       vnode_rele(vp);
                }
 
                vnode_lock_spin(vp);
@@ -1516,7 +1505,7 @@ ubc_unmap(struct vnode *vp)
                vnode_unlock(vp);
 
                if (need_wakeup)
-                       wakeup(&uip->ui_flags);
+                   wakeup(&uip->ui_flags);
 
        }
        /*
@@ -1795,7 +1784,7 @@ upl_size_t
 ubc_upl_maxbufsize(
        void)
 {
-       return(MAX_UPL_TRANSFER * PAGE_SIZE);
+       return(MAX_UPL_SIZE * PAGE_SIZE);
 }
 
 /*
@@ -1875,7 +1864,7 @@ ubc_upl_commit(
        kern_return_t   kr;
 
        pl = UPL_GET_INTERNAL_PAGE_LIST(upl);
-       kr = upl_commit(upl, pl, MAX_UPL_TRANSFER);
+       kr = upl_commit(upl, pl, MAX_UPL_SIZE);
        upl_deallocate(upl);
        return kr;
 }
@@ -1950,7 +1939,7 @@ ubc_upl_commit_range(
        pl = UPL_GET_INTERNAL_PAGE_LIST(upl);
 
        kr = upl_commit_range(upl, offset, size, flags,
-                                                 pl, MAX_UPL_TRANSFER, &empty);
+                                                 pl, MAX_UPL_SIZE, &empty);
 
        if((flags & UPL_COMMIT_FREE_ON_EMPTY) && empty)
                upl_deallocate(upl);
@@ -2225,7 +2214,9 @@ ubc_cs_blob_add(
        blob_start_offset = blob->csb_base_offset + blob->csb_start_offset;
        blob_end_offset = blob->csb_base_offset + blob->csb_end_offset;
 
-       if (blob_start_offset >= blob_end_offset) {
+       if (blob_start_offset >= blob_end_offset ||
+           blob_start_offset < 0 ||
+           blob_end_offset <= 0) {
                /* reject empty or backwards blob */
                error = EINVAL;
                goto out;
@@ -2567,8 +2558,11 @@ cs_validate_page(
                        codeLimit = ntohl(cd->codeLimit);
                        hash = hashes(cd, atop(offset),
                                      lower_bound, upper_bound);
-                       bcopy(hash, expected_hash, sizeof (expected_hash));
-                       found_hash = TRUE;
+                       if (hash != NULL) {
+                               bcopy(hash, expected_hash,
+                                     sizeof (expected_hash));
+                               found_hash = TRUE;
+                       }
 
 #if !CS_BLOB_KEEP_IN_KERNEL
                        /* we no longer need that blob in the kernel map */
index 499b4790c617e349e9d1f6471fdc7378c35fc832..31d3cd0825cbe6913958e10c59daf405084cfa84 100644 (file)
@@ -653,7 +653,7 @@ ifa_ifwithnet(
        struct ifaddr *ifa = NULL;
        struct ifaddr *ifa_maybe = (struct ifaddr *) 0;
        u_int af = addr->sa_family;
-       char *addr_data = addr->sa_data, *cplim;
+       const char *addr_data = addr->sa_data, *cplim;
 
        ifnet_head_lock_shared();
        /*
@@ -681,7 +681,7 @@ ifa_ifwithnet(
                ifnet_lock_shared(ifp);
                for (ifa = ifp->if_addrhead.tqh_first; ifa;
                     ifa = ifa->ifa_link.tqe_next) {
-                       char *cp, *cp2, *cp3;
+                       const char *cp, *cp2, *cp3;
 
                        if (ifa->ifa_addr->sa_family != af)
 next:                          continue;
index 302ab9431bb26343bbcb76f8af1466c45529c2ef..59dd0cb78b093112f3c68ba1fdf8df27b3898499 100644 (file)
@@ -1462,6 +1462,13 @@ findpcb:
                                 * Grow the congestion window, if the
                                 * connection is cwnd bound.
                                 */
+                               if (tp->snd_cwnd < tp->snd_wnd) {
+                                       tp->t_bytes_acked += acked;
+                                       if (tp->t_bytes_acked > tp->snd_cwnd) {
+                                               tp->t_bytes_acked -= tp->snd_cwnd;
+                                               tp->snd_cwnd += tp->t_maxseg;
+                                       }
+                               }
                                sbdrop(&so->so_snd, acked);
                                if (SEQ_GT(tp->snd_una, tp->snd_recover) &&
                                    SEQ_LEQ(th->th_ack, tp->snd_recover))
@@ -2543,44 +2550,29 @@ process_ACK:
                        register u_int cw = tp->snd_cwnd;
                        register u_int incr = tp->t_maxseg;
 
-                       if ((acked > incr) && tcp_do_rfc3465) {
-                               if (cw >= tp->snd_ssthresh) {
-                                       tp->t_bytes_acked += acked;
-                                       if (tp->t_bytes_acked >= cw) {
+                       if (cw >= tp->snd_ssthresh) {
+                               tp->t_bytes_acked += acked;
+                               if (tp->t_bytes_acked >= cw) {
                                        /* Time to increase the window. */
-                                               tp->t_bytes_acked -= cw;
-                                       } else {
-                                       /* No need to increase yet. */
-                                               incr = 0;
-                                       }
+                                       tp->t_bytes_acked -= cw;
                                } else {
-                                       /*
-                                        * If the user explicitly enables RFC3465
-                                        * use 2*SMSS for the "L" param.  Otherwise
-                                        * use the more conservative 1*SMSS.
-                                        *
-                                        * (See RFC 3465 2.3 Choosing the Limit)
-                                        */
-                                       u_int abc_lim;
-
-                                       abc_lim = (tcp_do_rfc3465 == 0) ?
-                                           incr : incr * 2;
-                                       incr = lmin(acked, abc_lim);
+                                       /* No need to increase yet. */
+                                       incr = 0;
                                }
-                       }
-                       else {
+                       } else {
                                /*
-                                * If the window gives us less than ssthresh packets
-                                * in flight, open exponentially (segsz per packet).
-                                * Otherwise open linearly: segsz per window
-                                * (segsz^2 / cwnd per packet).
+                                * If the user explicitly enables RFC3465
+                                * use 2*SMSS for the "L" param.  Otherwise
+                                * use the more conservative 1*SMSS.
+                                *
+                                * (See RFC 3465 2.3 Choosing the Limit)
                                 */
-               
-                                       if (cw >= tp->snd_ssthresh) {
-                                               incr = incr * incr / cw;
-                                       }
-                       }
+                               u_int abc_lim;
 
+                               abc_lim = (tcp_do_rfc3465 == 0) ?
+                                   incr : incr * 2;
+                               incr = min(acked, abc_lim);
+                       }
 
                        tp->snd_cwnd = min(cw+incr, TCP_MAXWIN<<tp->snd_scale);
                }
@@ -3559,6 +3551,9 @@ tcp_mss(tp, offer)
                tp->snd_ssthresh = max(2 * mss, rt->rt_rmx.rmx_ssthresh);
                tcpstat.tcps_usedssthresh++;
        }
+       else
+               tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT;
+
        lck_mtx_unlock(rt_mtx);
 }
 
index db82d4d90a5517ce13db2c728c088b6d7619ea79..ca32f6b401d57c82d02fe25c1b57e0d80fbe8bea 100644 (file)
@@ -717,7 +717,7 @@ after_sack_rexmit:
         * after the retransmission timer has been turned off.  Make sure
         * that the retransmission timer is set.
         */
-       if (tp->sack_enable && SEQ_GT(tp->snd_max, tp->snd_una) &&
+       if (tp->sack_enable && (tp->t_state >= TCPS_ESTABLISHED) && SEQ_GT(tp->snd_max, tp->snd_una) &&
                tp->t_timer[TCPT_REXMT] == 0 &&
            tp->t_timer[TCPT_PERSIST] == 0) {
                        tp->t_timer[TCPT_REXMT] = tp->t_rxtcur;
index f120008cd0ffc118494cc8ab17af54616bc8688b..f51febfc1af45998e510d576213555feb73c2418 100644 (file)
@@ -717,6 +717,7 @@ tcp_newtcpcb(inp)
        tp->snd_cwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;
        tp->snd_bwnd = TCP_MAXWIN << TCP_MAX_WINSHIFT;
        tp->snd_ssthresh = TCP_MAXWIN << TCP_MAX_WINSHIFT;
+       tp->snd_ssthresh_prev = TCP_MAXWIN << TCP_MAX_WINSHIFT;
        tp->t_rcvtime = 0;
        tp->t_bw_rtttime = 0;
        /*
index 833caaf4cdbe179d937067052c5735ba4ea42c15..e8de99b71f73b2e6167fd787d3793c638234f177 100644 (file)
@@ -729,15 +729,15 @@ tcp_timers(tp, timer)
                 * growth is 2 mss.  We don't allow the threshhold
                 * to go below this.)
                 */
-               {
-               u_int win = min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg;
-               if (win < 2)
-                       win = 2;
-               tp->snd_cwnd = tp->t_maxseg;
-               tp->snd_ssthresh = win * tp->t_maxseg;
-               tp->t_bytes_acked = 0;
-               tp->t_dupacks = 0;
-               tp->t_unacksegs = 0;
+               if (tp->t_state >=  TCPS_ESTABLISHED) {
+                       u_int win = min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg;
+                       if (win < 2)
+                               win = 2;
+                       tp->snd_cwnd = tp->t_maxseg;
+                       tp->snd_ssthresh = win * tp->t_maxseg;
+                       tp->t_bytes_acked = 0;
+                       tp->t_dupacks = 0;
+                       tp->t_unacksegs = 0;
                }
                EXIT_FASTRECOVERY(tp);
                (void) tcp_output(tp);
index 75abd5156b87528031ac2df3fb44d4d687a8d09c..11b39041314d81dd9dc3b8e8b024799f57f64f52 100644 (file)
@@ -2910,7 +2910,7 @@ ppsratecheck(lasttime, curpps, maxpps)
 
 #if 1 /* DIAGNOSTIC? */
        /* be careful about wrap-around */
-       if (*curpps + 1 > *curpps)
+       if (*curpps + 1 > 0)
                *curpps = *curpps + 1;
 #else
        /*
index 3ce9ba47424b72fca8b5f5d5bf4128d53604c825..c9473dd8bf722b64ff043f826cc4e61921dffbb2 100644 (file)
@@ -104,7 +104,7 @@ ipcomp4_input(struct mbuf *m, int off)
        }
 
        md = m_pulldown(m, off, sizeof(*ipcomp), NULL);
-       if (!m) {
+       if (!md) {
                m = NULL;       /*already freed*/
                ipseclog((LOG_DEBUG, "IPv4 IPComp input: assumption failed "
                    "(pulldown failure)\n"));
@@ -253,7 +253,7 @@ ipcomp6_input(mp, offp)
        off = *offp;
 
        md = m_pulldown(m, off, sizeof(*ipcomp), NULL);
-       if (!m) {
+       if (!md) {
                m = NULL;       /*already freed*/
                ipseclog((LOG_DEBUG, "IPv6 IPComp input: assumption failed "
                    "(pulldown failure)\n"));
index 48694c9ee71ff7ab503a8f56463455473d0dcd4f..44536c3316b108708e3d55b9381f6255237a9b83 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -2035,17 +2035,23 @@ nfs_request_async_finish(
        u_int64_t *xidp,
        int *status)
 {
-       int error, asyncio = req->r_callback.rcb_func ? 1 : 0;
+       int error = 0, asyncio = req->r_callback.rcb_func ? 1 : 0;
 
        lck_mtx_lock(&req->r_mtx);
        if (!asyncio)
                req->r_flags |= R_ASYNCWAIT;
-       while (req->r_flags & R_RESENDQ) /* wait until the request is off the resend queue */
-               msleep(req, &req->r_mtx, PZERO-1, "nfsresendqwait", NULL);
+       while (req->r_flags & R_RESENDQ) {  /* wait until the request is off the resend queue */
+               struct timespec ts = { 2, 0 };
+               if ((error = nfs_sigintr(req->r_nmp, req, req->r_thread, 0)))
+                       break;
+               msleep(req, &req->r_mtx, PZERO-1, "nfsresendqwait", &ts);
+       }
        lck_mtx_unlock(&req->r_mtx);
 
-       nfs_request_wait(req);
-       error = nfs_request_finish(req, nmrepp, status);
+       if (!error) {
+               nfs_request_wait(req);
+               error = nfs_request_finish(req, nmrepp, status);
+       }
 
        while (!error && (req->r_flags & R_RESTART)) {
                if (asyncio && req->r_resendtime) {  /* send later */
@@ -3214,7 +3220,7 @@ nfs_msg(thread_t thd,
 void
 nfs_down(struct nfsmount *nmp, thread_t thd, int error, int flags, const char *msg)
 {
-       int ostate;
+       int ostate, do_vfs_signal;
 
        if (nmp == NULL)
                return;
@@ -3229,7 +3235,12 @@ nfs_down(struct nfsmount *nmp, thread_t thd, int error, int flags, const char *m
                nmp->nm_state |= NFSSTA_JUKEBOXTIMEO;
        lck_mtx_unlock(&nmp->nm_lock);
 
-       if (!(ostate & (NFSSTA_TIMEO|NFSSTA_LOCKTIMEO|NFSSTA_JUKEBOXTIMEO)))
+       /* XXX don't allow users to know about/disconnect unresponsive, soft, nobrowse mounts */
+       if ((nmp->nm_flag & NFSMNT_SOFT) && (vfs_flags(nmp->nm_mountp) & MNT_DONTBROWSE))
+               do_vfs_signal = 0;
+       else
+               do_vfs_signal = !(ostate & (NFSSTA_TIMEO|NFSSTA_LOCKTIMEO|NFSSTA_JUKEBOXTIMEO));
+       if (do_vfs_signal)
                vfs_event_signal(&vfs_statfs(nmp->nm_mountp)->f_fsid, VQ_NOTRESP, 0);
 
        nfs_msg(thd, vfs_statfs(nmp->nm_mountp)->f_mntfromname, msg, error);
@@ -3238,7 +3249,7 @@ nfs_down(struct nfsmount *nmp, thread_t thd, int error, int flags, const char *m
 void
 nfs_up(struct nfsmount *nmp, thread_t thd, int flags, const char *msg)
 {
-       int ostate, state;
+       int ostate, state, do_vfs_signal;
 
        if (nmp == NULL)
                return;
@@ -3257,8 +3268,13 @@ nfs_up(struct nfsmount *nmp, thread_t thd, int flags, const char *msg)
        state = nmp->nm_state;
        lck_mtx_unlock(&nmp->nm_lock);
 
-       if ((ostate & (NFSSTA_TIMEO|NFSSTA_LOCKTIMEO|NFSSTA_JUKEBOXTIMEO)) &&
-           !(state & (NFSSTA_TIMEO|NFSSTA_LOCKTIMEO|NFSSTA_JUKEBOXTIMEO)))
+       /* XXX don't allow users to know about/disconnect unresponsive, soft, nobrowse mounts */
+       if ((nmp->nm_flag & NFSMNT_SOFT) && (vfs_flags(nmp->nm_mountp) & MNT_DONTBROWSE))
+               do_vfs_signal = 0;
+       else
+               do_vfs_signal = (ostate & (NFSSTA_TIMEO|NFSSTA_LOCKTIMEO|NFSSTA_JUKEBOXTIMEO)) &&
+                        !(state & (NFSSTA_TIMEO|NFSSTA_LOCKTIMEO|NFSSTA_JUKEBOXTIMEO));
+       if (do_vfs_signal)
                vfs_event_signal(&vfs_statfs(nmp->nm_mountp)->f_fsid, VQ_NOTRESP, 1);
 }
 
index 7e2e1ee8314b468421aab5435be562722755bd6f..7d65f3c4f24fbfbcc3d36d708a78c373ecd3ad82 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc.  All rights reserved.
+ * Copyright (c) 2000-2008 Apple Inc.  All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -2435,7 +2435,7 @@ static int
 nfs_vfs_sysctl(int *name, u_int namelen, user_addr_t oldp, size_t *oldlenp,
            user_addr_t newp, size_t newlen, vfs_context_t ctx)
 {
-       int error = 0, val;
+       int error = 0, val, softnobrowse;
        struct sysctl_req *req = NULL;
        struct vfsidctl vc;
        struct user_vfsidctl user_vc;
@@ -2793,9 +2793,11 @@ ustat_skip:
                break;
        case VFS_CTL_QUERY:
                lck_mtx_lock(&nmp->nm_lock);
-               if (nmp->nm_state & (NFSSTA_TIMEO|NFSSTA_JUKEBOXTIMEO))
+               /* XXX don't allow users to know about/disconnect unresponsive, soft, nobrowse mounts */
+               softnobrowse = ((nmp->nm_flag & NFSMNT_SOFT) && (vfs_flags(nmp->nm_mountp) & MNT_DONTBROWSE));
+               if (!softnobrowse && (nmp->nm_state & (NFSSTA_TIMEO|NFSSTA_JUKEBOXTIMEO)))
                        vq.vq_flags |= VQ_NOTRESP;
-               if (!(nmp->nm_flag & (NFSMNT_NOLOCKS|NFSMNT_LOCALLOCKS)) &&
+               if (!softnobrowse && !(nmp->nm_flag & (NFSMNT_NOLOCKS|NFSMNT_LOCALLOCKS)) &&
                    (nmp->nm_state & NFSSTA_LOCKTIMEO))
                        vq.vq_flags |= VQ_NOTRESP;
                lck_mtx_unlock(&nmp->nm_lock);
index 1408c6fcc03cbe4427325c6faa6188d8eb7f117a..7adb76efc226b65a81c1fc9b22f6e23973733112 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2004, 2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -37,6 +37,9 @@
  * cast to any desired pointer type.
  */
 #define        __DARWIN_ALIGNBYTES     (sizeof(__darwin_size_t) - 1)
-#define        __DARWIN_ALIGN(p)       ((__darwin_size_t)((char *)(p) + __DARWIN_ALIGNBYTES) &~ __DARWIN_ALIGNBYTES)
+#define        __DARWIN_ALIGN(p)       ((__darwin_size_t)((char *)(__darwin_intptr_t)(p) + __DARWIN_ALIGNBYTES) &~ __DARWIN_ALIGNBYTES)
+
+#define        __DARWIN_ALIGNBYTES32   (sizeof(__uint32_t) - 1)
+#define        __DARWIN_ALIGN32(p)     ((__darwin_size_t)((char *)(__darwin_intptr_t)(p) + __DARWIN_ALIGNBYTES32) &~ __DARWIN_ALIGNBYTES32)
 
 #endif /* _PPC__PARAM_H_ */
index 4048673b59c7906b41192556af71506f3472ac67..82af937631a527f4ffdfa6b03d7e81c38bc301df 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -596,22 +596,22 @@ struct cmsgcred {
 
 /* given pointer to struct cmsghdr, return pointer to data */
 #define        CMSG_DATA(cmsg)         ((unsigned char *)(cmsg) + \
-                                __DARWIN_ALIGN(sizeof(struct cmsghdr)))
+                                __DARWIN_ALIGN32(sizeof(struct cmsghdr)))
 
 /* given pointer to struct cmsghdr, return pointer to next cmsghdr */
 #define        CMSG_NXTHDR(mhdr, cmsg) \
-       (((unsigned char *)(cmsg) + __DARWIN_ALIGN((__darwin_intptr_t)(cmsg)->cmsg_len) + \
-         __DARWIN_ALIGN(sizeof(struct cmsghdr)) > \
+       (((unsigned char *)(cmsg) + __DARWIN_ALIGN32((uint32_t)(cmsg)->cmsg_len) + \
+         __DARWIN_ALIGN32(sizeof(struct cmsghdr)) > \
            (unsigned char *)(mhdr)->msg_control + (mhdr)->msg_controllen) ? \
            (struct cmsghdr *)0L /* NULL */ : \
-           (struct cmsghdr *)((unsigned char *)(cmsg) + __DARWIN_ALIGN((__darwin_intptr_t)(cmsg)->cmsg_len)))
+           (struct cmsghdr *)((unsigned char *)(cmsg) + __DARWIN_ALIGN32((uint32_t)(cmsg)->cmsg_len)))
 
 #define        CMSG_FIRSTHDR(mhdr)     ((struct cmsghdr *)(mhdr)->msg_control)
 
 #if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
 /* RFC 2292 additions */
-#define        CMSG_SPACE(l)           (__DARWIN_ALIGN(sizeof(struct cmsghdr)) + __DARWIN_ALIGN(l))
-#define        CMSG_LEN(l)             (__DARWIN_ALIGN(sizeof(struct cmsghdr)) + (l))
+#define        CMSG_SPACE(l)           (__DARWIN_ALIGN32(sizeof(struct cmsghdr)) + __DARWIN_ALIGN32(l))
+#define        CMSG_LEN(l)             (__DARWIN_ALIGN32(sizeof(struct cmsghdr)) + (l))
 
 #ifdef KERNEL
 #define        CMSG_ALIGN(n)   __DARWIN_ALIGN(n)
index 99b9008ccc0130368539e9dc6887f260c8a2ecf0..eb4d413b50483a30e48e5cf4193058dcb6515aea 100644 (file)
@@ -144,7 +144,9 @@ __private_extern__ void     ubc_destroy_named(vnode_t);
 
 /* internal only */
 __private_extern__ void        cluster_release(struct ubc_info *);
-
+__private_extern__ uint32_t cluster_max_io_size(mount_t, int);
 
 /* Flags for ubc_getobject() */
 #define UBC_FLAGS_NONE         0x0000
index 6eb09940faa0338518e2fb7e29566e414e0d8787..e63b6f3ba5052aee6559407afc38d1f09a19cc65 100644 (file)
@@ -126,7 +126,9 @@ ux_handler(void)
                        (void *) &ux_exception_port) != MACH_MSG_SUCCESS)
                panic("ux_handler: object_copyin(ux_exception_port) failed");
 
+    proc_list_lock();
     thread_wakeup(&ux_exception_port);
+    proc_list_unlock();
 
     /* Message handling loop. */
 
@@ -185,10 +187,11 @@ ux_handler_init(void)
 {
        ux_exception_port = MACH_PORT_NULL;
        (void) kernel_thread(kernel_task, ux_handler);
+       proc_list_lock();
        if (ux_exception_port == MACH_PORT_NULL)  {
-               assert_wait(&ux_exception_port, THREAD_UNINT);
-               thread_block(THREAD_CONTINUE_NULL);
+               (void)msleep(&ux_exception_port, proc_list_mlock, 0, "ux_handler_wait", 0);
        }
+       proc_list_unlock();
 }
 
 kern_return_t
index a1832c53215a50a32d84d1d7ef58c3ceb39b265f..79e526ef21e206a13dda1b7f37a35a6b32f7b092 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -4357,6 +4357,21 @@ VNOP_INACTIVE(struct vnode *vp, vfs_context_t ctx)
        if (!thread_safe) {
                unlock_fsnode(vp, &funnel_state);
        }
+
+#if NAMEDSTREAMS
+       /* For file systems that do not support namedstreams natively, mark
+        * the shadow stream file vnode to be recycled as soon as the last
+        * reference goes away. To avoid re-entering reclaim code, do not
+        * call recycle on terminating named stream vnodes.
+        */
+       if (vnode_isnamedstream(vp) &&
+                       (vp->v_parent != NULLVP) &&
+                       ((vp->v_parent->v_mount->mnt_kern_flag & MNTK_NAMED_STREAMS) == 0) &&
+                       ((vp->v_lflag & VL_TERMINATE) == 0)) {
+               vnode_recycle(vp);
+       }
+#endif
+
        return (_err);
 }
 
index 8d3657909e9a96051b082c955932698f8e136eab..c3b24c28d8a21812733a7a03935fba1d7eeb3076 100644 (file)
@@ -90,8 +90,9 @@
 #include <sys/kdebug.h>
 
 #define CL_READ                0x01
-#define CL_ASYNC       0x02
-#define CL_COMMIT      0x04
+#define CL_WRITE               0x02
+#define CL_ASYNC       0x04
+#define CL_COMMIT      0x08
 #define CL_PAGEOUT     0x10
 #define CL_AGE         0x20
 #define CL_NOZERO      0x40
@@ -182,17 +183,15 @@ int       is_file_clean(vnode_t, off_t);
  * can represent it in a 32 bit int
  */
 #define MAX_IO_REQUEST_SIZE    (1024 * 1024 * 256)
-#define MAX_IO_CONTIG_SIZE     (1024 * 1024 * 8)
-#define MAX_VECTS      16
-
-/*
- * note:  MAX_CLUSTER_SIZE CANNOT be larger than MAX_UPL_TRANSFER
- */
-#define MAX_CLUSTER_SIZE       (MAX_UPL_TRANSFER)
-#define MAX_PREFETCH           (MAX_CLUSTER_SIZE * PAGE_SIZE * 2)
+#define MAX_IO_CONTIG_SIZE             (MAX_UPL_SIZE * PAGE_SIZE)
+#define MAX_VECTS                      16
 #define MIN_DIRECT_WRITE_SIZE  (4 * PAGE_SIZE)
 
 
+#define MAX_CLUSTER_SIZE(vp)   (cluster_max_io_size(vp->v_mount, CL_WRITE))
+#define MAX_PREFETCH(vp)       (cluster_max_io_size(vp->v_mount, CL_READ) * 3);
+
+
 int speculative_reads_disabled = 0;
 
 /*
@@ -231,6 +230,52 @@ cluster_init(void) {
 }
 
 
+uint32_t
+cluster_max_io_size(mount_t mp, int type)
+{
+       uint32_t        max_io_size;
+       uint32_t        segcnt;
+       uint32_t        maxcnt;
+       switch(type) {
+
+       case CL_READ:
+               segcnt = mp->mnt_segreadcnt;
+               maxcnt = mp->mnt_maxreadcnt;
+               break;
+       case CL_WRITE:
+               segcnt = mp->mnt_segwritecnt;
+               maxcnt = mp->mnt_maxwritecnt;
+               break;
+       default:
+               segcnt = min(mp->mnt_segreadcnt, mp->mnt_segwritecnt);
+               maxcnt = min(mp->mnt_maxreadcnt, mp->mnt_maxwritecnt);
+               break;
+       }
+       if (segcnt > MAX_UPL_SIZE) {
+              /*
+               * don't allow a size beyond the max UPL size we can create
+               */
+               segcnt = MAX_UPL_SIZE;
+       }
+       max_io_size = min((segcnt * PAGE_SIZE), maxcnt);
+
+       if (max_io_size < (MAX_UPL_TRANSFER * PAGE_SIZE)) {
+              /*
+               * don't allow a size smaller than the old fixed limit
+               */
+              max_io_size = (MAX_UPL_TRANSFER * PAGE_SIZE);
+       } else {
+              /*
+               * make sure the size specified is a multiple of PAGE_SIZE
+               */
+              max_io_size &= ~PAGE_MASK;
+       }
+       return (max_io_size);
+}
+
+
+
 
 #define CLW_ALLOCATE           0x01
 #define CLW_RETURNLOCKED       0x02
@@ -805,16 +850,21 @@ cluster_io(vnode_t vp, upl_t upl, vm_offset_t upl_offset, off_t f_offset, int no
                                async_throttle = VNODE_ASYNC_THROTTLE;
                        else {
                                u_int max_cluster;
+                               u_int max_cluster_size;
+                               u_int max_prefetch;
+
+                               max_cluster_size = MAX_CLUSTER_SIZE(vp);
+                               max_prefetch = MAX_PREFETCH(vp);
                                
-                               if (max_iosize > (MAX_CLUSTER_SIZE * PAGE_SIZE))
-                                       max_cluster = (MAX_CLUSTER_SIZE * PAGE_SIZE);
+                               if (max_iosize > max_cluster_size)
+                                       max_cluster = max_cluster_size;
                                else
                                        max_cluster = max_iosize;
 
                                if (size < max_cluster)
                                        max_cluster = size;
 
-                               async_throttle = min(VNODE_ASYNC_THROTTLE, (MAX_PREFETCH / max_cluster) - 1);
+                               async_throttle = min(VNODE_ASYNC_THROTTLE, (max_prefetch / max_cluster) - 1);
                        }
                }
        }
@@ -1449,6 +1499,7 @@ cluster_read_ahead(vnode_t vp, struct cl_extent *extent, off_t filesize, struct
        daddr64_t       r_addr;
        off_t           f_offset;
        int             size_of_prefetch;
+       u_int           max_prefetch;
 
 
        KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 48)) | DBG_FUNC_START,
@@ -1468,8 +1519,10 @@ cluster_read_ahead(vnode_t vp, struct cl_extent *extent, off_t filesize, struct
 
                return;
        }
+       max_prefetch = MAX_PREFETCH(vp);
+
        if (extent->e_addr < rap->cl_maxra) {
-               if ((rap->cl_maxra - extent->e_addr) > ((MAX_PREFETCH / PAGE_SIZE) / 4)) {
+               if ((rap->cl_maxra - extent->e_addr) > ((max_prefetch / PAGE_SIZE) / 4)) {
 
                        KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 48)) | DBG_FUNC_END,
                                     rap->cl_ralen, (int)rap->cl_maxra, (int)rap->cl_lastr, 2, 0);
@@ -1491,13 +1544,13 @@ cluster_read_ahead(vnode_t vp, struct cl_extent *extent, off_t filesize, struct
        if (f_offset < filesize) {
                daddr64_t read_size;
 
-               rap->cl_ralen = rap->cl_ralen ? min(MAX_PREFETCH / PAGE_SIZE, rap->cl_ralen << 1) : 1;
+               rap->cl_ralen = rap->cl_ralen ? min(max_prefetch / PAGE_SIZE, rap->cl_ralen << 1) : 1;
 
                read_size = (extent->e_addr + 1) - extent->b_addr;
 
                if (read_size > rap->cl_ralen) {
-                       if (read_size > MAX_PREFETCH / PAGE_SIZE)
-                               rap->cl_ralen = MAX_PREFETCH / PAGE_SIZE;
+                       if (read_size > max_prefetch / PAGE_SIZE)
+                               rap->cl_ralen = max_prefetch / PAGE_SIZE;
                        else
                                rap->cl_ralen = read_size;
                }
@@ -1835,7 +1888,7 @@ cluster_write_direct(vnode_t vp, struct uio *uio, off_t oldEOF, off_t newEOF, in
        u_int32_t        io_req_size;
        u_int32_t        offset_in_file;
        u_int32_t        offset_in_iovbase;
-       int              io_size;
+       u_int32_t        io_size;
        int              io_flag;
        int              bflag;
        vm_size_t        upl_size;
@@ -1851,11 +1904,15 @@ cluster_write_direct(vnode_t vp, struct uio *uio, off_t oldEOF, off_t newEOF, in
        user_addr_t      iov_base;
        u_int32_t        mem_alignment_mask;
        u_int32_t        devblocksize;
+       u_int32_t        max_upl_size;
+
+
+       max_upl_size = cluster_max_io_size(vp->v_mount, CL_WRITE);
 
        if (flags & IO_PASSIVE)
-           bflag = CL_PASSIVE;
+               bflag = CL_PASSIVE;
        else
-           bflag = 0;
+               bflag = 0;
 
        /*
         * When we enter this routine, we know
@@ -1918,8 +1975,8 @@ next_dwrite:
                io_size  = io_req_size & ~PAGE_MASK;
                iov_base = uio_curriovbase(uio);
 
-               if (io_size > (MAX_UPL_TRANSFER * PAGE_SIZE))
-                       io_size = MAX_UPL_TRANSFER * PAGE_SIZE;
+               if (io_size > max_upl_size)
+                       io_size = max_upl_size;
 
                upl_offset = (vm_offset_t)((u_int32_t)iov_base & PAGE_MASK);
                upl_needed_size = (upl_offset + io_size + (PAGE_SIZE -1)) & ~PAGE_MASK;
@@ -2022,9 +2079,16 @@ next_dwrite:
                 */
                lck_mtx_lock(cl_mtxp);
 
-               while ((iostate.io_issued - iostate.io_completed) > (2 * MAX_UPL_TRANSFER * PAGE_SIZE)) {
+               while ((iostate.io_issued - iostate.io_completed) > (2 * max_upl_size)) {
+
+                       KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_START,
+                                       iostate.io_issued, iostate.io_completed, 2 * max_upl_size, 0, 0);
+
                        iostate.io_wanted = 1;
                        msleep((caddr_t)&iostate.io_wanted, cl_mtxp, PRIBIO + 1, "cluster_write_direct", NULL);
+
+                       KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_END,
+                                       iostate.io_issued, iostate.io_completed, 2 * max_upl_size, 0, 0);
                }       
                lck_mtx_unlock(cl_mtxp);
 
@@ -2083,8 +2147,14 @@ wait_for_dwrites:
                lck_mtx_lock(cl_mtxp);
 
                while (iostate.io_issued != iostate.io_completed) {
+                       KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_START,
+                                       iostate.io_issued, iostate.io_completed, 0, 0, 0);
+
                        iostate.io_wanted = 1;
                        msleep((caddr_t)&iostate.io_wanted, cl_mtxp, PRIBIO + 1, "cluster_write_direct", NULL);
+
+                       KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_END,
+                                       iostate.io_issued, iostate.io_completed, 0, 0, 0);
                }       
                lck_mtx_unlock(cl_mtxp);
        }
@@ -2242,8 +2312,15 @@ next_cwrite:
                        lck_mtx_lock(cl_mtxp);
 
                        while ((iostate.io_issued - iostate.io_completed) > (2 * MAX_IO_CONTIG_SIZE)) {
+
+                               KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_START,
+                                               iostate.io_issued, iostate.io_completed, 2 * MAX_IO_CONTIG_SIZE, 0, 0);
+
                                iostate.io_wanted = 1;
                                msleep((caddr_t)&iostate.io_wanted, cl_mtxp, PRIBIO + 1, "cluster_write_contig", NULL);
+
+                               KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_END,
+                                               iostate.io_issued, iostate.io_completed, 2 * MAX_IO_CONTIG_SIZE, 0, 0);
                        }
                        lck_mtx_unlock(cl_mtxp);
                }
@@ -2274,7 +2351,7 @@ next_cwrite:
                        io_size    -= xsize;
                }
        }
-        if (error == 0 && iostate.io_error == 0 && tail_size == 0) {
+        if (error == 0 && iostate.io_error == 0 && tail_size == 0 && num_upl < MAX_VECTS) {
 
                error = cluster_io_type(uio, write_type, write_length, 0);
 
@@ -2293,8 +2370,14 @@ wait_for_cwrites:
         lck_mtx_lock(cl_mtxp);
 
         while (iostate.io_issued != iostate.io_completed) {
+               KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_START,
+                               iostate.io_issued, iostate.io_completed, 0, 0, 0);
+
                iostate.io_wanted = 1;
                msleep((caddr_t)&iostate.io_wanted, cl_mtxp, PRIBIO + 1, "cluster_write_contig", NULL);
+
+               KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_END,
+                               iostate.io_issued, iostate.io_completed, 0, 0, 0);
         }
         lck_mtx_unlock(cl_mtxp);
 
@@ -2343,11 +2426,13 @@ cluster_write_copy(vnode_t vp, struct uio *uio, u_int32_t io_req_size, off_t old
         int              intersection;
        struct cl_writebehind *wbp;
        int              bflag;
+       u_int            max_cluster_pgcount;
+       u_int            max_io_size;
 
        if (flags & IO_PASSIVE)
-           bflag = CL_PASSIVE;
+               bflag = CL_PASSIVE;
        else
-           bflag = 0;
+               bflag = 0;
 
        if (uio) {
                KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 40)) | DBG_FUNC_START,
@@ -2365,6 +2450,9 @@ cluster_write_copy(vnode_t vp, struct uio *uio, u_int32_t io_req_size, off_t old
        zero_off  = 0;
        zero_off1 = 0;
 
+       max_cluster_pgcount = MAX_CLUSTER_SIZE(vp) / PAGE_SIZE;
+       max_io_size = cluster_max_io_size(vp->v_mount, CL_WRITE);
+
        if (flags & IO_HEADZEROFILL) {
                /*
                 * some filesystems (HFS is one) don't support unallocated holes within a file...
@@ -2414,8 +2502,8 @@ cluster_write_copy(vnode_t vp, struct uio *uio, u_int32_t io_req_size, off_t old
                KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 46)) | DBG_FUNC_NONE,
                             (int)zero_off, (int)zero_cnt, (int)zero_off1, (int)zero_cnt1, 0);
 
-               if (total_size > (MAX_UPL_TRANSFER * PAGE_SIZE))
-                       total_size = MAX_UPL_TRANSFER * PAGE_SIZE;
+               if (total_size > max_io_size)
+                       total_size = max_io_size;
 
                cl.b_addr = (daddr64_t)(upl_f_offset / PAGE_SIZE_64);
                
@@ -2424,7 +2512,7 @@ cluster_write_copy(vnode_t vp, struct uio *uio, u_int32_t io_req_size, off_t old
                         * assumption... total_size <= io_resid
                         * because IO_HEADZEROFILL and IO_TAILZEROFILL not set
                         */
-                       if ((start_offset + total_size) > (MAX_UPL_TRANSFER * PAGE_SIZE))
+                       if ((start_offset + total_size) > max_io_size)
                                total_size -= start_offset;
                        xfer_resid = total_size;
 
@@ -2465,8 +2553,8 @@ cluster_write_copy(vnode_t vp, struct uio *uio, u_int32_t io_req_size, off_t old
                 */
                upl_size = (start_offset + total_size + (PAGE_SIZE - 1)) & ~PAGE_MASK;
 
-               if (upl_size > (MAX_UPL_TRANSFER * PAGE_SIZE))
-                       upl_size = MAX_UPL_TRANSFER * PAGE_SIZE;
+               if (upl_size > max_io_size)
+                       upl_size = max_io_size;
 
                pages_in_upl = upl_size / PAGE_SIZE;
                io_size      = upl_size - start_offset;
@@ -2749,7 +2837,7 @@ check_cluster:
                                        /*
                                         * the current write starts at or after the current cluster
                                         */
-                                       if (cl.e_addr <= (wbp->cl_clusters[cl_index].b_addr + MAX_CLUSTER_SIZE)) {
+                                       if (cl.e_addr <= (wbp->cl_clusters[cl_index].b_addr + max_cluster_pgcount)) {
                                                /*
                                                 * we have a write that fits entirely
                                                 * within the existing cluster limits
@@ -2761,7 +2849,7 @@ check_cluster:
                                                        wbp->cl_clusters[cl_index].e_addr = cl.e_addr;
                                                break;
                                        }
-                                       if (cl.b_addr < (wbp->cl_clusters[cl_index].b_addr + MAX_CLUSTER_SIZE)) {
+                                       if (cl.b_addr < (wbp->cl_clusters[cl_index].b_addr + max_cluster_pgcount)) {
                                                /*
                                                 * we have a write that starts in the middle of the current cluster
                                                 * but extends beyond the cluster's limit... we know this because
@@ -2772,7 +2860,7 @@ check_cluster:
                                                 * note that we'll always have a leftover tail in this case since
                                                 * full absorbtion would have occurred in the clause above
                                                 */
-                                               wbp->cl_clusters[cl_index].e_addr = wbp->cl_clusters[cl_index].b_addr + MAX_CLUSTER_SIZE;
+                                               wbp->cl_clusters[cl_index].e_addr = wbp->cl_clusters[cl_index].b_addr + max_cluster_pgcount;
 
                                                if (upl_size) {
                                                        daddr64_t start_pg_in_upl;
@@ -2803,7 +2891,7 @@ check_cluster:
                                        /*
                                         * the current write starts in front of the cluster we're currently considering
                                         */
-                                       if ((wbp->cl_clusters[cl_index].e_addr - cl.b_addr) <= MAX_CLUSTER_SIZE) {
+                                       if ((wbp->cl_clusters[cl_index].e_addr - cl.b_addr) <= max_cluster_pgcount) {
                                                /*
                                                 * we can just merge the new request into
                                                 * this cluster and leave it in the cache
@@ -2816,7 +2904,7 @@ check_cluster:
                                                        /*
                                                         * the current write completely
                                                         * envelops the existing cluster and since
-                                                        * each write is limited to at most MAX_CLUSTER_SIZE pages
+                                                        * each write is limited to at most max_cluster_pgcount pages
                                                         * we can just use the start and last blocknos of the write
                                                         * to generate the cluster limits
                                                         */
@@ -2834,13 +2922,13 @@ check_cluster:
                                         * get an intersection with the current write
                                         * 
                                         */
-                                       if (cl.e_addr > wbp->cl_clusters[cl_index].e_addr - MAX_CLUSTER_SIZE) {
+                                       if (cl.e_addr > wbp->cl_clusters[cl_index].e_addr - max_cluster_pgcount) {
                                                /*
                                                 * the current write extends into the proposed cluster
                                                 * clip the length of the current write after first combining it's
                                                 * tail with the newly shaped cluster
                                                 */
-                                               wbp->cl_clusters[cl_index].b_addr = wbp->cl_clusters[cl_index].e_addr - MAX_CLUSTER_SIZE;
+                                               wbp->cl_clusters[cl_index].b_addr = wbp->cl_clusters[cl_index].e_addr - max_cluster_pgcount;
 
                                                if (upl_size) {
                                                        intersection = (int)((cl.e_addr - wbp->cl_clusters[cl_index].b_addr) * PAGE_SIZE);
@@ -3082,7 +3170,7 @@ cluster_read_copy(vnode_t vp, struct uio *uio, u_int32_t io_req_size, off_t file
        upl_page_info_t *pl;
        upl_t            upl;
        vm_offset_t      upl_offset;
-       int              upl_size;
+       u_int32_t        upl_size;
        off_t            upl_f_offset;
        int              start_offset;
        int              start_pg;
@@ -3098,7 +3186,9 @@ cluster_read_copy(vnode_t vp, struct uio *uio, u_int32_t io_req_size, off_t file
        u_int32_t        size_of_prefetch;
        u_int32_t        xsize;
        u_int32_t        io_size;
-       u_int32_t        max_rd_size = MAX_PREFETCH;
+       u_int32_t        max_rd_size;
+       u_int32_t        max_io_size;
+       u_int32_t        max_prefetch;
        u_int            rd_ahead_enabled = 1;
        u_int            prefetch_enabled = 1;
        struct cl_readahead *   rap;
@@ -3120,9 +3210,13 @@ cluster_read_copy(vnode_t vp, struct uio *uio, u_int32_t io_req_size, off_t file
                take_reference = 0;
 
        if (flags & IO_PASSIVE)
-           bflag = CL_PASSIVE;
+               bflag = CL_PASSIVE;
        else
-           bflag = 0;
+               bflag = 0;
+
+       max_prefetch = MAX_PREFETCH(vp);
+       max_rd_size = max_prefetch;
+       max_io_size = cluster_max_io_size(vp->v_mount, CL_READ);
 
        KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 32)) | DBG_FUNC_START,
                     (int)uio->uio_offset, io_req_size, (int)filesize, flags, 0);
@@ -3220,8 +3314,8 @@ cluster_read_copy(vnode_t vp, struct uio *uio, u_int32_t io_req_size, off_t file
                                 * we can notice that our I/O pipe is running dry and 
                                 * get the next I/O issued before it does go dry
                                 */
-                               if (last_ioread_offset && io_size > ((MAX_UPL_TRANSFER * PAGE_SIZE) / 4))
-                                       io_resid = ((MAX_UPL_TRANSFER * PAGE_SIZE) / 4);
+                               if (last_ioread_offset && io_size > (max_io_size / 4))
+                                       io_resid = (max_io_size / 4);
                                else
                                        io_resid = io_size;
 
@@ -3270,11 +3364,11 @@ cluster_read_copy(vnode_t vp, struct uio *uio, u_int32_t io_req_size, off_t file
                upl_size = (start_offset + io_size + (PAGE_SIZE - 1)) & ~PAGE_MASK;
 
                if (flags & IO_NOCACHE) {
-                       if (upl_size > (MAX_UPL_TRANSFER * PAGE_SIZE))
-                               upl_size = (MAX_UPL_TRANSFER * PAGE_SIZE);
+                       if (upl_size > max_io_size)
+                               upl_size = max_io_size;
                } else {
-                       if (upl_size > (MAX_UPL_TRANSFER * PAGE_SIZE) / 4)
-                               upl_size = (MAX_UPL_TRANSFER * PAGE_SIZE) / 4;
+                       if (upl_size > max_io_size / 4)
+                               upl_size = max_io_size / 4;
                }
                pages_in_upl = upl_size / PAGE_SIZE;
 
@@ -3419,8 +3513,14 @@ cluster_read_copy(vnode_t vp, struct uio *uio, u_int32_t io_req_size, off_t file
                        lck_mtx_lock(cl_mtxp);
 
                        while (iostate.io_issued != iostate.io_completed) {
+                               KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_START,
+                                               iostate.io_issued, iostate.io_completed, 0, 0, 0);
+
                                iostate.io_wanted = 1;
                                msleep((caddr_t)&iostate.io_wanted, cl_mtxp, PRIBIO + 1, "cluster_read_copy", NULL);
+
+                               KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_END,
+                                               iostate.io_issued, iostate.io_completed, 0, 0, 0);
                        }       
                        lck_mtx_unlock(cl_mtxp);
 
@@ -3502,7 +3602,7 @@ cluster_read_copy(vnode_t vp, struct uio *uio, u_int32_t io_req_size, off_t file
                                                rd_ahead_enabled = 1;
                                        prefetch_enabled = 1;
 
-                                       max_rd_size = MAX_PREFETCH;
+                                       max_rd_size = max_prefetch;
                                        last_ioread_offset = 0;
                                }
                        }
@@ -3553,13 +3653,21 @@ cluster_read_direct(vnode_t vp, struct uio *uio, off_t filesize, int *read_type,
         u_int32_t       xsize;
        u_int32_t        devblocksize;
        u_int32_t        mem_alignment_mask;
-       u_int32_t        max_rd_size  = MAX_UPL_TRANSFER * PAGE_SIZE;
-       u_int32_t        max_rd_ahead = MAX_PREFETCH;
+       u_int32_t        max_upl_size;
+       u_int32_t        max_rd_size;
+       u_int32_t        max_rd_ahead;
+
+       max_upl_size = cluster_max_io_size(vp->v_mount, CL_READ);
+
+       max_rd_size = max_upl_size;
+       max_rd_ahead = max_rd_size * 2;
+
 
        if (flags & IO_PASSIVE)
-           bflag = CL_PASSIVE;
+               bflag = CL_PASSIVE;
        else
-           bflag = 0;
+               bflag = 0;
 
        KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 70)) | DBG_FUNC_START,
                     (int)uio->uio_offset, (int)filesize, *read_type, *read_length, 0);
@@ -3627,8 +3735,8 @@ next_dread:
                        max_rd_size  = HARD_THROTTLE_MAXSIZE;
                        max_rd_ahead = HARD_THROTTLE_MAXSIZE - 1;
                } else {
-                       max_rd_size  = MAX_UPL_TRANSFER * PAGE_SIZE;
-                       max_rd_ahead = MAX_PREFETCH;
+                       max_rd_size  = max_upl_size;
+                       max_rd_ahead = max_rd_size * 2;
                }
                io_start = io_size = io_req_size;
 
@@ -3795,8 +3903,14 @@ next_dread:
                lck_mtx_lock(cl_mtxp);
 
                while ((iostate.io_issued - iostate.io_completed) > max_rd_ahead) {
+                       KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_START,
+                                       iostate.io_issued, iostate.io_completed, max_rd_ahead, 0, 0);
+
                        iostate.io_wanted = 1;
                        msleep((caddr_t)&iostate.io_wanted, cl_mtxp, PRIBIO + 1, "cluster_read_direct", NULL);
+
+                       KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_END,
+                                       iostate.io_issued, iostate.io_completed, max_rd_ahead, 0, 0);
                }       
                lck_mtx_unlock(cl_mtxp);
                        
@@ -3856,8 +3970,14 @@ wait_for_dreads:
                lck_mtx_lock(cl_mtxp);
 
                while (iostate.io_issued != iostate.io_completed) {
+                       KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_START,
+                                       iostate.io_issued, iostate.io_completed, 0, 0, 0);
+
                        iostate.io_wanted = 1;
                        msleep((caddr_t)&iostate.io_wanted, cl_mtxp, PRIBIO + 1, "cluster_read_direct", NULL);
+
+                       KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_END,
+                                       iostate.io_issued, iostate.io_completed, 0, 0, 0);
                }       
                lck_mtx_unlock(cl_mtxp);
        }
@@ -3909,9 +4029,9 @@ cluster_read_contig(vnode_t vp, struct uio *uio, off_t filesize, int *read_type,
        int              bflag;
 
        if (flags & IO_PASSIVE)
-           bflag = CL_PASSIVE;
+               bflag = CL_PASSIVE;
        else
-           bflag = 0;
+               bflag = 0;
 
        /*
         * When we enter this routine, we know
@@ -4028,9 +4148,15 @@ next_cread:
                if (iostate.io_issued) {
                        lck_mtx_lock(cl_mtxp);
 
-                       while ((iostate.io_issued - iostate.io_completed) > (3 * MAX_IO_CONTIG_SIZE)) {
+                       while ((iostate.io_issued - iostate.io_completed) > (2 * MAX_IO_CONTIG_SIZE)) {
+                               KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_START,
+                                               iostate.io_issued, iostate.io_completed, 2 * MAX_IO_CONTIG_SIZE, 0, 0);
+
                                iostate.io_wanted = 1;
                                msleep((caddr_t)&iostate.io_wanted, cl_mtxp, PRIBIO + 1, "cluster_read_contig", NULL);
+
+                               KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_END,
+                                               iostate.io_issued, iostate.io_completed, 2 * MAX_IO_CONTIG_SIZE, 0, 0);
                        }       
                        lck_mtx_unlock(cl_mtxp);
                }
@@ -4077,8 +4203,14 @@ wait_for_creads:
        lck_mtx_lock(cl_mtxp);
 
        while (iostate.io_issued != iostate.io_completed) {
+               KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_START,
+                               iostate.io_issued, iostate.io_completed, 0, 0, 0);
+
                iostate.io_wanted = 1;
                msleep((caddr_t)&iostate.io_wanted, cl_mtxp, PRIBIO + 1, "cluster_read_contig", NULL);
+
+               KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 95)) | DBG_FUNC_END,
+                               iostate.io_issued, iostate.io_completed, 0, 0, 0);
        }       
        lck_mtx_unlock(cl_mtxp);
 
@@ -4192,12 +4324,16 @@ advisory_read_ext(vnode_t vp, off_t filesize, off_t f_offset, int resid, int (*c
        int              retval = 0;
        int              issued_io;
        int              skip_range;
-
+       uint32_t         max_io_size;
+       
+       
        if ( !UBCINFOEXISTS(vp))
                return(EINVAL);
 
+       max_io_size = cluster_max_io_size(vp->v_mount, CL_READ);
+       
        KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 60)) | DBG_FUNC_START,
-                    (int)f_offset, resid, (int)filesize, 0, 0);
+                       (int)f_offset, resid, (int)filesize, 0, 0);
 
        while (resid && f_offset < filesize && retval == 0) {
                /*
@@ -4218,8 +4354,8 @@ advisory_read_ext(vnode_t vp, off_t filesize, off_t f_offset, int resid, int (*c
                        io_size = max_size;
 
                upl_size = (start_offset + io_size + (PAGE_SIZE - 1)) & ~PAGE_MASK;
-               if (upl_size > (MAX_UPL_TRANSFER * PAGE_SIZE))
-                       upl_size = MAX_UPL_TRANSFER * PAGE_SIZE;
+               if ((uint32_t)upl_size > max_io_size)
+                       upl_size = max_io_size;
 
                skip_range = 0;
                /*
@@ -4437,7 +4573,10 @@ cluster_try_push(struct cl_writebehind *wbp, vnode_t vp, off_t EOF, int push_fla
         int cl_len;
        int cl_pushed = 0;
        struct cl_wextent l_clusters[MAX_CLUSTERS];
-
+       u_int  max_cluster_pgcount;
+       
+       max_cluster_pgcount = MAX_CLUSTER_SIZE(vp) / PAGE_SIZE;
        /*
         * the write behind context exists and has
         * already been locked...
@@ -4498,7 +4637,7 @@ cluster_try_push(struct cl_writebehind *wbp, vnode_t vp, off_t EOF, int push_fla
                 * of order... if this occurs at the tail of the last cluster, we don't want to fall into the sparse cluster world...
                 */
                for (i = 0; i < MAX_CLUSTERS - 1; i++) {
-                       if ((l_clusters[i].e_addr - l_clusters[i].b_addr) != MAX_CLUSTER_SIZE)
+                       if ((l_clusters[i].e_addr - l_clusters[i].b_addr) != max_cluster_pgcount)
                                goto dont_try;
                        if (l_clusters[i].e_addr != l_clusters[i+1].b_addr)
                                goto dont_try;
index e955664a063acfa4cdf70c1600596aef61434e60..07eaa1480dddddec71556a2a8103f02911f1e5ec 100644 (file)
@@ -508,7 +508,7 @@ add_fsevent(int type, vfs_context_t ctx, ...)
     // (as long as it's not an event type that can never be the
     // same as a previous event)
     //
-    if (type != FSE_CREATE_FILE && type != FSE_DELETE && type != FSE_RENAME && type != FSE_EXCHANGE) {
+    if (type != FSE_CREATE_FILE && type != FSE_DELETE && type != FSE_RENAME && type != FSE_EXCHANGE && type != FSE_CHOWN) {
        void *ptr=NULL;
        int   vid=0, was_str=0, nlen=0;
 
@@ -963,7 +963,7 @@ add_fsevent(int type, vfs_context_t ctx, ...)
                VATTR_WANTED(&va, va_mode);
                VATTR_WANTED(&va, va_uid);
                VATTR_WANTED(&va, va_gid);
-               if ((ret = vnode_getattr(vp, &va, ctx)) != 0) {
+               if ((ret = vnode_getattr(vp, &va, vfs_context_kernel())) != 0) {
                    // printf("add_fsevent: failed to getattr on vp %p (%d)\n", cur->fref.vp, ret);
                    cur->str = NULL;
                    error = EINVAL;
@@ -2551,7 +2551,7 @@ release_pathbuff(char *path)
 }
 
 int
-get_fse_info(struct vnode *vp, fse_info *fse, vfs_context_t ctx)
+get_fse_info(struct vnode *vp, fse_info *fse, __unused vfs_context_t ctx)
 {
     struct vnode_attr va;
 
@@ -2569,7 +2569,7 @@ get_fse_info(struct vnode *vp, fse_info *fse, vfs_context_t ctx)
        }
     }
     
-    if (vnode_getattr(vp, &va, ctx) != 0) {
+    if (vnode_getattr(vp, &va, vfs_context_kernel()) != 0) {
        memset(fse, 0, sizeof(fse_info));
        return -1;
     }
index 74239095159977c07b1a5ce4d044818b9f975aa1..618e4546ceefecb9d437fcf2981ead3bc93fdaa1 100644 (file)
@@ -322,7 +322,7 @@ static int escape_str(char *str, int len, int buflen)
                                *dst-- = '\\';
                                count--;
                        }
-                       *src--;
+                       src--;
                }
        }
 
index df54d26b1db4456b1b5e751ec7428c2f1c91329d..8299bfd335a056552dceeb9a4c7f61f0ebe7da66 100644 (file)
@@ -1126,6 +1126,15 @@ replay_journal(journal *jnl)
                last_sequence_num = blhdr->binfo[0].b.sequence_num;
 
                if (blhdr_offset >= jnl->jhdr->end && jnl->jhdr->start <= jnl->jhdr->end) {
+                   if (last_sequence_num == 0) {
+                       check_past_jnl_end = 0;
+                       printf("jnl: %s: pre-sequence-num-enabled txn's - can not go further than end (%lld %lld).\n",
+                           jnl->jdev_name, jnl->jhdr->start, jnl->jhdr->end);
+                       if (jnl->jhdr->start != jnl->jhdr->end) {
+                           jnl->jhdr->start = jnl->jhdr->end;
+                       }
+                       continue;
+                   }
                    printf("jnl: %s: examining extra transactions starting @ %lld / 0x%llx\n", jnl->jdev_name, blhdr_offset, blhdr_offset);
                }
 
index 535603224f504b7e13817bc507a199f781f0b75e..ca6d9e6b10f5348690630fc52f59eefedb9fd64c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -162,6 +162,7 @@ __private_extern__ int unlink1(vfs_context_t, struct nameidata *, int);
 
 static void vnode_list_add(vnode_t);
 static void vnode_list_remove(vnode_t);
+static void vnode_list_remove_locked(vnode_t);
 
 static errno_t vnode_drain(vnode_t);
 static void vgone(vnode_t, int flags);
@@ -1316,9 +1317,9 @@ loop:
                 * Alias, but not in use, so flush it out.
                 */
                if ((vp->v_iocount == 1) && (vp->v_usecount == 0)) {
-                       vnode_reclaim_internal(vp, 1, 0, 0);
+                       vnode_reclaim_internal(vp, 1, 1, 0);
+                       vnode_put_locked(vp);
                        vnode_unlock(vp);
-                       vnode_put(vp);
                        goto loop;
                }
        }
@@ -1340,8 +1341,8 @@ retnullvp:
                if (vp != NULLVP) {
                        nvp->v_flag |= VALIASED;
                        vp->v_flag |= VALIASED;
+                       vnode_put_locked(vp);
                        vnode_unlock(vp);
-                       vnode_put(vp);
                }
                return (NULLVP);
        }
@@ -1523,8 +1524,33 @@ vnode_list_add(vnode_t vp)
        vnode_list_unlock();
 }
 
+
+/*
+ * remove the vnode from appropriate free list.
+ * called with vnode LOCKED and
+ * the list lock held
+ */
+static void
+vnode_list_remove_locked(vnode_t vp)
+{
+       if (VONLIST(vp)) {
+               /*
+                * the v_listflag field is
+                * protected by the vnode_list_lock
+                */
+               if (vp->v_listflag & VLIST_RAGE)
+                       VREMRAGE("vnode_list_remove", vp);
+               else if (vp->v_listflag & VLIST_DEAD)
+                       VREMDEAD("vnode_list_remove", vp);
+               else
+                       VREMFREE("vnode_list_remove", vp);
+       }
+}
+
+
 /*
  * remove the vnode from appropriate free list.
+ * called with vnode LOCKED
  */
 static void
 vnode_list_remove(vnode_t vp)
@@ -1548,24 +1574,16 @@ vnode_list_remove(vnode_t vp)
                /*
                 * however, we're not guaranteed that
                 * we won't go from the on-list state
-                * to the non-on-list state until we
+                * to the not-on-list state until we
                 * hold the vnode_list_lock... this 
-                * is due to new_vnode removing vnodes
+                * is due to "new_vnode" removing vnodes
                 * from the free list uder the list_lock
                 * w/o the vnode lock... so we need to
                 * check again whether we're currently
                 * on the free list
                 */
-               if (VONLIST(vp)) {
-                       if (vp->v_listflag & VLIST_RAGE)
-                               VREMRAGE("vnode_list_remove", vp);
-                       else if (vp->v_listflag & VLIST_DEAD)
-                               VREMDEAD("vnode_list_remove", vp);
-                       else
-                               VREMFREE("vnode_list_remove", vp);
+               vnode_list_remove_locked(vp);
 
-                       VLISTNONE(vp);
-               }
                vnode_list_unlock();
        }
 }
@@ -1675,7 +1693,7 @@ vnode_rele_internal(vnode_t vp, int fmode, int dont_reenter, int locked)
                        goto defer_reclaim;
                }
                vnode_lock_convert(vp);
-               vnode_reclaim_internal(vp, 1, 0, 0);
+               vnode_reclaim_internal(vp, 1, 1, 0);
        }
        vnode_dropiocount(vp);
        vnode_list_add(vp);
@@ -1799,11 +1817,11 @@ loop:
 #ifdef JOE_DEBUG
                        record_vp(vp, 1);
 #endif
-                       vnode_reclaim_internal(vp, 1, 0, 0);
+                       vnode_reclaim_internal(vp, 1, 1, 0);
                        vnode_dropiocount(vp);
                        vnode_list_add(vp);
-
                        vnode_unlock(vp);
+
                        reclaimed++;
                        mount_lock(mp);
                        continue;
@@ -1819,7 +1837,7 @@ loop:
 #ifdef JOE_DEBUG
                                record_vp(vp, 1);
 #endif
-                               vnode_reclaim_internal(vp, 1, 0, 0);
+                               vnode_reclaim_internal(vp, 1, 1, 0);
                                vnode_dropiocount(vp);
                                vnode_list_add(vp);
                                vnode_unlock(vp);
@@ -1878,6 +1896,10 @@ vclean(vnode_t vp, int flags)
        int already_terminating;
        int clflags = 0;
 
+#if NAMEDSTREAMS
+       int is_namedstream;
+#endif
+
        /*
         * Check to see if the vnode is in use.
         * If so we have to reference it before we clean it out
@@ -1908,6 +1930,10 @@ vclean(vnode_t vp, int flags)
         */
        insmntque(vp, (struct mount *)0);
 
+#if NAMEDSTREAMS
+       is_namedstream = vnode_isnamedstream(vp);
+#endif
+
        vnode_unlock(vp);
 
        OSAddAtomic(1, &num_recycledvnodes);
@@ -1946,6 +1972,15 @@ vclean(vnode_t vp, int flags)
        if (active || need_inactive) 
                VNOP_INACTIVE(vp, ctx);
 
+#if NAMEDSTREAMS
+       /* Delete the shadow stream file before we reclaim its vnode */
+       if ((is_namedstream != 0) &&
+                       (vp->v_parent != NULLVP) &&
+                       ((vp->v_parent->v_mount->mnt_kern_flag & MNTK_NAMED_STREAMS) == 0)) {
+               vnode_relenamedstream(vp->v_parent, vp, ctx);
+       }
+#endif
+
        /*
         * Destroy ubc named reference
         * cluster_release is done on this path
@@ -2029,7 +2064,7 @@ vn_revoke(vnode_t vp, __unused int flags, __unused vfs_context_t a_context)
                                        SPECHASH_LOCK();        
                                        break;
                                }
-                               vnode_reclaim_internal(vq, 0, 0, 0);
+                               vnode_reclaim_internal(vq, 0, 1, 0);
                                vnode_put(vq);
                                SPECHASH_LOCK();
                                break;
@@ -2057,6 +2092,7 @@ vnode_recycle(struct vnode *vp)
                return(0);
        } 
        vnode_reclaim_internal(vp, 1, 0, 0);
+
        vnode_unlock(vp);
 
        return (1);
@@ -2209,9 +2245,9 @@ loop:
                                /*
                                 * Alias, but not in use, so flush it out.
                                 */
-                               vnode_reclaim_internal(vq, 1, 0, 0);
+                               vnode_reclaim_internal(vq, 1, 1, 0);
+                               vnode_put_locked(vq);
                                vnode_unlock(vq);
-                               vnode_put(vq);
                                goto loop;
                        }
                        count += (vq->v_usecount - vq->v_kusecount);
@@ -3265,6 +3301,7 @@ retry:
                mac_vnode_label_init(vp);
 #endif /* MAC */
 
+               vp->v_iocount = 1;
                goto done;
        }
 
@@ -3359,17 +3396,7 @@ retry:
 steal_this_vp:
        vpid = vp->v_id;
 
-       /*
-        * the v_listflag field is
-        * protected by the vnode_list_lock
-        */
-       if (vp->v_listflag & VLIST_DEAD)
-               VREMDEAD("new_vnode", vp);
-       else if (vp->v_listflag & VLIST_RAGE)
-               VREMRAGE("new_vnode", vp);
-       else
-               VREMFREE("new_vnode", vp);
-       VLISTNONE(vp);
+       vnode_list_remove_locked(vp);
 
        vnode_list_unlock();
        vnode_lock_spin(vp);
@@ -3421,7 +3448,6 @@ steal_this_vp:
                if (vp->v_lflag & VL_DEAD)
                        panic("new_vnode: the vnode is VL_DEAD but not VBAD");
                vnode_lock_convert(vp);
-
                (void)vnode_reclaim_internal(vp, 1, 1, 0);
 
                if ((VONLIST(vp)))
@@ -3452,6 +3478,7 @@ steal_this_vp:
        }
 #endif /* MAC */
 
+       vp->v_iocount = 1;
        vp->v_lflag = 0;
        vp->v_writecount = 0;
         vp->v_references = 0;
@@ -3580,7 +3607,7 @@ retry:
 
        if ((vp->v_lflag & (VL_MARKTERM | VL_TERMINATE | VL_DEAD)) == VL_MARKTERM) {
                vnode_lock_convert(vp);
-               vnode_reclaim_internal(vp, 1, 0, 0);
+               vnode_reclaim_internal(vp, 1, 1, 0);
        }
        vnode_dropiocount(vp);
        vnode_list_add(vp);
@@ -3808,9 +3835,19 @@ vnode_reclaim_internal(struct vnode * vp, int locked, int reuse, int flags)
         * once new_vnode drops the list_lock, it will block trying to take
         * the vnode lock until we release it... at that point it will evaluate
         * whether the v_vid has changed
+        * also need to make sure that the vnode isn't on a list where "new_vnode"
+        * can find it after the v_id has been bumped until we are completely done
+        * with the vnode (i.e. putting it back on a list has to be the very last
+        * thing we do to this vnode... many of the callers of vnode_reclaim_internal
+        * are holding an io_count on the vnode... they need to drop the io_count
+        * BEFORE doing a vnode_list_add or make sure to hold the vnode lock until
+        * they are completely done with the vnode
         */
        vnode_list_lock();
+
+       vnode_list_remove_locked(vp);
        vp->v_id++;
+
        vnode_list_unlock();
 
        if (isfifo) {
@@ -3826,7 +3863,7 @@ vnode_reclaim_internal(struct vnode * vp, int locked, int reuse, int flags)
        if (vp->v_data)
                panic("vnode_reclaim_internal: cleaned vnode isn't");
        if (vp->v_numoutput)
-               panic("vnode_reclaim_internal: Clean vnode has pending I/O's");
+               panic("vnode_reclaim_internal: clean vnode has pending I/O's");
        if (UBCINFOEXISTS(vp))
                panic("vnode_reclaim_internal: ubcinfo not cleaned");
        if (vp->v_parent)
@@ -3844,12 +3881,11 @@ vnode_reclaim_internal(struct vnode * vp, int locked, int reuse, int flags)
                vp->v_lflag &= ~VL_TERMWANT;
                wakeup(&vp->v_lflag);
        }
-       if (!reuse && vp->v_usecount == 0) {
+       if (!reuse) {
                /*
                 * make sure we get on the
-                * dead list
+                * dead list if appropriate
                 */
-               vnode_list_remove(vp);
                vnode_list_add(vp);
        }
        if (!locked)
@@ -3857,9 +3893,6 @@ vnode_reclaim_internal(struct vnode * vp, int locked, int reuse, int flags)
 }
 
 /* USAGE:
- * The following api creates a vnode and associates all the parameter specified in vnode_fsparam
- * structure and returns a vnode handle with a reference. device aliasing is handled here so checkalias
- * is obsoleted by this.
  *  vnode_create(int flavor, size_t size, void * param,  vnode_t  *vp)
  */
 int  
@@ -3884,7 +3917,6 @@ vnode_create(int flavor, size_t size, void *data, vnode_t *vpp)
                        vp->v_op = param->vnfs_vops;
                        vp->v_type = param->vnfs_vtype;
                        vp->v_data = param->vnfs_fsnode;
-                       vp->v_iocount = 1;
 
                        if (param->vnfs_markroot)
                                vp->v_flag |= VROOT;
@@ -6532,6 +6564,22 @@ errno_t rmdir_remove_orphaned_appleDouble(vnode_t vp , vfs_context_t ctx, int *
                        cpos += dp->d_reclen;
                        dp = (struct dirent*)cpos;
                }
+               
+               /*
+                * workaround for HFS/NFS setting eofflag before end of file 
+                */
+               if (vp->v_tag == VT_HFS && nentries > 2)
+                       eofflag=0;
+
+               if (vp->v_tag == VT_NFS) {
+                       if (eofflag && !full_erase_flag) {
+                               full_erase_flag = 1;
+                               eofflag = 0;
+                               uio_reset(auio, 0, UIO_SYSSPACE, UIO_READ);
+                       }
+                       else if (!eofflag && full_erase_flag)
+                               full_erase_flag = 0;
+               }
 
        } while (!eofflag);
        /*
@@ -6542,6 +6590,7 @@ errno_t rmdir_remove_orphaned_appleDouble(vnode_t vp , vfs_context_t ctx, int *
 
        uio_reset(auio, 0, UIO_SYSSPACE, UIO_READ);
        eofflag = 0;
+       full_erase_flag = 0;
 
        do {
                siz = UIO_BUFF_SIZE;
index c266535dcde05bb94af70bb0c1593e42dda1f8e8..51b67f399541fb403162bd9c209aa2d2144b783d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 1995-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -3493,6 +3493,10 @@ access(__unused proc_t p, struct access_args *uap, __unused register_t *retval)
        int niopts;
        struct vfs_context context;
 
+#if NAMEDRSRCFORK
+       int is_namedstream = 0;
+#endif
+
        /*
         * Access is defined as checking against the process'
         * real identity, even if operations are checking the
@@ -3517,8 +3521,27 @@ access(__unused proc_t p, struct access_args *uap, __unused register_t *retval)
        if (error)
                goto out;
 
+#if NAMEDRSRCFORK
+       /* Grab reference on the shadow stream file vnode to
+        * force an inactive on release which will mark it for
+        * recycle
+        */
+       if (vnode_isnamedstream(nd.ni_vp) &&
+                       (nd.ni_vp->v_parent != NULLVP) &&
+                       ((nd.ni_vp->v_parent->v_mount->mnt_kern_flag & MNTK_NAMED_STREAMS) == 0)) {
+               is_namedstream = 1;
+               vnode_ref(nd.ni_vp);
+       }
+#endif
+
        error = access1(nd.ni_vp, nd.ni_dvp, uap->flags, &context);
        
+#if NAMEDRSRCFORK
+       if (is_namedstream) {
+               vnode_rele(nd.ni_vp);
+       }
+#endif
+
        vnode_put(nd.ni_vp);
        if (uap->flags & _DELETE_OK)
                vnode_put(nd.ni_dvp);
@@ -3551,6 +3574,7 @@ stat2(vfs_context_t ctx, struct nameidata *ndp, user_addr_t ub, user_addr_t xsec
        void * statptr;
 
 #if NAMEDRSRCFORK
+       int is_namedstream = 0;
        /* stat calls are allowed for resource forks. */
        ndp->ni_cnd.cn_flags |= CN_ALLOWRSRCFORK;
 #endif
@@ -3562,16 +3586,28 @@ stat2(vfs_context_t ctx, struct nameidata *ndp, user_addr_t ub, user_addr_t xsec
                statptr  = (void *)&sb64;
        else
                statptr  = (void *)&sb;
+
+#if NAMEDRSRCFORK
+       /* Grab reference on the shadow stream file vnode to
+        * force an inactive on release which will mark it for
+        * recycle.
+        */
+       if (vnode_isnamedstream(ndp->ni_vp) &&
+                       (ndp->ni_vp->v_parent != NULLVP) &&
+                       ((ndp->ni_vp->v_parent->v_mount->mnt_kern_flag & MNTK_NAMED_STREAMS) == 0)) {
+               is_namedstream = 1;
+               vnode_ref (ndp->ni_vp);
+       }
+#endif
+
        error = vn_stat(ndp->ni_vp, statptr, (xsecurity != USER_ADDR_NULL ? &fsec : NULL), isstat64, ctx);
 
 #if NAMEDRSRCFORK
-       /* Clean up resource fork shadow file if needed. */
-       if ((ndp->ni_vp->v_flag & VISNAMEDSTREAM) && 
-           (ndp->ni_vp->v_parent != NULLVP) &&
-           !(ndp->ni_vp->v_parent->v_mount->mnt_kern_flag & MNTK_NAMED_STREAMS)) {
-               (void) vnode_relenamedstream(ndp->ni_vp->v_parent, ndp->ni_vp, ctx);
+       if (is_namedstream) {
+               vnode_rele (ndp->ni_vp);
        }
 #endif
+       
        vnode_put(ndp->ni_vp);
        nameidone(ndp);
 
index 2d9ced9584a64f9941f834d402b5241d6cbc4542..c7e566bab8d5e8f8d8e6158656afa2f8f990aee6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -482,15 +482,13 @@ vn_close(struct vnode *vp, int flags, vfs_context_t ctx)
 #endif
 
 #if NAMEDRSRCFORK
-       /* Clean up resource fork shadow file if needed. */
+       /* Sync data from resource fork shadow file if needed. */
        if ((vp->v_flag & VISNAMEDSTREAM) && 
            (vp->v_parent != NULLVP) &&
            !(vp->v_parent->v_mount->mnt_kern_flag & MNTK_NAMED_STREAMS)) {
                if (flags & FWASWRITTEN) {
                        (void) vnode_flushnamedstream(vp->v_parent, vp, ctx);
                }
-               /* XXX failure ignored */
-               vnode_relenamedstream(vp->v_parent, vp, ctx);
        }
 #endif
        error = VNOP_CLOSE(vp, flags, ctx);
index 30e62d8ce8c2a9f989d0a7f92a3cd92b1b82434a..5c59cfbc8bfc331fa47710865799ca4c40fe7ddb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -400,7 +400,13 @@ vnode_getnamedstream(vnode_t vp, vnode_t *svpp, const char *name, enum nsoperati
                vnode_lock(svp);
                svp->v_flag |= VISNAMEDSTREAM;
                vnode_unlock(svp);
-               /* Make the file it's parent. */
+               /* Make the file its parent. 
+                * Note: This parent link helps us distinguish vnodes for 
+                * shadow stream files from vnodes for resource fork on file
+                * systems that support named streams natively (both have
+                * VISNAMEDSTREAM set) by allowing access to mount structure
+                * for checking MNTK_NAMED_STREAMS bit at many places in the code
+                */
                vnode_update_identity(svp, vp, NULL, 0, 0, VNODE_UPDATE_PARENT);
        }               
 
@@ -426,8 +432,14 @@ vnode_makenamedstream(vnode_t vp, vnode_t *svpp, const char *name, int flags, vf
                /* Tag the vnode. */
                vnode_lock(svp);
                svp->v_flag |= VISNAMEDSTREAM;
-               vnode_unlock(svp);
-               /* Make the file it's parent. */
+               vnode_unlock(svp);              
+               /* Make the file its parent. 
+                * Note: This parent link helps us distinguish vnodes for 
+                * shadow stream files from vnodes for resource fork on file
+                * systems that support named streams natively (both have
+                * VISNAMEDSTREAM set) by allowing access to mount structure
+                * for checking MNTK_NAMED_STREAMS bit at many places in the code
+                */
                vnode_update_identity(svp, vp, NULL, 0, 0, VNODE_UPDATE_PARENT);
        }
        return (error);
@@ -453,6 +465,15 @@ vnode_removenamedstream(vnode_t vp, vnode_t svp, const char *name, int flags, vf
 
 /*
  * Release a named stream shadow file.
+ *
+ * Note: This function is called from two places where we do not need 
+ * to check if the vnode has any references held before deleting the 
+ * shadow file.  Once from vclean() when the vnode is being reclaimed 
+ * and we do not hold any references on the vnode.  Second time from 
+ * default_getnamedstream() when we get an error during shadow stream 
+ * file initialization so that other processes who are waiting for the 
+ * shadow stream file initialization by the creator will get opportunity 
+ * to create and initialize the file again.
  */
 errno_t
 vnode_relenamedstream(vnode_t vp, vnode_t svp, vfs_context_t context)
@@ -462,9 +483,6 @@ vnode_relenamedstream(vnode_t vp, vnode_t svp, vfs_context_t context)
        char tmpname[48];
        errno_t err;
 
-       if (vnode_isinuse(svp, 1)) {
-               return (EBUSY);
-       }
        cache_purge(svp);
 
        vnode_lock(svp);
@@ -484,11 +502,8 @@ vnode_relenamedstream(vnode_t vp, vnode_t svp, vfs_context_t context)
        if (err != 0) {
                return err;
        }
-       /* Check for busy svp one last time. */
-       if (vnode_isinuse(svp, 1) == 0) {
-               (void) VNOP_REMOVE(dvp, svp, &cn, 0, context);
-               (void) vnode_recycle(svp);
-       }
+       
+       (void) VNOP_REMOVE(dvp, svp, &cn, 0, context);
        vnode_put(dvp);
 
        return (0);
@@ -786,9 +801,12 @@ out:
                        wakeup((caddr_t)&svp->v_parent);
                        vnode_unlock(svp);
                } else {
-                       /* On post create errors, get rid of shadow file. */
-                       (void)vnode_relenamedstream(vp, svp, context);
-
+                       /* On post create errors, get rid of the shadow file. This
+                        * way, if there is another process waiting for initialization
+                        * of the shadow file by the current process, it will wake up
+                        * and retry by creating and initializing the shadow file again.
+                        */
+                       (void) vnode_relenamedstream(vp, svp, context);
                        wakeup((caddr_t)&svp->v_parent);
                }
        }
index 54e6d30c6f1ea5c7c5358da6a38d1f661a94550d..094b6258c16197787fb5dfb7736c8e1a8a90c742 100644 (file)
@@ -527,6 +527,7 @@ task_for_pid(
        if (p->task != TASK_NULL) {
                /* If we aren't root and target's task access port is set... */
                if (!kauth_cred_issuser(kauth_cred_get()) &&
+                       p != current_proc() &&
                        (task_get_task_access_port(p->task, &tfpport) == 0) &&
                        (tfpport != IPC_PORT_NULL)) {
 
index e53ae4e157ca6a076e602827a83b3f885f05f360..c35f33369dfe15107d31c47a6533e5fc355ddf40 100644 (file)
@@ -379,9 +379,9 @@ vnode_pagein(
                goto out;
        }
        if (upl == (upl_t)NULL) {
-               if (size > (MAX_UPL_TRANSFER * PAGE_SIZE)) {
+               if (size > (MAX_UPL_SIZE * PAGE_SIZE)) {
 
-                 panic("vnode_pagein: size = %x\n", size);
+                       panic("vnode_pagein: size = %x\n", size);
 
                        result = PAGER_ERROR;
                        error  = PAGER_ERROR;
@@ -391,7 +391,7 @@ vnode_pagein(
 
                if (upl == (upl_t)NULL) {
 
-                 panic("vnode_pagein: ubc_create_upl failed\n");
+                       panic("vnode_pagein: ubc_create_upl failed\n");
 
                        result =  PAGER_ABSENT;
                        error = PAGER_ABSENT;
index 6f5ee0f98e7b00589edec043211905663dd66dd3..06cd966f52d530ed39d52db1b76adfd0f37c3b0f 100644 (file)
@@ -1,4 +1,4 @@
-9.2.0
+9.3.0
 
 # The first line of this file contains the master version number for the kernel.
 # All other instances of the kernel version in xnu are derived from this file.
index 0365cc0ce9186210fe38b8804b7f72aa4e52b424..f92b863681679a68b04609f35e7517f0b8de0d3e 100644 (file)
@@ -388,7 +388,7 @@ private:
                        Segment64     segment,
                        void         *segments,
                        UInt32        segmentIndex);
-    IOReturn IODMACommand::walkAll(UInt8 op);
+    IOReturn walkAll(UInt8 op);
 
 public:
 
index 1e6632fbb9a5de47c3f3348d84e0f132eb775ab7..1d30052e7b405dd9bdf49b7f348ed70059c4344a 100644 (file)
@@ -33,6 +33,8 @@
 #include <IOKit/IODMAEventSource.h>
 #include <IOKit/IOService.h>
 
+class IODMAEventSource;
+
 class IODMAController : public IOService
 {
   OSDeclareAbstractStructors(IODMAController);
index ce68f6f8607c27485fdbce3c87a894bcffca6417..4659c32471efb50f6ff42caf071c3e3b71043941 100644 (file)
@@ -34,6 +34,8 @@
 #include <IOKit/IODMAController.h>
 #include <IOKit/IOEventSource.h>
 
+class IODMAController;
+
 class IODMAEventSource : public IOEventSource
 {
   OSDeclareDefaultStructors(IODMAEventSource);
index 3322945d541fb0b9ef4d975621ac7daa7413ab3e..a9337bd1d9a3dce91a31f62c51881a72d7af8236 100644 (file)
@@ -56,7 +56,8 @@ enum {
 enum {
   kOFVariablePermRootOnly = 0,
   kOFVariablePermUserRead,
-  kOFVariablePermUserWrite
+  kOFVariablePermUserWrite,
+  kOFVariablePermKernelOnly
 };
 
 class IODTNVRAM : public IOService
index 3e447c36cda531417732007e2f4e0926f21a8244..1d3953308de3df4e1030d6d6eaf3988837a939ec 100644 (file)
@@ -359,7 +359,16 @@ enum {
 #define kIOPMPSLegacyBatteryInfoKey                 "LegacyBatteryInfo"
 #define kIOPMPSBatteryHealthKey                     "BatteryHealth"
 #define kIOPMPSHealthConfidenceKey                  "HealthConfidence"
-#define kIOPMPSCapacityEstimatedKey                "CapacityEstimated"
+#define kIOPMPSCapacityEstimatedKey                    "CapacityEstimated"
+#define kIOPMPSBatteryChargeStatusKey               "ChargeStatus"
+
+// kIOPMBatteryChargeStatusKey may have one of the following values, or may have
+// no value. If kIOPMBatteryChargeStatusKey has a NULL value (or no value) associated with it
+// then charge is proceeding normally. If one of these battery charge status reasons is listed,
+// then the charge may have been interrupted.
+#define kIOPMBatteryChargeStatusTooHot              "HighTemperature"
+#define kIOPMBatteryChargeStatusTooCold             "LowTemperature"
+#define kIOPMBatteryChargeStatusGradient            "BatteryTemperatureGradient"
 
 // Definitions for battery location, in case of multiple batteries.
 // A location of 0 is unspecified
index 610229ce38b0aad2f201b1b7d35d5f40d17957bf..144b4c836f52c811c8052ae92911cc2a449f5bfe 100644 (file)
@@ -84,6 +84,7 @@ iocpu_run_platform_actions(queue_head_t * queue, uint32_t first_priority, uint32
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
+#define kBootCPUNumber  0
 
 static iocpu_platform_action_entry_t * gIOAllActionsQueue;
 static queue_head_t gIOSleepActionQueue;
@@ -293,6 +294,7 @@ void IOCPUSleepKernel(void)
 {
     long cnt, numCPUs;
     IOCPU *target;
+    IOCPU *bootCPU = NULL;
   
     kprintf("IOCPUSleepKernel\n");
 
@@ -327,13 +329,26 @@ void IOCPUSleepKernel(void)
     numCPUs = gIOCPUs->getCount();
     // Sleep the CPUs.
     cnt = numCPUs;
-    while (cnt--) {
-       target = OSDynamicCast(IOCPU, gIOCPUs->getObject(cnt));
-       if (target->getCPUState() == kIOCPUStateRunning) {
-           target->haltCPU();
-       }
+    while (cnt--) 
+    {
+        target = OSDynamicCast(IOCPU, gIOCPUs->getObject(cnt));
+        
+        // We make certain that the bootCPU is the last to sleep
+        // We'll skip it for now, and halt it after finishing the
+        // non-boot CPU's.
+        if (target->getCPUNumber() == kBootCPUNumber) 
+        {
+            bootCPU = target;
+        } else if (target->getCPUState() == kIOCPUStateRunning) 
+        {
+            target->haltCPU();
+        }
     }
 
+    // Now sleep the boot CPU.
+    if (bootCPU)
+        bootCPU->haltCPU();
+
     iocpu_run_platform_actions(&gIOWakeActionQueue, 0, 0UL-1,
                                    NULL, NULL, NULL);
 
@@ -351,11 +366,16 @@ void IOCPUSleepKernel(void)
        IOPanic("gIOWakeActionQueue");
   
     // Wake the other CPUs.
-    for (cnt = 1; cnt < numCPUs; cnt++) {
-       target = OSDynamicCast(IOCPU, gIOCPUs->getObject(cnt));
-       if (target->getCPUState() == kIOCPUStateStopped) {
-           processor_start(target->getMachProcessor());
-       }
+    for (cnt = 0; cnt < numCPUs; cnt++) 
+    {
+        target = OSDynamicCast(IOCPU, gIOCPUs->getObject(cnt));
+        
+        // Skip the already-woken boot CPU.
+        if ((target->getCPUNumber() != kBootCPUNumber)
+            && (target->getCPUState() == kIOCPUStateStopped))
+        {
+            processor_start(target->getMachProcessor());
+        }
     }
 }
 
index f65dbe3b6c8007b775218fb3af5a717410f17f00..b1ce6b51dc2d27a37bcd437ec3cfed891989cf42 100644 (file)
@@ -87,6 +87,15 @@ IOReturn IOInterruptController::registerInterrupt(IOService *nub, int source,
   // Check if the interrupt source can/should be shared.
   canBeShared = vectorCanBeShared(vectorNumber, vector);
   IODTGetInterruptOptions(nub, source, &options);
+#if defined(__i386__) || defined(__x86_64__)
+  int   interruptType;
+  if (OSDynamicCast(IOPlatformDevice, getProvider()) &&
+      (getInterruptType(nub, source, &interruptType) == kIOReturnSuccess) &&
+      (kIOInterruptTypeLevel & interruptType))
+  {
+    options |= kIODTInterruptShared;
+  }
+#endif
   shouldBeShared = canBeShared && (options & kIODTInterruptShared);
   wasAlreadyRegisterd = vector->interruptRegistered;
   
index 43321aac12c2367d21165fa7f50bbd9a230fa6fd..b86f7f65164c1496db20cbdb8298a0942185e78e 100644 (file)
@@ -2429,9 +2429,9 @@ IOMemoryDescriptorMapMemEntry(vm_map_t map, ipc_port_t entry, IOOptionBits optio
     IOReturn err;
     IOMemoryDescriptorMapAllocRef ref;
 
-    ref.sharedMem      = entry;
-    ref.sourceOffset           = offset;
-    ref.options                = options;
+    ref.sharedMem       = entry;
+    ref.sourceOffset = trunc_page_64(offset);
+    ref.options                 = options;
 
     ref.size = length;
 
index 9905c602881ea401cf19e4d33d264bd854ea8103..b4e86780de77447b010c25d504a33b3c425d5d77 100644 (file)
@@ -221,37 +221,35 @@ void IODTNVRAM::sync(void)
 
 bool IODTNVRAM::serializeProperties(OSSerialize *s) const
 {
-  bool                 result;
+  bool                 result, hasPrivilege;
   UInt32               variablePerm;
   const OSSymbol       *key;
-  OSDictionary         *dict, *tmpDict = 0;
+  OSDictionary         *dict = 0, *tmpDict = 0;
   OSCollectionIterator *iter = 0;
   
   if (_ofDict == 0) return false;
   
   // Verify permissions.
-  result = IOUserClient::clientHasPrivilege(current_task(), kIONVRAMPrivilege);
-  if (result != kIOReturnSuccess) {
-    tmpDict = OSDictionary::withCapacity(1);
-    if (tmpDict == 0) return false;
+  hasPrivilege = (kIOReturnSuccess == IOUserClient::clientHasPrivilege(current_task(), kIONVRAMPrivilege));
+
+  tmpDict = OSDictionary::withCapacity(1);
+  if (tmpDict == 0) return false;
     
-    iter = OSCollectionIterator::withCollection(_ofDict);
-    if (iter == 0) return false;
+  iter = OSCollectionIterator::withCollection(_ofDict);
+  if (iter == 0) return false;
     
-    while (1) {
-      key = OSDynamicCast(OSSymbol, iter->getNextObject());
-      if (key == 0) break;
+  while (1) {
+    key = OSDynamicCast(OSSymbol, iter->getNextObject());
+    if (key == 0) break;
       
-      variablePerm = getOFVariablePerm(key);
-      if (variablePerm != kOFVariablePermRootOnly) {
-       tmpDict->setObject(key, _ofDict->getObject(key));
-      }
+    variablePerm = getOFVariablePerm(key);
+    if ((hasPrivilege || (variablePerm != kOFVariablePermRootOnly)) &&
+       ( ! (variablePerm == kOFVariablePermKernelOnly && current_task() != kernel_task) )) {
+      tmpDict->setObject(key, _ofDict->getObject(key));
     }
     dict = tmpDict;
-  } else {
-    dict = _ofDict;
   }
-  
+
   result = dict->serialize(s);
   
   if (tmpDict != 0) tmpDict->release();
@@ -268,11 +266,12 @@ OSObject *IODTNVRAM::getProperty(const OSSymbol *aKey) const
   if (_ofDict == 0) return 0;
   
   // Verify permissions.
+  variablePerm = getOFVariablePerm(aKey);
   result = IOUserClient::clientHasPrivilege(current_task(), kIONVRAMPrivilege);
   if (result != kIOReturnSuccess) {
-    variablePerm = getOFVariablePerm(aKey);
     if (variablePerm == kOFVariablePermRootOnly) return 0;
   }
+  if (variablePerm == kOFVariablePermKernelOnly && current_task() != kernel_task) return 0;
   
   return _ofDict->getObject(aKey);
 }
@@ -301,12 +300,13 @@ bool IODTNVRAM::setProperty(const OSSymbol *aKey, OSObject *anObject)
   if (_ofDict == 0) return false;
   
   // Verify permissions.
+  propPerm = getOFVariablePerm(aKey);
   result = IOUserClient::clientHasPrivilege(current_task(), kIONVRAMPrivilege);
   if (result != kIOReturnSuccess) {
-    propPerm = getOFVariablePerm(aKey);
     if (propPerm != kOFVariablePermUserWrite) return false;
   }
-  
+  if (propPerm == kOFVariablePermKernelOnly && current_task() != kernel_task) return 0;
+
   // Don't allow creation of new properties on old world machines.
   if (getPlatform()->getBootROMType() == 0) {
     if (_ofDict->getObject(aKey) == 0) return false;
@@ -365,11 +365,12 @@ void IODTNVRAM::removeProperty(const OSSymbol *aKey)
   if (_ofDict == 0) return;
   
   // Verify permissions.
+  propPerm = getOFVariablePerm(aKey);
   result = IOUserClient::clientHasPrivilege(current_task(), kIOClientPrivilegeAdministrator);
   if (result != kIOReturnSuccess) {
-    propPerm = getOFVariablePerm(aKey);
     if (propPerm != kOFVariablePermUserWrite) return;
   }
+  if (propPerm == kOFVariablePermKernelOnly && current_task() != kernel_task) return;
   
   // Don't allow removal of properties on old world machines.
   if (getPlatform()->getBootROMType() == 0) return;
@@ -924,6 +925,7 @@ OFVariable gOFVariables[] = {
   {"security-mode", kOFVariableTypeString, kOFVariablePermUserRead, -1},
   {"security-password", kOFVariableTypeData, kOFVariablePermRootOnly, -1},
   {"boot-image", kOFVariableTypeData, kOFVariablePermUserWrite, -1},
+  {"com.apple.System.fp-state", kOFVariableTypeData, kOFVariablePermKernelOnly, -1},
   {0, kOFVariableTypeData, kOFVariablePermUserRead, -1}
 };
 
index 776de768cabd6f28089ebb68e3ea6532c0e653e8..1f9678fd565cd8b0ef76d1b33360c918164e5e0e 100644 (file)
@@ -386,6 +386,7 @@ void IOService::PMinit ( void )
         fDeviceOverrides            = false;
         fMachineState               = kIOPM_Finished;
         fIdleTimerEventSource       = NULL;
+        fIdleTimerMinPowerState     = 0;
         fActivityLock               = IOLockAlloc();
         fClampOn                    = false;
         fStrictTreeOrder            = false;
@@ -1500,10 +1501,10 @@ void IOService::handlePowerDomainWillChangeTo ( IOPMRequest * request )
        PM_ASSERT_IN_GATE();
     OUR_PMLog(kPMLogWillChange, newPowerFlags, 0);
 
-       if (!inPlane(gIOPowerPlane))
+       if (!inPlane(gIOPowerPlane) || !whichParent || !whichParent->getAwaitingAck())
        {
                PM_DEBUG("[%s] %s: not in power tree\n", getName(), __FUNCTION__);
-               return;
+        goto exit_no_ack;
        }
 
        savedParentsKnowState = fParentsKnowState;
@@ -1575,6 +1576,10 @@ void IOService::handlePowerDomainWillChangeTo ( IOPMRequest * request )
                        getName());
                ask_parent( fDesiredPowerState );
        }
+
+exit_no_ack:
+    // Drop the retain from notifyChild().
+    if (whichParent) whichParent->release();
 }
 
 //*********************************************************************************
@@ -1610,10 +1615,10 @@ void IOService::handlePowerDomainDidChangeTo ( IOPMRequest * request )
        PM_ASSERT_IN_GATE();
     OUR_PMLog(kPMLogDidChange, newPowerFlags, 0);
 
-       if (!inPlane(gIOPowerPlane))
+       if (!inPlane(gIOPowerPlane) || !whichParent || !whichParent->getAwaitingAck())
        {
                PM_DEBUG("[%s] %s: not in power tree\n", getName(), __FUNCTION__);
-               return;
+        goto exit_no_ack;
        }
 
        savedParentsKnowState = fParentsKnowState;
@@ -1658,6 +1663,10 @@ void IOService::handlePowerDomainDidChangeTo ( IOPMRequest * request )
                        getName());
                ask_parent( fDesiredPowerState );
        }
+
+exit_no_ack:
+    // Drop the retain from notifyChild().
+    if (whichParent) whichParent->release();
 }
 
 //*********************************************************************************
@@ -3265,6 +3274,7 @@ bool IOService::notifyChild ( IOPowerConnection * theNub, bool is_prechange )
        childRequest = acquirePMRequest( theChild, requestType );
        if (childRequest)
        {
+        theNub->retain();
                childRequest->fArg0 = (void *) fHeadNoteOutputFlags;
                childRequest->fArg1 = (void *) theNub;
                childRequest->fArg2 = (void *) (fHeadNoteState < fCurrentPowerState);
@@ -3688,6 +3698,14 @@ void IOService::all_done ( void )
         if (fCurrentCapabilityFlags & kIOPMStaticPowerValid)
             fCurrentPowerConsumption = powerStatePtr->staticPower;
     }
+
+    // When power rises enough to satisfy the tickle's desire for more power,
+    // the condition preventing idle-timer from dropping power is removed.
+
+    if (fCurrentPowerState >= fIdleTimerMinPowerState)
+    {
+        fIdleTimerMinPowerState = 0;
+    }
 }
 
 //*********************************************************************************
@@ -5543,13 +5561,18 @@ void IOService::executePMRequest( IOPMRequest * request )
 
                                if (request->fArg1)
                                {
-                                       // power rise
-                                       if (fDeviceDesire < (unsigned long) request->fArg0)
+                                       // Power rise from activity tickle.
+                    unsigned long ticklePowerState = (unsigned long) request->fArg0;
+                    if ((fDeviceDesire < ticklePowerState) &&
+                        (ticklePowerState < fNumberOfPowerStates))
+                    {
                                                setDeviceDesire = true;
-                               }
-                               else if (fDeviceDesire)
+                        fIdleTimerMinPowerState = ticklePowerState;
+                    }
+                }
+                               else if (fDeviceDesire > fIdleTimerMinPowerState)
                                {
-                                       // power drop and deviceDesire is not zero
+                                       // Power drop from idle timer expiration.
                                        request->fArg0 = (void *) (fDeviceDesire - 1);
                                        setDeviceDesire = true;
                                }
index 33af8328ada23e1c448bfc301a5e31928e6ce6c8..658730e05f47c9e95b21fd3eb2ba2c95c2d6a2b8 100644 (file)
@@ -172,6 +172,7 @@ private:
         Idle timer's period in seconds.
     */
     unsigned long           IdleTimerPeriod;
+    unsigned long           IdleTimerMinPowerState;
 
     /*! @var DriverDesire
         Power state desired by our controlling driver.
@@ -326,6 +327,7 @@ private:
 #define fActivityLock               pwrMgt->ActivityLock
 #define fIdleTimerEventSource       pwrMgt->IdleTimerEventSource
 #define fIdleTimerPeriod            pwrMgt->IdleTimerPeriod
+#define fIdleTimerMinPowerState     pwrMgt->IdleTimerMinPowerState
 #define fDeviceActive               pwrMgt->DeviceActive
 #define fDeviceActiveTimestamp      pwrMgt->DeviceActiveTimestamp
 #define fDriverDesire               pwrMgt->DriverDesire
index 895f27b986fe2c1107991ca9540746ea680e6991..6346d0c2d08bcf48834f889b6471c8f3b711dd33 100644 (file)
@@ -123,10 +123,10 @@ OSDictionary * IONetworkMatching(  const char * path,
 
        len = strlen( kIODeviceTreePlane ":" );
        maxLen -= len;
-       if( maxLen < 0)
+       if( maxLen <= 0)
            continue;
 
-       strcpy( buf, kIODeviceTreePlane ":" );
+       strlcpy( buf, kIODeviceTreePlane ":", len + 1 );
        comp = buf + len;
 
         // remove parameters following ':' from the path
@@ -136,10 +136,9 @@ OSDictionary * IONetworkMatching(  const char * path,
 
         len = skip - path;
        maxLen -= len;
-       if( maxLen < 0)
+       if( maxLen <= 0)
            continue;
-        strncpy( comp, path, len );
-        comp[ len ] = 0;
+       strlcpy( comp, path, len + 1 );
 
        matching = IOService::serviceMatching( "IONetworkInterface" );
        if( !matching)
@@ -280,6 +279,7 @@ OSDictionary * IODiskMatching( const char * path, char * buf, int maxLen )
     long         partition = -1;
     long                lun = -1;
     char         c;
+    int          len;
 
     // scan the tail of the path for "@unit:partition"
     do {
@@ -317,34 +317,52 @@ OSDictionary * IODiskMatching( const char * path, char * buf, int maxLen )
         if( c || unit == -1 || partition == -1)
             continue;
                
-        maxLen -= strlen( "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" );
-        maxLen -= ( alias ? strlen( alias ) : 0 ) + (look - path);
-        maxLen -= strlen( "/@hhhhhhhh,hhhhhhhh:dddddddddd';}" );
+        len = strlen( "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" );
+        maxLen -= len;
+        if( maxLen <= 0)
+            continue;
 
-        if( maxLen > 0) {
-            sprintf( buf, "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" );
-            comp = buf + strlen( buf );
-                       
-            if( alias) {
-                strcpy( comp, alias );
-                comp += strlen( alias );
-            }
-                       
-            if ( (look - path)) {
-                strncpy( comp, path, look - path);
-                comp += look - path;
-            }
+        snprintf( buf, len + 1, "{" kIOPathMatchKey "='" kIODeviceTreePlane ":" );
+        comp = buf + len;
+
+        if( alias) {
+            len = strlen( alias );
+            maxLen -= len;
+            if( maxLen <= 0)
+                continue;
+
+            strlcpy( comp, alias, len + 1 );
+            comp += len;
+        }
+
+        if ( (look - path)) {
+            len = (look - path);
+            maxLen -= len;
+            if( maxLen <= 0)
+                continue;
+
+            strlcpy( comp, path, len + 1 );
+            comp += len;
+        }
                        
-                       if ( lun != -1 )
-                       {
-                               sprintf ( comp, "/@%lx,%lx:%ld';}", unit, lun, partition );
-                       }
-                       else
-                       {
-               sprintf( comp, "/@%lx:%ld';}", unit, partition );
-            }
-        } else
-            continue;
+        if ( lun != -1 )
+        {
+            len = strlen( "/@hhhhhhhh,hhhhhhhh:dddddddddd';}" );
+            maxLen -= len;
+            if( maxLen <= 0)
+                continue;
+
+            snprintf( comp, len + 1, "/@%lx,%lx:%ld';}", unit, lun, partition );
+        }
+        else
+        {
+            len = strlen( "/@hhhhhhhh:dddddddddd';}" );
+            maxLen -= len;
+            if( maxLen <= 0)
+                continue;
+
+            snprintf( comp, len + 1, "/@%lx:%ld';}", unit, partition );
+        }
                
         return( OSDynamicCast(OSDictionary, OSUnserialize( buf, 0 )) );
 
@@ -371,18 +389,17 @@ OSDictionary * IOOFPathMatching( const char * path, char * buf, int maxLen )
 
        len = strlen( kIODeviceTreePlane ":" );
        maxLen -= len;
-       if( maxLen < 0)
+       if( maxLen <= 0)
            continue;
 
-       strcpy( buf, kIODeviceTreePlane ":" );
+       strlcpy( buf, kIODeviceTreePlane ":", len + 1 );
        comp = buf + len;
 
        len = strlen( path );
        maxLen -= len;
-       if( maxLen < 0)
+       if( maxLen <= 0)
            continue;
-        strncpy( comp, path, len );
-        comp[ len ] = 0;
+       strlcpy( comp, path, len + 1 );
 
        matching = OSDictionary::withCapacity( 1 );
        if( !matching)
@@ -442,7 +459,7 @@ IOService * IOFindMatchingChild( IOService * service )
 
 static int didRam = 0;
 
-kern_return_t IOFindBSDRoot( char * rootName,
+kern_return_t IOFindBSDRoot( char * rootName, unsigned int rootNameSize,
                                dev_t * root, u_int32_t * oflags )
 {
     mach_timespec_t    t;
@@ -726,7 +743,7 @@ kern_return_t IOFindBSDRoot( char * rootName,
 
        iostr = (OSString *) service->getProperty( kIOBSDNameKey );
        if( iostr)
-           strcpy( rootName, iostr->getCStringNoCopy() );
+           strlcpy( rootName, iostr->getCStringNoCopy(), rootNameSize );
        off = (OSNumber *) service->getProperty( kIOBSDMajorKey );
        if( off)
            mjr = off->unsigned32BitValue();
@@ -740,7 +757,7 @@ kern_return_t IOFindBSDRoot( char * rootName,
     } else {
 
        IOLog( "Wait for root failed\n" );
-        strcpy( rootName, "en0");
+        strlcpy( rootName, "en0", rootNameSize );
         flags |= 1;
     }
 
index 0aa46fce4d8f3f54bce52e77327946edda5c0c7a..886094ab6d1dcb802002ba72d4267c46d1bfe0d8 100644 (file)
@@ -966,6 +966,9 @@ bool extractExtensionsFromArchive(const MemoryMapFileInfo * mkext_file_info,
     OSData         * moduleInfo = 0;  // must release
     MkextEntryInfo   module_info;
 
+    IORegistryEntry * root;
+    OSData * checksumObj;
+
     if (vaddr) {
        // addExtensionsFromArchive passes a kernel virtual address
        mkext_data = (mkext_header *)mkext_file_info->paddr;
@@ -1007,9 +1010,9 @@ bool extractExtensionsFromArchive(const MemoryMapFileInfo * mkext_file_info,
         goto finish;
     }
 
-    IORegistryEntry * root = IORegistryEntry::getRegistryRoot();
+    root = IORegistryEntry::getRegistryRoot();
     assert(root);
-    OSData * checksumObj = OSData::withBytes((void *)&checksum,
+    checksumObj = OSData::withBytes((void *)&checksum,
         sizeof(checksum));
     assert(checksumObj);
     if (checksumObj) {
index 0d4989a32099eeab41c0853bcfff146663d45fa2..5ac6c41b40e5444bc03dd67a384cce163bb72ff6 100644 (file)
@@ -110,7 +110,7 @@ endif
 # default architecture configuration = system architecture where you are running make.
 # default machine configuration for ppc = none at this time.
 # default machine configuration for i386 = none at this time.
-# default machine configuration for arm = "S5L8900XRB".
+# default machine configuration for arm = "S5L8900X".
 #
 ifndef TARGET_CONFIGS_UC
 ifdef TARGET_CONFIGS
@@ -211,7 +211,7 @@ export DSYMBUILDDIR = ./Contents/Resources/DWARF/
 # We must not use -fno-keep-inline-functions, or it will remove the dtrace
 # probes from the kernel.
 #
-export CFLAGS_GEN = -static $(DEBUG_CFLAGS) -nostdinc -nostdlib -no-cpp-precomp \
+export CFLAGS_GEN = -static $(DEBUG_CFLAGS) -nostdinc -nostdlib \
        -fno-builtin -finline -msoft-float \
        -fsigned-bitfields $(OTHER_CFLAGS)
 
index 1f4a94e1f5f780cb574001133257872e9b536047..52a26a331d2a2bf89ebcc2fbe788d7241ee32b04 100644 (file)
@@ -104,7 +104,7 @@ panic_ui_initialize(const unsigned char * system_clut)
 
        /* Convert xnu-####.###.obj~### into ####.###~### */
 
-       if (version) {
+       if (version[0]) {
                const char *versionpos = strnstr(version, "xnu-", VERSIONBUF_LEN);
 
                if (versionpos) {
index d2b571f66b82a921623b3282bca713ed8081447f..9c3962bc73a8631cade3d40dbd6fa420589834dd 100644 (file)
@@ -101,7 +101,7 @@ db_term(db_expr_t *valuep)
                valid_symbol = TRUE;
            }
            if (db_allow_unprefixed_hexa && db_radix == 16 &&
-               db_tok_string) {
+               db_tok_string[0]) {
                char *cp;
                db_expr_t value;
                    
index ad8867f53ee2a148a68e9f6c6b739c73021ec13d..b7f108ecf828e5b48f27303e13cdaa5d42e73c2c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2003-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -229,7 +229,8 @@ x86_core_alloc(int cpu)
     core->pcore_num = cpup->cpu_phys_number / lcpus_per_core;
     core->lcore_num = core->pcore_num % cpuid_info()->cpuid_cores_per_package;
 
-    core->flags = X86CORE_FL_PRESENT | X86CORE_FL_READY;
+    core->flags = X86CORE_FL_PRESENT | X86CORE_FL_READY
+               | X86CORE_FL_HALTED | X86CORE_FL_IDLE;
 
     return(core);
 }
index e22f231cf02dfc06c6f39919d72d35072141cfa1..8208cc7ca4b2e8e1d46c5e308276b34f3765b45b 100644 (file)
 #define cpu_to_logical_cpu(cpu)                (cpu_to_lapic[cpu] & CPU_THREAD_MASK)
 #define cpu_is_core_cpu(cpu)           (cpu_to_logical_cpu(cpu) == 0)
 
-#define cpu_to_lcpu(cpu)               (&cpu_datap(cpu)->lcpu)
-#define cpu_to_core(cpu)               (cpu_to_lcpu(cpu)->core)
-#define cpu_to_package(cpu)            (cpu_to_core(cpu)->package)
+#define _cpu_to_lcpu(cpu)              (&cpu_datap(cpu)->lcpu)
+#define _cpu_to_core(cpu)              (_cpu_to_lcpu(cpu)->core)
+#define _cpu_to_package(cpu)           (_cpu_to_core(cpu)->package)
+
+#define cpu_to_lcpu(cpu)               ((cpu_datap(cpu) != NULL) ? _cpu_to_lcpu(cpu) : NULL)
+#define cpu_to_core(cpu)               ((cpu_to_lcpu(cpu) != NULL) ? _cpu_to_lcpu(cpu)->core : NULL)
+#define cpu_to_package(cpu)            ((cpu_to_core(cpu) != NULL) ? _cpu_to_core(cpu)->package : NULL)
 
 /* Fast access: */
 #define x86_lcpu()                     (&current_cpu_datap()->lcpu)
index 5ae9621d52d8dbc20d304fdf936dde3921c17ccf..940a7c649fd62944bbf8641acc86a3968470b768 100644 (file)
@@ -133,6 +133,26 @@ hpet_request(uint32_t cpu)
        return(-1);
     }
 
+    /*
+     * Deal with the case where the CPU # passed in is past the
+     * value specified in cpus=n in boot-args.
+     */
+    if (cpu >= real_ncpus) {
+       enabled = ml_set_interrupts_enabled(FALSE);
+       lcpu = cpu_to_lcpu(cpu);
+       if (lcpu != NULL) {
+           core = lcpu->core;
+           pkg  = core->package;
+
+           if (lcpu->primary) {
+               pkg->flags |= X86PKG_FL_HAS_HPET;
+           }
+       }
+
+       ml_set_interrupts_enabled(enabled);
+       return(0);
+    }
+
     rc = (*hpet_req)(ml_get_apicid(cpu), hpet_arg, &hpetReq);
     if (rc != 0) {
        return(rc);
index 29e35692299bf0bffee0111899248507a5981dec..ac1bb007a7a44a711303f18311f692432b69b032 100644 (file)
@@ -226,30 +226,35 @@ Entry(timer_grab)
  * Nanotime returned in %edx:%eax.
  * Computed from tsc based on the scale factor
  * and an implicit 32 bit shift.
+ * This code must match what _rtc_nanotime_read does in
+ * i386/machine_routines_asm.s.  Failure to do so can
+ * result in "weird" timing results.
  *
  * Uses %eax, %ebx, %ecx, %edx, %esi, %edi.
  */
 #define RNT_INFO               _rtc_nanotime_info
-#define NANOTIME                                                                                                                 \
-0:     movl    RNT_INFO+RNT_TSC_BASE,%esi                                                                      ; \
-       movl    RNT_INFO+RNT_TSC_BASE+4,%edi                                                            ; \
-       rdtsc                                                                                                                           ; \
-       subl    %esi,%eax                                               /* tsc - tsc_base */            ; \
-       sbbl    %edi,%edx                                                                                                       ; \
-       movl    RNT_INFO+RNT_SCALE,%ecx                                                                         ; \
-       movl    %edx,%ebx                                               /* delta * scale */                     ; \
-       mull    %ecx                                                                                                            ; \
-       movl    %ebx,%eax                                                                                                       ; \
-       movl    %edx,%ebx                                                                                                       ; \
-       mull    %ecx                                                                                                            ; \
-       addl    %ebx,%eax                                                                                                       ; \
-       adcl    $0,%edx                                                 /* add carry into hi */         ; \
-       addl    RNT_INFO+RNT_NS_BASE,%eax               /* add ns_base lo */            ; \
-       adcl    RNT_INFO+RNT_NS_BASE+4,%edx             /* add ns_base hi */            ; \
-       cmpl    RNT_INFO+RNT_TSC_BASE,%esi                                                                      ; \
-       jne     0b                                                                      /* repeat if changed */         ; \
-       cmpl    RNT_INFO+RNT_TSC_BASE+4,%edi                                                            ; \
-       jne     0b
+#define NANOTIME                                                       \
+       lea     RNT_INFO,%edi                                           ; \
+0:                                                                     ; \
+       movl    RNT_GENERATION(%edi),%esi       /* being updated? */    ; \
+       testl   %esi,%esi                                               ; \
+       jz      0b                              /* wait until done */   ; \
+       rdtsc                                                           ; \
+       subl    RNT_TSC_BASE(%edi),%eax                                 ; \
+       sbbl    RNT_TSC_BASE+4(%edi),%edx       /* tsc - tsc_base */    ; \
+       movl    RNT_SCALE(%edi),%ecx            /* * scale factor */    ; \
+       movl    %edx,%ebx                                               ; \
+       mull    %ecx                                                    ; \
+       movl    %ebx,%eax                                               ; \
+       movl    %edx,%ebx                                               ; \
+       mull    %ecx                                                    ; \
+       addl    %ebx,%eax                                               ; \
+       adcl    $0,%edx                                                 ; \
+       addl    RNT_NS_BASE(%edi),%eax          /* + ns_base */         ; \
+       adcl    RNT_NS_BASE+4(%edi),%edx                                ; \
+       cmpl    RNT_GENERATION(%edi),%esi       /* check for update */  ; \
+       jne     0b                              /* do it all again */
+
 
 /*
  * Add 64-bit delta in register dreg : areg to timer pointed to by register treg.
index 214a588b75fdd7542a038493466fd19238952a67..79adff8276a65cd0b3075c9adbda8cd873623665 100644 (file)
@@ -242,6 +242,23 @@ static void mca_dump_32bit_state(void)
        kdb_printf("  IA32_MCG_MISC:   0x%08x\n", rdmsr32(IA32_MCG_MISC));
 }
 
+static void
+mca_report_cpu_info(void)
+{
+       uint64_t        microcode;
+       i386_cpu_info_t *infop = cpuid_info();
+
+       // microcode revision is top 32 bits of MSR_IA32_UCODE_REV
+       microcode = rdmsr64(MSR_IA32_UCODE_REV) >> 32;
+       kdb_printf("family: %d model: %d stepping: %d microcode revision %d\n", 
+               infop->cpuid_family,
+               infop->cpuid_model,
+               infop->cpuid_stepping,
+               (uint32_t) microcode);
+       kdb_printf("%s\n", infop->cpuid_brand_string);
+}
+
+
 static const char *mca_threshold_status[] = {
        [THRESHOLD_STATUS_NO_TRACKING]  "No tracking",
        [THRESHOLD_STATUS_GREEN]        "Green",
@@ -327,6 +344,9 @@ mca_dump(void)
        kdb_printf(
                "Machine-check capabilities (cpu %d) 0x%016qx:\n",
                cpu_number(), ia32_mcg_cap.u64);
+
+       mca_report_cpu_info();
+
        kdb_printf(
                " %d error-reporting banks\n%s%s", mca_error_bank_count,
                IF(mca_control_MSR_present,
index 1e41a89d6baa0230838ff89974125187c8f36fac..b7187aecf91ad0f984dd5faa522348c3d4627e88 100644 (file)
@@ -175,7 +175,10 @@ LEXT(_rtc_nanotime_store)
  *
  * This is the same as the commpage nanotime routine, except that it uses the
  * kernel internal "rtc_nanotime_info" data instead of the commpage data.  The two copies
- * of data (one in the kernel and one in user space) are kept in sync by rtc_nanotime_update().
+ * of data (one in the kernel and one in user space) are kept in sync by rtc_clock_napped().
+ *
+ * Warning!  There is another copy of this code in osfmk/i386/locore.s.  The
+ * two versions must be kept in sync with each other!
  *
  * There are actually two versions of the algorithm, one each for "slow" and "fast"
  * processors.  The more common "fast" algorithm is:
index 1c0ee14bbfb225efdf4b835a93c15572456082bd..9b80f01a0961ed09730b46bcdca1adfc978e22a4 100644 (file)
@@ -174,7 +174,7 @@ struct fake_descriptor64 {
 };
 #define        FAKE_UBER64(addr32)     { (uint32_t) (addr32), KERNEL_UBER_BASE_HI32 }
 #define        FAKE_COMPAT(addr32)     { (uint32_t) (addr32), 0x0 }
-#define        UBER64(addr32)          ((addr64_t) addr32 + KERNEL_UBER_BASE)
+#define        UBER64(addr32)          ((addr64_t) (uintptr_t)addr32 + KERNEL_UBER_BASE)
 
 /*
  * Boot-time data for master (or only) CPU
index 3993c5d0567d3f4821abd119b5a2a78c973a9f52..1fa4294f8a5b1da6ee36d43e9cc1a9175f448321 100644 (file)
@@ -116,8 +116,8 @@ typedef struct ipc_mqueue {
 extern int ipc_mqueue_full;
 extern int ipc_mqueue_rcv;
 
-#define IPC_MQUEUE_FULL                (event64_t)&ipc_mqueue_full
-#define IPC_MQUEUE_RECEIVE     (event64_t)&ipc_mqueue_rcv
+#define IPC_MQUEUE_FULL                CAST_EVENT64_T(&ipc_mqueue_full)
+#define IPC_MQUEUE_RECEIVE     CAST_EVENT64_T(&ipc_mqueue_rcv)
 
 /*
  * Exported interfaces
index 88d72cfda3ddd7654e9b8cb26d664cfa01647c71..8452a20099928afce9f48b3c923116d8ee0bd045 100644 (file)
@@ -42,6 +42,8 @@ typedef struct {
     unsigned short             exception_port;
     unsigned char              exception_seq;
     boolean_t                  exception_ack_needed;
+    int                                kdp_cpu;
+    thread_t                   kdp_thread;
 } kdp_glob_t;
 
 extern kdp_glob_t      kdp;
index a513398fe9f85d780e10afaee71e6dcff54e48cd..e47f63dfc09e98ba7d7c2df708372752c1abe0d7 100644 (file)
@@ -1073,7 +1073,9 @@ kdp_raise_exception(
      * do this. I think the client and the host can get out of sync.
      */
     kdp.saved_state = saved_state;
-     
+    kdp.kdp_cpu = cpu_number();
+    kdp.kdp_thread = current_thread();
+
     if (pkt.input)
        kdp_panic("kdp_raise_exception");
 
@@ -1416,22 +1418,19 @@ kdp_get_xnu_version(char *versionbuf)
        char *vptr;
 
        strlcpy(vstr, "custom", 10);
-       if (version) {
-               if (kdp_vm_read(version, versionbuf, 95)) {
-                       versionbuf[94] = '\0';
-                       versionpos = strnstr(versionbuf, "xnu-", 90);
-                       if (versionpos) {
-                               strncpy(vstr, versionpos, sizeof(vstr));
-                               vstr[sizeof(vstr)-1] = '\0';
-                               vptr = vstr + 4; /* Begin after "xnu-" */
-                               while (*vptr && (isdigit(*vptr) || *vptr == '.'))
-                                       vptr++;
+       if (strlcpy(versionbuf, version, 95) < 95) {
+               versionpos = strnstr(versionbuf, "xnu-", 90);
+               if (versionpos) {
+                       strncpy(vstr, versionpos, sizeof(vstr));
+                       vstr[sizeof(vstr)-1] = '\0';
+                       vptr = vstr + 4; /* Begin after "xnu-" */
+                       while (*vptr && (isdigit(*vptr) || *vptr == '.'))
+                               vptr++;
+                       *vptr = '\0';
+                       /* Remove trailing period, if any */
+                       if (*(--vptr) == '.')
                                *vptr = '\0';
-                               /* Remove trailing period, if any */
-                               if (*(--vptr) == '.')
-                                       *vptr = '\0';
-                               retval = 0;
-                       }
+                       retval = 0;
                }
        }
        strlcpy(versionbuf, vstr, KDP_MAXPACKET);
index 07c3145a2fe108b0e1bd398dd1a1f7266a7c867b..35441c45c9544b3ab1f5f097ce57c7c0a130f253 100644 (file)
@@ -153,8 +153,11 @@ kdp_getstate(
     state->esi = saved_state->esi;
     state->ebp = saved_state->ebp;
 
-    if ((saved_state->cs & 0x3) == 0){ /* Kernel State */
-       state->esp = (unsigned int) &saved_state->uesp;
+    if ((saved_state->cs & SEL_PL) == SEL_PL_K) { /* Kernel state? */
+           if (cpu_mode_is64bit())
+                   state->esp = (uint32_t) saved_state->uesp;
+           else
+                   state->esp = ((uint32_t)saved_state) + offsetof(x86_saved_state_t, ss_32) + sizeof(x86_saved_state32_t);
         state->ss = KERNEL_DS;
     } else {
        state->esp = saved_state->uesp;
@@ -193,8 +196,6 @@ kdp_setstate(
     saved_state->frame.eflags |=  ( EFL_IF | EFL_SET );
 #endif
     saved_state->eip = state->eip;
-    saved_state->fs = state->fs;
-    saved_state->gs = state->gs;
 }
 
 
@@ -493,6 +494,7 @@ kdp_ml_get_breakinsn(void)
 {
   return 0xcc;
 }
+
 extern pmap_t kdp_pmap;
 extern uint32_t kdp_src_high32;
 
index 8aaff637f3227a952ef02265b88fdb72df797b47..f0b75b59a1ee4020e9028af80e2b3a47c6e5dcd5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2008 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -190,10 +190,12 @@ void
 ast_check(
        processor_t             processor)
 {
+       thread_t                        thread = processor->active_thread;
+
+       processor->current_pri = thread->sched_pri;
        if (    processor->state == PROCESSOR_RUNNING           ||
                        processor->state == PROCESSOR_SHUTDOWN          ) {
-               thread_t                        thread = processor->active_thread;
-               ast_t                           preempt;
+               ast_t                   preempt;
 
                /*
                 *      Propagate thread ast to processor.
index bfc5528ab30e85f07d4df00170f665f4a54435d3..f75adc50788020efc868d4af537940a83d553cf1 100644 (file)
@@ -63,6 +63,7 @@ typedef       void *event_t;          /* wait event */
 
 typedef uint64_t event64_t;            /* 64 bit wait event */
 #define                NO_EVENT64              ((event64_t) 0)
+#define                CAST_EVENT64_T(a_ptr)   ((event64_t)((uintptr_t)(a_ptr)))
 
 /*
  *     Possible wait_result_t values.
index fac911d115b23117ac302d6abbc1105aec2f99c0..9d88531f21dce61866e62ff54eccf86065cb24c4 100644 (file)
@@ -840,7 +840,7 @@ kmod_control(host_priv_t host_priv,
            /* Get the bundle id, if provided, and discard the buffer sent down.
             */
             if (*data && *dataCount) {
-                (char *)(kmem_alloc(kernel_map, (vm_offset_t *)&kext_id, id_length));
+                kmem_alloc(kernel_map, (vm_offset_t *)&kext_id, id_length);
                 if (!kext_id) {
                     return KERN_FAILURE;
                 }
index 1e7d3e96fc78da756365faa92de93e59878a7bb0..0fa0930c7a4d726209bd4d34d6bb9d68cd6a8543 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -120,8 +120,9 @@ processor_up(
        init_ast_check(processor);
        pset = processor->processor_set;
        pset_lock(pset);
-       pset->processor_count++;
-       enqueue_head(&pset->active_queue, (queue_entry_t)processor);
+       if (++pset->processor_count == 1)
+               pset->low_pri = processor;
+       enqueue_tail(&pset->active_queue, (queue_entry_t)processor);
        processor->state = PROCESSOR_RUNNING;
        (void)hw_atomic_add(&processor_avail_count, 1);
        pset_unlock(pset);
@@ -318,10 +319,9 @@ processor_offline(
 
        pset = processor->processor_set;
        pset_lock(pset);
-       pset->processor_count--;
        processor->state = PROCESSOR_OFF_LINE;
-       if (processor == pset->low_hint)
-               pset->low_hint = PROCESSOR_NULL;
+       if (--pset->processor_count == 0)
+               pset->low_pri = PROCESSOR_NULL;
        (void)hw_atomic_sub(&processor_avail_count, 1);
        pset_unlock(pset);
        ml_cpu_down();
index 6faceb7aaa58dbd44bd96e28c31bedfc399f312b..a922e3688b8ed82997cad9aeec27aa1749415e92 100644 (file)
@@ -435,12 +435,13 @@ __doprnt(
 
                    n = 0;
 
-                   while (*p != '\0') {
-                       if (++n > prec || (length > 0 && n > length))
-                           break;
-
-                       (*putc)(*p++, arg);
-                       nprinted++;
+                   while ((n < prec) && (!(length > 0 && n >= length))) {
+                           if (*p == '\0') {
+                                   break;
+                           }
+                           (*putc)(*p++, arg);
+                           nprinted++;
+                           n++;
                    }
 
                    if (n < length && ladjust) {
index 6564cc97c8f34f96bce28d3fa37808891f0d08db..8ee162fa3158210c25ae0a7b9b54be02ab597b19 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -172,8 +172,7 @@ thread_quantum_expire(
 
                pset_lock(pset);
 
-               pset_hint_low(pset, processor);
-               pset_hint_high(pset, processor);
+               pset_pri_hint(pset, processor, processor->current_pri);
 
                pset_unlock(pset);
        }
index 9ef40cd536b752246159b5b341cd8f6ce1208934..518891c79c9de2144f1babd19ea97f1a765c9fc7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -214,8 +214,7 @@ pset_init(
        queue_init(&pset->idle_queue);
        pset->idle_count = 0;
        pset->processor_count = 0;
-       pset->high_hint = PROCESSOR_NULL;
-       pset->low_hint = PROCESSOR_NULL;
+       pset->low_pri = PROCESSOR_NULL;
        pset_lock_init(pset);
        pset->pset_self = IP_NULL;
        pset->pset_name_self = IP_NULL;
index 50e7ae7f6122940e5693eafcb02b38249241a3f9..5cb479cd1a3bf87b0b5a116ee4708d424aa258fc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -86,8 +86,7 @@ struct processor_set {
        queue_head_t            idle_queue;             /* idle processors */
        int                                     idle_count;
 
-       processor_t                     low_hint;
-       processor_t                     high_hint;
+       processor_t                     low_pri;
 
        int                                     processor_count;
 
@@ -180,28 +179,12 @@ extern processor_t        cpu_to_processor(
 
 /* Update hints */
 
-#define pset_hint_low(ps, p)   \
-MACRO_BEGIN                                                                                                            \
-       if ((ps)->low_hint != PROCESSOR_NULL) {                                         \
-               if ((p) != (ps)->low_hint) {                                                    \
-                       if ((p)->runq.count < (ps)->low_hint->runq.count)       \
-                               (ps)->low_hint = (p);                                                   \
-               }                                                                                                               \
-       }                                                                                                                       \
-       else                                                                                                            \
-               (ps)->low_hint = (p);                                                                   \
-MACRO_END
-
-#define pset_hint_high(ps, p)  \
-MACRO_BEGIN                                                                                                            \
-       if ((ps)->high_hint != PROCESSOR_NULL) {                                        \
-               if ((p) != (ps)->high_hint) {                                                   \
-                       if ((p)->runq.count > (ps)->high_hint->runq.count)      \
-                               (ps)->high_hint = (p);                                                  \
-               }                                                                                                               \
-       }                                                                                                                       \
-       else                                                                                                            \
-               (ps)->high_hint = (p);                                                                  \
+#define pset_pri_hint(ps, p, pri)              \
+MACRO_BEGIN                                                                                            \
+       if ((p) != (ps)->low_pri) {                                                     \
+               if ((pri) < (ps)->low_pri->current_pri)                 \
+                       (ps)->low_pri = (p);                                            \
+       }                                                                                                       \
 MACRO_END
 
 extern void            processor_bootstrap(void) __attribute__((section("__TEXT, initcode")));
index e2027c0662e0f474c01245dffbdd810277da89c6..a12449033818dff09b85b05a390036ed89d99eb4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -144,8 +144,6 @@ uint32_t    sched_fixed_shift;
 uint32_t       sched_run_count, sched_share_count;
 uint32_t       sched_load_average, sched_mach_factor;
 
-void           (*pm_tick_callout)(void)        = NULL;
-
 /* Forwards */
 void wait_queues_init(void) __attribute__((section("__TEXT, initcode")));
 
@@ -164,6 +162,9 @@ static thread_t     choose_thread(
                                        processor_t                     processor);
 
 static thread_t        steal_thread(
+                                       processor_set_t         pset);
+
+static thread_t        steal_processor_thread(
                                        processor_t                     processor);
 
 static void            thread_update_scan(void);
@@ -300,15 +301,9 @@ sched_timebase_init(void)
        /* scheduler tick interval */
        clock_interval_to_absolutetime_interval(USEC_PER_SEC >> SCHED_TICK_SHIFT,
                                                                                                        NSEC_PER_USEC, &abstime);
+       assert((abstime >> 32) == 0 && (uint32_t)abstime != 0);
        sched_tick_interval = abstime;
 
-#if DEBUG
-       printf("Quantum: %d. Smallest quantum: %d. Min Rt/Max Rt: %d/%d."
-               " Tick: %d.\n",
-               std_quantum, min_std_quantum, min_rt_quantum, max_rt_quantum,
-               sched_tick_interval);
-#endif
-
        /*
         * Compute conversion factor from usage to
         * timesharing priorities with 5/8 ** n aging.
@@ -1174,7 +1169,7 @@ thread_select(
        processor_t                     processor)
 {
        processor_set_t         pset = processor->processor_set;
-       thread_t                        new_thread;
+       thread_t                        new_thread = THREAD_NULL;
        boolean_t                       other_runnable;
 
        do {
@@ -1246,8 +1241,7 @@ thread_select(
 
                                /* I am the highest priority runnable (non-idle) thread */
 
-                               pset_hint_low(pset, processor);
-                               pset_hint_high(pset, processor);
+                               pset_pri_hint(pset, processor, processor->current_pri);
 
                                processor->deadline = UINT64_MAX;
 
@@ -1266,14 +1260,18 @@ thread_select(
                 *      No runnable threads, attempt to steal
                 *      from other processors.
                 */
-               if (pset->high_hint != PROCESSOR_NULL && pset->high_hint->runq.count > 0) {
-                       new_thread = steal_thread(pset->high_hint);
-                       if (new_thread != THREAD_NULL) {
-                               pset_unlock(pset);
+               new_thread = steal_thread(pset);
+               if (new_thread != THREAD_NULL)
+                       return (new_thread);
 
-                               return (new_thread);
-                       }
-               }
+               /*
+                *      If other threads have appeared, shortcut
+                *      around again.
+                */
+               if (processor->runq.count > 0 || rt_runq.count > 0)
+                       continue;
+
+               pset_lock(pset);
 
                /*
                 *      Nothing is runnable, so set this processor idle if it
@@ -1284,7 +1282,7 @@ thread_select(
                        processor->state = PROCESSOR_IDLE;
 
                        enqueue_head(&pset->idle_queue, (queue_entry_t)processor);
-                       pset->low_hint = processor;
+                       pset->low_pri = processor;
                        pset->idle_count++;
                }
 
@@ -1354,6 +1352,9 @@ thread_select_idle(
         */
        spllo(); new_thread = processor_idle(thread, processor);
 
+       /*
+        *      Return at splsched.
+        */
        (*thread->sched_call)(SCHED_CALL_UNBLOCK, thread);
 
        thread_lock(thread);
@@ -2019,7 +2020,7 @@ realtime_setrun(
        if (processor->state == PROCESSOR_IDLE) {
                remqueue(&pset->idle_queue, (queue_entry_t)processor);
                pset->idle_count--;
-               enqueue_head(&pset->active_queue, (queue_entry_t)processor);
+               enqueue_tail(&pset->active_queue, (queue_entry_t)processor);
 
                processor->next_thread = thread;
                processor->deadline = thread->realtime.deadline;
@@ -2110,7 +2111,7 @@ processor_setrun(
        if (processor->state == PROCESSOR_IDLE) {
                remqueue(&pset->idle_queue, (queue_entry_t)processor);
                pset->idle_count--;
-               enqueue_head(&pset->active_queue, (queue_entry_t)processor);
+               enqueue_tail(&pset->active_queue, (queue_entry_t)processor);
 
                processor->next_thread = thread;
                processor->deadline = UINT64_MAX;
@@ -2136,8 +2137,6 @@ processor_setrun(
        if (!processor_enqueue(processor, thread, options))
                preempt = AST_NONE;
 
-       pset_hint_high(pset, processor);
-
        if (preempt != AST_NONE) {
                if (processor == current_processor()) {
                        thread_t        self = processor->active_thread;
@@ -2182,7 +2181,7 @@ choose_next_pset(
                nset = next_pset(nset);
        } while (nset->processor_count < 1 && nset != pset);
 
-       return ((nset != pset)? nset: pset);
+       return (nset);
 }
 
 /*
@@ -2202,7 +2201,19 @@ choose_processor(
        thread_t                        thread)
 {
        processor_set_t         nset, cset = pset;
-       processor_t                     processor;
+       processor_t                     processor = thread->last_processor;
+
+       /*
+        *      Prefer the last processor, when appropriate.
+        */
+       if (processor != PROCESSOR_NULL) {
+               if (processor->processor_set != pset ||
+                               processor->state == PROCESSOR_SHUTDOWN || processor->state == PROCESSOR_OFF_LINE)
+                       processor = PROCESSOR_NULL;
+               else
+               if (processor->state == PROCESSOR_IDLE || processor->current_pri < thread->sched_pri)
+                       return (processor);
+       }
 
        /*
         *      Iterate through the processor sets to locate
@@ -2227,23 +2238,26 @@ choose_processor(
 
                                processor = (processor_t)queue_next((queue_entry_t)processor);
                        }
+
+                       processor = PROCESSOR_NULL;
                }
                else {
                        /*
-                        *      Choose the low hint processor in the processor set if available.
+                        *      Check the low hint processor in the processor set if available.
                         */
-                       processor = cset->low_hint;
-                       if (processor != PROCESSOR_NULL &&
-                                               processor->state != PROCESSOR_SHUTDOWN && processor->state != PROCESSOR_OFF_LINE)
-                               return (processor);
+                       if (cset->low_pri != PROCESSOR_NULL &&
+                                               cset->low_pri->state != PROCESSOR_SHUTDOWN && cset->low_pri->state != PROCESSOR_OFF_LINE) {
+                               if (processor == PROCESSOR_NULL || cset->low_pri->current_pri < thread->sched_pri)
+                                       processor = cset->low_pri;
+                       }
 
                        /*
-                        *      Choose any active processor if the hint was invalid.
+                        *      Otherwise, choose an available processor in the set.
                         */
-                       processor = (processor_t)dequeue_head(&cset->active_queue);
-                       if (processor != PROCESSOR_NULL) {
-                               enqueue_tail(&cset->active_queue, (queue_entry_t)processor);
-                               return (processor);
+                       if (processor == PROCESSOR_NULL) {
+                               processor = (processor_t)dequeue_head(&cset->active_queue);
+                               if (processor != PROCESSOR_NULL)
+                                       enqueue_tail(&cset->active_queue, (queue_entry_t)processor);
                        }
                }
 
@@ -2261,16 +2275,48 @@ choose_processor(
        } while (nset != pset);
 
        /*
-        *      If all else fails choose the current processor,
-        *      this routine must return a running processor.
+        *      Make sure that we pick a running processor,
+        *      and that the correct processor set is locked.
         */
-       processor = current_processor();
-       if (cset != processor->processor_set) {
-               pset_unlock(cset);
+       do {
+               /*
+                *      If we haven't been able to choose a processor,
+                *      pick the current one and return it.
+                */
+               if (processor == PROCESSOR_NULL) {
+                       processor = current_processor();
 
-               cset = processor->processor_set;
-               pset_lock(cset);
-       }
+                       /*
+                        *      Check that the correct processor set is
+                        *      returned locked.
+                        */
+                       if (cset != processor->processor_set) {
+                               pset_unlock(cset);
+
+                               cset = processor->processor_set;
+                               pset_lock(cset);
+                       }
+
+                       return (processor);
+               }
+
+               /*
+                *      Check that the processor set for the chosen
+                *      processor is locked.
+                */
+               if (cset != processor->processor_set) {
+                       pset_unlock(cset);
+
+                       cset = processor->processor_set;
+                       pset_lock(cset);
+               }
+
+               /*
+                *      We must verify that the chosen processor is still available.
+                */
+               if (processor->state == PROCESSOR_SHUTDOWN || processor->state == PROCESSOR_OFF_LINE)
+                       processor = PROCESSOR_NULL;
+       } while (processor == PROCESSOR_NULL);
 
        return (processor);
 }
@@ -2329,9 +2375,6 @@ thread_setrun(
                        /*
                         *      Choose a different processor in certain cases.
                         */
-                       if (processor->state == PROCESSOR_SHUTDOWN || processor->state == PROCESSOR_OFF_LINE)
-                               processor = choose_processor(pset, thread);
-                       else
                        if (thread->sched_pri >= BASEPRI_RTQUEUES) {
                                /*
                                 *      If the processor is executing an RT thread with
@@ -2342,38 +2385,26 @@ thread_setrun(
                                        processor = choose_processor(pset, thread);
                        }
                        else
-                       if (processor->state != PROCESSOR_IDLE && pset->idle_count > 0) {
                                processor = choose_processor(pset, thread);
-                       }
-                       else {
-                               processor_set_t         nset = choose_next_pset(pset);
-
-                               /*
-                                *      Bump into a lesser loaded processor set if appropriate.
-                                */
-                               if (pset != nset && (nset->low_hint == PROCESSOR_NULL ||
-                                                                                               (pset->idle_count == 0 && nset->idle_count > 0) ||
-                                                                                                               processor->runq.count > nset->low_hint->runq.count)) {
-                                       pset_unlock(pset);
-
-                                       pset = nset;
-                                       pset_lock(pset);
-
-                                       processor = choose_processor(pset, thread);
-                               }
-                       }
                }
                else {
                        /*
                         *      No Affinity case:
                         *
-                        *      Choose a processor from the current processor set.
+                        *      Utilitize a per task hint to spread threads
+                        *      among the available processor sets.
                         */
-                       processor = current_processor();
-                       pset = processor->processor_set;
+                       task_t          task = thread->task;
+
+                       pset = task->pset_hint;
+                       if (pset == PROCESSOR_SET_NULL)
+                               pset = current_processor()->processor_set;
+
+                       pset = choose_next_pset(pset);
                        pset_lock(pset);
 
                        processor = choose_processor(pset, thread);
+                       task->pset_hint = processor->processor_set;
                }
        }
        else {
@@ -2673,8 +2704,7 @@ run_queue_remove(
  *     choose_thread:
  *
  *     Choose a thread to execute from the run queues
- *     and return it.  May steal a thread from another
- *     processor.
+ *     and return it.
  *
  *     Called with pset scheduling lock and rt lock held,
  *     released on return.
@@ -2689,29 +2719,10 @@ choose_thread(
        if (processor->runq.count > 0 && processor->runq.highq >= rt_runq.highq) {
                simple_unlock(&rt_lock);
 
-               pset_hint_low(pset, processor);
-
-               if (pset->high_hint != PROCESSOR_NULL) {
-                       if (processor != pset->high_hint) {
-                               if (processor->runq.count >= pset->high_hint->runq.count)
-                                       pset->high_hint = processor;
-                               else
-                               if (pset->high_hint->runq.highq > processor->runq.highq) {
-                                       thread = steal_thread(pset->high_hint);
-                                       if (thread != THREAD_NULL) {
-                                               processor->deadline = UINT64_MAX;
-                                               pset_unlock(pset);
-
-                                               return (thread);
-                                       }
-                               }
-                       }
-               }
-               else
-                       pset->high_hint = processor;
-
                thread = run_queue_dequeue(&processor->runq, SCHED_HEADQ);
 
+               pset_pri_hint(pset, processor, thread->sched_pri);
+
                processor->deadline = UINT64_MAX;
                pset_unlock(pset);
 
@@ -2728,21 +2739,22 @@ choose_thread(
 }
 
 /*
- *     steal_thread:
+ *     steal_processor_thread:
  *
- *     Steal a thread from a processor and return it.
+ *     Locate a thread to steal from the processor and
+ *     return it.
  *
  *     Associated pset must be locked.  Returns THREAD_NULL
  *     on failure.
  */
 static thread_t
-steal_thread(
+steal_processor_thread(
        processor_t             processor)
 {
        run_queue_t             rq = &processor->runq;
        queue_t                 queue = rq->queues + rq->highq;
        int                             pri = rq->highq, count = rq->count;
-       thread_t                thread = THREAD_NULL;
+       thread_t                thread;
 
        while (count > 0) {
                thread = (thread_t)queue_first(queue);
@@ -2774,6 +2786,58 @@ steal_thread(
        return (THREAD_NULL);
 }
 
+/*
+ *     Locate and steal a thread, beginning
+ *     at the pset.
+ *
+ *     The pset must be locked, and is returned
+ *     unlocked.
+ *
+ *     Returns the stolen thread, or THREAD_NULL on
+ *     failure.
+ */
+static thread_t
+steal_thread(
+       processor_set_t         pset)
+{
+       processor_set_t         nset, cset = pset;
+       processor_t                     processor;
+       thread_t                        thread;
+
+       do {
+               processor = (processor_t)queue_first(&cset->active_queue);
+               while (!queue_end(&cset->active_queue, (queue_entry_t)processor)) {
+                       if (processor->runq.count > 0) {
+                               thread = steal_processor_thread(processor);
+                               if (thread != THREAD_NULL) {
+                                       remqueue(&cset->active_queue, (queue_entry_t)processor);
+                                       enqueue_tail(&cset->active_queue, (queue_entry_t)processor);
+
+                                       processor->deadline = UINT64_MAX;
+                                       pset_unlock(cset);
+
+                                       return (thread);
+                               }
+                       }
+
+                       processor = (processor_t)queue_next((queue_entry_t)processor);
+               }
+
+               nset = next_pset(cset);
+
+               if (nset != pset) {
+                       pset_unlock(cset);
+
+                       cset = nset;
+                       pset_lock(cset);
+               }
+       } while (nset != pset);
+
+       pset_unlock(cset);
+
+       return (THREAD_NULL);
+}
+
 /*
  *     This is the processor idle loop, which just looks for other threads
  *     to execute.  Processor idle threads invoke this without supplying a
@@ -2803,20 +2867,11 @@ processor_idle(
                                                                        mach_absolute_time(), &PROCESSOR_DATA(processor, idle_state));
        PROCESSOR_DATA(processor, current_state) = &PROCESSOR_DATA(processor, idle_state);
 
-       while (processor->next_thread == THREAD_NULL && processor->runq.count == 0 &&
+       while (processor->next_thread == THREAD_NULL && processor->runq.count == 0 && rt_runq.count == 0 &&
                                (thread == THREAD_NULL || ((thread->state & (TH_WAIT|TH_SUSP)) == TH_WAIT && !thread->wake_active))) {
-               volatile processor_t    hint;
-
                machine_idle();
 
                (void)splsched();
-
-               if (pset->low_hint == PROCESSOR_NULL)
-                       break;
-
-               hint = pset->high_hint;
-               if (hint != PROCESSOR_NULL && hint->runq.count > 0)
-                       break;
        }
 
        timer_switch(&PROCESSOR_DATA(processor, idle_state),
@@ -2867,7 +2922,7 @@ processor_idle(
                pset->idle_count--;
 
                processor->state = PROCESSOR_RUNNING;
-               enqueue_head(&pset->active_queue, (queue_entry_t)processor);
+               enqueue_tail(&pset->active_queue, (queue_entry_t)processor);
        }
        else
        if (state == PROCESSOR_SHUTDOWN) {
@@ -2900,6 +2955,11 @@ processor_idle(
        return (THREAD_NULL);
 }
 
+/*
+ *     Each processor has a dedicated thread which
+ *     executes the idle loop when there is no suitable
+ *     previous context.
+ */
 void
 idle_thread(void)
 {
@@ -3003,9 +3063,6 @@ sched_tick_continue(void)
         */
        thread_update_scan();
 
-       if (pm_tick_callout != NULL)
-           (*pm_tick_callout)();
-
        clock_deadline_for_periodic_event(sched_tick_interval, abstime,
                                                                                                                &sched_tick_deadline);
 
index af059424fc542d18e9eaca425b418cf25d33857a..fd9adc146d16655c866261de8861d30bda179f9d 100644 (file)
        MACRO_END
 
 unsigned int lock_set_event;
-#define LOCK_SET_EVENT ((event64_t)&lock_set_event)
+#define LOCK_SET_EVENT CAST_EVENT64_T(&lock_set_event)
 
 unsigned int lock_set_handoff;
-#define LOCK_SET_HANDOFF ((event64_t)&lock_set_handoff)
+#define LOCK_SET_HANDOFF CAST_EVENT64_T(&lock_set_handoff)
 
 /*
  *     ROUTINE:        lock_set_init           [private]
index 9ddb7e909153e20dc93990bce4b1c4821aafb473..ec121838339cb8c7b3a5af8b1177e45ab36c2511 100644 (file)
@@ -59,7 +59,7 @@
 #include <kern/mach_param.h>
 
 static unsigned int semaphore_event;
-#define SEMAPHORE_EVENT ((event64_t)&semaphore_event)
+#define SEMAPHORE_EVENT CAST_EVENT64_T(&semaphore_event)
 
 zone_t semaphore_zone;
 unsigned int semaphore_max = SEMAPHORE_MAX;
index 2a2fde2d817ef06099385731d0f32ca479a6d1bd..b7dd9076504224de41cecc72cf4ebbaee6764f35 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -355,6 +355,7 @@ task_create_internal(
        new_task->thread_count = 0;
        new_task->active_thread_count = 0;
        new_task->user_stop_count = 0;
+       new_task->pset_hint = PROCESSOR_SET_NULL;
        new_task->role = TASK_UNSPECIFIED;
        new_task->active = TRUE;
        new_task->user_data = NULL;
index 21b65530b53ca1d0b37eeae801282169e8a25af1..e3dae79d908a98332321e8315710630aff890866 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -130,6 +130,7 @@ struct task {
        queue_head_t            threads;
        int                     thread_count;
        uint32_t                active_thread_count;
+       processor_set_t                 pset_hint;
        struct affinity_space   *affinity_space;
 
        /* User-visible scheduling information */
index 763259873baa200d39f2789d29199bb6b1a00afa..3a0a6a08df18e9b1261a0994afbce8c894843ac7 100644 (file)
@@ -267,13 +267,13 @@ xpr_search(
        if (!nxprbufs)
                return;
 
-       n = nxprbufs;
-
        s = splhigh();
        simple_lock(&xprlock);
 
        prev = db_recover;
-       if (_setjmp(db_recover = &db_jmpbuf) == 0)
+       if (_setjmp(db_recover = &db_jmpbuf) == 0) {
+           n = nxprbufs;
+
            for (x = *(struct xprbuf **)xprlast ; n--; ) {
                if (--x < xprbase)
                        x = xprlast - 1;
@@ -289,6 +289,7 @@ xpr_search(
                          x->cpuinfo, x->timestamp);
                db_printf(x->msg, x->arg1,x->arg2,x->arg3,x->arg4,x->arg5);
            }
+       }
        db_recover = prev;
 
        simple_unlock(&xprlock);
index 65c57e54046866d7432da75e73ff1c50557f50ca..01b462b12fa574effb6bdac24b2e4e52a9845cbe 100644 (file)
@@ -380,6 +380,7 @@ typedef struct memory_object_attr_info      memory_object_attr_info_data_t;
  */
 #ifdef PRIVATE
 #define MAX_UPL_TRANSFER 256
+#define MAX_UPL_SIZE    4096
 
 struct upl_page_info {
        ppnum_t         phys_addr;      /* physical page index number */
index 4301c37dd7b546ff0d570e5a79285daa14a024f4..72ccbeeafb6cfb38fc7ba85dda72783c4631fc8a 100644 (file)
@@ -362,7 +362,7 @@ pmap_bootstrap(uint64_t msize, vm_offset_t *first_avail, unsigned int kmapsize)
         * Initialize kernel pmap
         */
        kernel_pmap = &kernel_pmap_store;
-       kernel_pmap_phys = (addr64_t)&kernel_pmap_store;
+       kernel_pmap_phys = (addr64_t)(uintptr_t)&kernel_pmap_store;
        cursor_pmap = &kernel_pmap_store;
 
        kernel_pmap->pmap_link.next = (queue_t)kernel_pmap;             /* Set up anchor forward */
index 781eb38a19d0ba8b0c8092b8fc5bb733cf54f618..c5629bf1b7ad135a4eb3ed489511b60ba013580c 100644 (file)
@@ -165,7 +165,7 @@ ppc_init(
        BootProcInfo.VMX_owner = NULL;
        BootProcInfo.pp_cbfr = console_per_proc_alloc(TRUE);
        BootProcInfo.rtcPop = EndOfAllTime;
-       BootProcInfo.pp2ndPage = (addr64_t)&BootProcInfo;       /* Initial physical address of the second page */
+       BootProcInfo.pp2ndPage = (addr64_t)(uintptr_t)&BootProcInfo;    /* Initial physical address of the second page */
 
        BootProcInfo.pms.pmsStamp = 0;                                          /* Dummy transition time */
        BootProcInfo.pms.pmsPop = EndOfAllTime;                         /* Set the pop way into the future */
index af15986864de23ae89d0d150b51e3256e6671e6c..49d177d8032069ce113116685afa7024c17e6337 100644 (file)
@@ -296,12 +296,12 @@ void ppc_vm_init(uint64_t mem_limit, boot_args *args)
 
        }
 
-       pmap_enter(kernel_pmap, (vm_map_offset_t)&sharedPage,
+       pmap_enter(kernel_pmap, (vm_map_offset_t)(uintptr_t)&sharedPage,
                (ppnum_t)&sharedPage >> 12, /* Make sure the sharedPage is mapped */
                VM_PROT_READ|VM_PROT_WRITE, 
                VM_WIMG_USE_DEFAULT, TRUE);
 
-       pmap_enter(kernel_pmap, (vm_map_offset_t)&lowGlo.lgVerCode,
+       pmap_enter(kernel_pmap, (vm_map_offset_t)(uintptr_t)&lowGlo.lgVerCode,
                (ppnum_t)&lowGlo.lgVerCode >> 12,       /* Make sure the low memory globals are mapped */
                VM_PROT_READ|VM_PROT_WRITE, 
                VM_WIMG_USE_DEFAULT, TRUE);
index a86f6d3ccb699e9af15072c94313241f1ca1c93e..42f85716216488a362f511fac5943d540345600e 100644 (file)
@@ -144,8 +144,8 @@ void savearea_init(vm_offset_t addr) {
 
        saveanchor.savefree    = 0;                                                     /* Remember the start of the free chain */
        saveanchor.savefreecnt = 0;                                                     /* Remember the length */
-       saveanchor.savepoolfwd = (addr64_t)&saveanchor;         /* Remember pool forward */
-       saveanchor.savepoolbwd = (addr64_t)&saveanchor;         /* Remember pool backward */
+       saveanchor.savepoolfwd = (addr64_t)(uintptr_t)&saveanchor;              /* Remember pool forward */
+       saveanchor.savepoolbwd = (addr64_t)(uintptr_t)&saveanchor;              /* Remember pool backward */
 
        save =  addr;                                                                           /* Point to the whole block of blocks */        
 
@@ -179,8 +179,8 @@ void savearea_init(vm_offset_t addr) {
        saveanchor.savefree = 0;                                                        /* Remember the start of the free chain */
        saveanchor.savefreecnt = 0;                                                     /* Remember the length */
        saveanchor.saveadjust = 0;                                                      /* Set none needed yet */
-       saveanchor.savepoolfwd = (addr64_t)&saveanchor;         /* Remember pool forward */
-       saveanchor.savepoolbwd = (addr64_t)&saveanchor;         /* Remember pool backward */
+       saveanchor.savepoolfwd = (addr64_t)(uintptr_t)&saveanchor;              /* Remember pool forward */
+       saveanchor.savepoolbwd = (addr64_t)(uintptr_t)&saveanchor;              /* Remember pool backward */
 
        for(i=0; i < InitialSaveBloks; i++) {                           /* Initialize the saveareas */
 
index 809d71e177940e8343a2eeb30bd8f7ce466a8418..f5275261d3d525fe1eb11b1c4ba819a9028d45ec 100644 (file)
@@ -536,7 +536,8 @@ vm_fault_zero_page(vm_page_t m, boolean_t no_zero_fill)
 
        if (!IP_VALID(memory_manager_default) &&
                (m->object->purgable == VM_PURGABLE_DENY ||
-                m->object->purgable == VM_PURGABLE_NONVOLATILE)) {
+                m->object->purgable == VM_PURGABLE_NONVOLATILE ||
+                m->object->purgable == VM_PURGABLE_VOLATILE )) {
                vm_page_lock_queues();
 
                 queue_enter(&vm_page_queue_throttled, m, vm_page_t, pageq);
index 218a491572ee4721b76a12765d6501861c83f53f..a573d49eac4a726824881f931b4be1fc2c39f616 100644 (file)
@@ -6406,7 +6406,9 @@ vm_object_range_op(
        if (range) {
                if (offset > offset_end)
                        offset = offset_end;
-               *range = offset - offset_beg;
+               if(offset > offset_beg)
+                       *range = offset - offset_beg;
+               else *range=0;
        }
        return KERN_SUCCESS;
 }
index 4052f9673b84a6cc31a8a29f4d8074ec045f1a89..3319ca213c152c079d192e7460775fdcd865ffcc 100644 (file)
@@ -620,7 +620,7 @@ extern void         vm_page_validate_cs(vm_page_t   page);
                mem->inactive = FALSE;                          \
                if (!mem->fictitious) {                         \
                        vm_page_inactive_count--;               \
-                       vm_purgeable_q_advance_all(1);          \
+                       vm_purgeable_q_advance_all();           \
                } else {                                        \
                        assert(mem->phys_page ==                \
                               vm_page_fictitious_addr);        \
index 0f3e790a689bb5a55ac1c3df21c89711e36621ef..18ff4907a49e9489ea1305ada1d10122230c3358 100644 (file)
@@ -1347,7 +1347,7 @@ vm_pageout_scan_delay:
                        percent_avail = 
                                (vm_page_active_count + vm_page_inactive_count + 
                                 vm_page_speculative_count + vm_page_free_count +
-                                vm_page_purgeable_count ) * 100 /
+                                (IP_VALID(memory_manager_default)?0:vm_page_purgeable_count) ) * 100 /
                                atop_64(max_mem);
                        if (percent_avail >= (kern_memorystatus_level + 5) || 
                            percent_avail <= (kern_memorystatus_level - 5)) {
@@ -1498,7 +1498,7 @@ consider_inactive:
                                                     vm_page_t, pageq);
                                        m->throttled = FALSE;
                                        vm_page_throttled_count--;
-
+                                       
                                        /*
                                         * not throttled any more, so can stick
                                         * it on the inactive queue.
@@ -1514,7 +1514,7 @@ consider_inactive:
 #if MACH_ASSERT
                                        vm_page_inactive_count--;       /* balance for purgeable queue asserts */
 #endif
-                                       vm_purgeable_q_advance_all(1);
+                                       vm_purgeable_q_advance_all();
 
                                        queue_enter(&vm_page_queue_inactive, m,
                                                    vm_page_t, pageq);
@@ -1596,7 +1596,7 @@ consider_inactive:
 #if MACH_ASSERT
                                vm_page_inactive_count--;       /* balance for purgeable queue asserts */
 #endif
-                               vm_purgeable_q_advance_all(1);
+                               vm_purgeable_q_advance_all();
 
                                queue_enter(&vm_page_queue_inactive, m,
                                            vm_page_t, pageq);
@@ -1630,7 +1630,7 @@ consider_inactive:
                        m->inactive = FALSE;
                        if (!m->fictitious)
                                vm_page_inactive_count--;
-                               vm_purgeable_q_advance_all(1);
+                               vm_purgeable_q_advance_all();
                }
 
                /* If the object is empty, the page must be reclaimed even if dirty or used. */
@@ -1835,7 +1835,8 @@ throttle_inactive:
                        if (!IP_VALID(memory_manager_default) &&
                                object->internal && 
                                (object->purgable == VM_PURGABLE_DENY ||
-                                object->purgable == VM_PURGABLE_NONVOLATILE)) {
+                                object->purgable == VM_PURGABLE_NONVOLATILE ||
+                                object->purgable == VM_PURGABLE_VOLATILE )) {
                                queue_enter(&vm_page_queue_throttled, m,
                                            vm_page_t, pageq);
                                m->throttled = TRUE;
@@ -2612,11 +2613,11 @@ vm_object_upl_request(
                panic("vm_object_upl_request: contiguous object specified\n");
 
 
-       if ((size / PAGE_SIZE) > MAX_UPL_TRANSFER)
-               size = MAX_UPL_TRANSFER * PAGE_SIZE;
+       if ((size / PAGE_SIZE) > MAX_UPL_SIZE)
+               size = MAX_UPL_SIZE * PAGE_SIZE;
 
        if ( (cntrl_flags & UPL_SET_INTERNAL) && page_list_count != NULL)
-               *page_list_count = MAX_UPL_TRANSFER;
+               *page_list_count = MAX_UPL_SIZE;
 
        if (cntrl_flags & UPL_SET_INTERNAL) {
                if (cntrl_flags & UPL_SET_LITE) {
@@ -3550,8 +3551,8 @@ REDISCOVER_ENTRY:
                        return KERN_SUCCESS;
                }
                if (entry->object.vm_object == VM_OBJECT_NULL || !entry->object.vm_object->phys_contiguous) {
-                       if ((*upl_size/page_size) > MAX_UPL_TRANSFER)
-                                       *upl_size = MAX_UPL_TRANSFER * page_size;
+                       if ((*upl_size/page_size) > MAX_UPL_SIZE)
+                                       *upl_size = MAX_UPL_SIZE * page_size;
                }
                /*
                 *      Create an object if necessary.
@@ -4715,12 +4716,12 @@ vm_object_iopl_request(
        else
                prot = VM_PROT_READ | VM_PROT_WRITE;
 
-       if (((size/page_size) > MAX_UPL_TRANSFER) && !object->phys_contiguous)
-               size = MAX_UPL_TRANSFER * page_size;
+       if (((size/page_size) > MAX_UPL_SIZE) && !object->phys_contiguous)
+               size = MAX_UPL_SIZE * page_size;
 
        if (cntrl_flags & UPL_SET_INTERNAL) {
                if (page_list_count != NULL)
-                       *page_list_count = MAX_UPL_TRANSFER;
+                       *page_list_count = MAX_UPL_SIZE;
        }
        if (((cntrl_flags & UPL_SET_INTERNAL) && !(object->phys_contiguous)) &&
            ((page_list_count != NULL) && (*page_list_count != 0) && *page_list_count < (size/page_size)))
index dfd80266f956420d3e8592214e335f8297a4e4f6..ab0f00a42360c7170e5d4eba0744158c910813a8 100644 (file)
 
 #include <mach/mach_types.h>
 #include <vm/vm_page.h>
+#include <vm/vm_kern.h>                /* kmem_alloc */
 #include <vm/vm_purgeable_internal.h>
 #include <sys/kdebug.h>
+#include <kern/sched_prim.h>
 
 struct token {
        token_cnt_t     count;
        token_idx_t     next;
 };
 
-struct token    tokens[MAX_VOLATILE];
+struct token   *tokens;
+token_idx_t    token_q_max_cnt = 0;
+vm_size_t      token_q_cur_size = 0;
 
 token_idx_t     token_free_idx = 0;            /* head of free queue */
 token_idx_t     token_init_idx = 1;            /* token 0 is reserved!! */
@@ -43,6 +47,8 @@ int             available_for_purge = 0;      /* increase when ripe token
                                                 * token removed protect with
                                                 * page_queue_lock */
 
+static int token_q_allocating = 0;             /* flag to singlethread allocator */
+
 struct purgeable_q purgeable_queues[PURGEABLE_Q_TYPE_MAX];
 
 #define TOKEN_ADD           0x40/* 0x100 */
@@ -52,7 +58,6 @@ struct purgeable_q purgeable_queues[PURGEABLE_Q_TYPE_MAX];
 #define OBJECT_ADDED        0x50/* 0x140 */
 #define OBJECT_REMOVED      0x51/* 0x144 */
 
-static void     vm_purgeable_q_advance(uint32_t num_pages, purgeable_q_t queue);
 static token_idx_t vm_purgeable_token_remove_first(purgeable_q_t queue);
 
 #if MACH_ASSERT
@@ -96,16 +101,78 @@ vm_purgeable_token_add(purgeable_q_t queue)
        token_idx_t     token;
        enum purgeable_q_type i;
 
-       if (token_init_idx < MAX_VOLATILE) {    /* lazy token array init */
-               token = token_init_idx;
-               token_init_idx++;
-       } else if (token_free_idx) {
+find_available_token:
+
+       if (token_free_idx) {                           /* unused tokens available */
                token = token_free_idx;
                token_free_idx = tokens[token_free_idx].next;
-       } else {
-               return KERN_FAILURE;
+       } else if (token_init_idx < token_q_max_cnt) {  /* lazy token array init */
+               token = token_init_idx;
+               token_init_idx++;
+       } else {                                        /* allocate more memory */
+               /* Wait if another thread is inside the memory alloc section */
+               while(token_q_allocating) {
+                       wait_result_t res = thread_sleep_mutex((event_t)&token_q_allocating, 
+                                                              &vm_page_queue_lock,
+                                                              THREAD_UNINT);
+                       if(res != THREAD_AWAKENED) return KERN_ABORTED;
+               };
+               
+               /* Check whether memory is still maxed out */
+               if(token_init_idx < token_q_max_cnt)
+                       goto find_available_token;
+               
+               /* Still no memory. Allocate some. */
+               token_q_allocating = 1;
+               
+               /* Drop page queue lock so we can allocate */
+               vm_page_unlock_queues();
+               
+               struct token *new_loc;
+               vm_size_t alloc_size = token_q_cur_size + PAGE_SIZE;
+               kern_return_t result;
+               
+               if (token_q_cur_size) {
+                       result=kmem_realloc(kernel_map, (vm_offset_t)tokens, token_q_cur_size,
+                                           (vm_offset_t*)&new_loc, alloc_size);
+               } else {
+                       result=kmem_alloc(kernel_map, (vm_offset_t*)&new_loc, alloc_size);
+               }
+               
+               vm_page_lock_queues();
+               
+               if (result) {
+                       /* Unblock waiting threads */
+                       token_q_allocating = 0;
+                       thread_wakeup((event_t)&token_q_allocating);
+                       return result;
+               }
+               
+               /* If we get here, we allocated new memory. Update pointers and
+                * dealloc old range */
+               struct token *old_tokens=tokens;
+               tokens=new_loc;
+               vm_size_t old_token_q_cur_size=token_q_cur_size;
+               token_q_cur_size=alloc_size;
+               token_q_max_cnt = token_q_cur_size / sizeof(struct token);
+               assert (token_init_idx < token_q_max_cnt);      /* We must have a free token now */
+               
+               if (old_token_q_cur_size) {     /* clean up old mapping */
+                       vm_page_unlock_queues();
+                       /* kmem_realloc leaves the old region mapped. Get rid of it. */
+                       kmem_free(kernel_map, (vm_offset_t)old_tokens, old_token_q_cur_size);
+                       vm_page_lock_queues();
+               }
+               
+               /* Unblock waiting threads */
+               token_q_allocating = 0;
+               thread_wakeup((event_t)&token_q_allocating);
+               
+               goto find_available_token;
        }
-
+       
+       assert (token);
+       
        /*
         * the new pagecount we got need to be applied to all queues except
         * obsolete
@@ -234,12 +301,12 @@ vm_purgeable_token_delete_first(purgeable_q_t queue)
 
 
 void
-vm_purgeable_q_advance_all(uint32_t num_pages)
+vm_purgeable_q_advance_all()
 {
        /* check queue counters - if they get really large, scale them back.
         * They tend to get that large when there is no purgeable queue action */
        int i;
-       if(token_new_pagecount > (INT32_MAX >> 1))      /* a system idling years might get there */
+       if(token_new_pagecount > (TOKEN_NEW_PAGECOUNT_MAX >> 1))        /* a system idling years might get there */
        {
                for (i = PURGEABLE_Q_TYPE_FIFO; i < PURGEABLE_Q_TYPE_MAX; i++) {
                        int64_t pages = purgeable_queues[i].new_pages += token_new_pagecount;
@@ -251,62 +318,60 @@ vm_purgeable_q_advance_all(uint32_t num_pages)
        }
        
        /*
-        * don't need to advance obsolete queue - all items are ripe there,
+        * Decrement token counters. A token counter can be zero, this means the
+        * object is ripe to be purged. It is not purged immediately, because that
+        * could cause several objects to be purged even if purging one would satisfy
+        * the memory needs. Instead, the pageout thread purges one after the other
+        * by calling vm_purgeable_object_purge_one and then rechecking the memory
+        * balance.
+        *
+        * No need to advance obsolete queue - all items are ripe there,
         * always
         */
-       vm_purgeable_q_advance(num_pages, &purgeable_queues[PURGEABLE_Q_TYPE_FIFO]);
-       vm_purgeable_q_advance(num_pages, &purgeable_queues[PURGEABLE_Q_TYPE_LIFO]);
-}
+       for (i = PURGEABLE_Q_TYPE_FIFO; i < PURGEABLE_Q_TYPE_MAX; i++) {
+               purgeable_q_t queue = &purgeable_queues[i];
+               uint32_t num_pages = 1;
+               
+               /* Iterate over tokens as long as there are unripe tokens. */
+               while (queue->token_q_unripe) {
+                       if (tokens[queue->token_q_unripe].count && num_pages)
+                       {
+                               tokens[queue->token_q_unripe].count -= 1;
+                               num_pages -= 1;
+                       }
 
-/*
- * Decrements token counters. A token counter can be zero, this means the
- * object is ripe to be purged. It is not purged immediately, because that
- * could cause several objects to be purged even if purging one would satisfy
- * the memory needs. Instead, the pageout thread purges one after the other
- * by calling vm_purgeable_object_purge_one and then rechecking the memory
- * balance.
- */
-static void
-vm_purgeable_q_advance(uint32_t num_pages, purgeable_q_t queue)
-{
-       /* Iterate over tokens as long as there are unripe tokens. */
-       while (queue->token_q_unripe) {
-               int             min = (tokens[queue->token_q_unripe].count < num_pages) ?
-               tokens[queue->token_q_unripe].count : num_pages;
-               tokens[queue->token_q_unripe].count -= min;
-               num_pages -= min;
-
-               if (tokens[queue->token_q_unripe].count == 0) {
-                       queue->token_q_unripe = tokens[queue->token_q_unripe].next;
-                       available_for_purge++;
-                       KERNEL_DEBUG_CONSTANT((MACHDBG_CODE(DBG_MACH_VM, TOKEN_QUEUE_ADVANCE)),
-                                             queue->type,
-                                         tokens[queue->token_q_head].count,    /* num pages on new
-                                                                                * first token */
-                                             0,
-                                             available_for_purge,
-                                             0);
-                       continue;       /* One token ripened. Make sure to
-                                        * check the next. */
+                       if (tokens[queue->token_q_unripe].count == 0) {
+                               queue->token_q_unripe = tokens[queue->token_q_unripe].next;
+                               available_for_purge++;
+                               KERNEL_DEBUG_CONSTANT((MACHDBG_CODE(DBG_MACH_VM, TOKEN_QUEUE_ADVANCE)),
+                                                     queue->type,
+                                                     tokens[queue->token_q_head].count,        /* num pages on new
+                                                                                        * first token */
+                                                     0,
+                                                     available_for_purge,
+                                                     0);
+                               continue;       /* One token ripened. Make sure to
+                                                * check the next. */
+                       }
+                       if (num_pages == 0)
+                               break;  /* Current token not ripe and no more pages.
+                                        * Work done. */
                }
-               if (num_pages == 0)
-                       break;  /* Current token not ripe and no more pages.
-                                * Work done. */
-       }
 
-       /*
-        * if there are no unripe tokens in the queue, decrement the
-        * new_pages counter instead new_pages can be negative, but must be
-        * canceled out by token_new_pagecount -- since inactive queue as a
-        * whole always contains a nonnegative number of pages
-        */
-       if (!queue->token_q_unripe) {
-               queue->new_pages -= num_pages;
-               assert((int32_t) token_new_pagecount + queue->new_pages >= 0);
-       }
+               /*
+                * if there are no unripe tokens in the queue, decrement the
+                * new_pages counter instead new_pages can be negative, but must be
+                * canceled out by token_new_pagecount -- since inactive queue as a
+                * whole always contains a nonnegative number of pages
+                */
+               if (!queue->token_q_unripe) {
+                       queue->new_pages -= num_pages;
+                       assert((int32_t) token_new_pagecount + queue->new_pages >= 0);
+               }
 #if MACH_ASSERT
-       vm_purgeable_token_check_queue(queue);
+               vm_purgeable_token_check_queue(queue);
 #endif
+       }
 }
 
 /*
index e225da651463a5770d8b5d3f398db77afc9f04b9..95f90db5d3f41b61a1dfdf3448e28e95d3634887 100644 (file)
@@ -49,12 +49,10 @@ enum purgeable_q_type {
 #if (CONFIG_TOKEN_QUEUE_SMALL == 1)
 typedef uint16_t token_idx_t;
 typedef uint16_t token_cnt_t;
-#define MAX_VOLATILE 0x01000
 #define TOKEN_COUNT_MAX UINT16_MAX
 #else
 typedef uint32_t token_idx_t;
 typedef uint32_t token_cnt_t;
-#define MAX_VOLATILE 0x10000
 #define TOKEN_COUNT_MAX UINT32_MAX
 #endif
 
@@ -76,6 +74,7 @@ typedef struct purgeable_q * purgeable_q_t;
 
 extern struct purgeable_q purgeable_queues[PURGEABLE_Q_TYPE_MAX];
 extern int32_t token_new_pagecount;
+#define TOKEN_NEW_PAGECOUNT_MAX INT32_MAX
 extern int available_for_purge;
 
 
@@ -84,10 +83,9 @@ extern int available_for_purge;
  * the token counters are protected by the vm_page_queue_lock, since they're
  * mostly used in that context and we don't want to do a lot of extra locking
  * the purgeable page queues are protected by a separate lock since they're
- * mostly user on a user context and we don't want any contention with the
+ * mostly used on a user context and we don't want any contention with the
  * pageout daemon.
  */
-
 decl_mutex_data(,vm_purgeable_queue_lock)
 
 /* add a new token to queue. called by vm_object_purgeable_control */
@@ -98,19 +96,18 @@ kern_return_t vm_purgeable_token_add(purgeable_q_t queue);
 void vm_purgeable_token_delete_first(purgeable_q_t queue);
 
 /*
- * decrement token counters. the function will call the object purger if a
- * token expires.
+ * decrement token counters.
+ * enter with page queue locked
  */
-/* enter with page queue locked */
-void vm_purgeable_q_advance_all(uint32_t num_pages);
+void vm_purgeable_q_advance_all(void);
 
-/* the object purger. purges the specified number of objects from memory. */
+/* the object purger. purges the next eligible object from memory. */
 void vm_purgeable_object_purge_one(void);
 
 /* insert purgeable object into queue */
 void vm_purgeable_object_add(vm_object_t object, purgeable_q_t queue, int group);
 
-/* Look for page belonging to object. If found, put on inactive queue. */
+/* look for object. If found, remove from purgeable queue. */
 purgeable_q_t vm_purgeable_object_remove(vm_object_t object);
 
 #endif /* __VM_PURGEABLE_INTERNAL__ */
index f50356d0db2ed33cabd628ba2b394e03d3715883..313549ecfb062e468a3d8e4540bb1ac770d88ed1 100644 (file)
@@ -1765,7 +1765,7 @@ return_page_from_cpu_list:
        percent_avail = 
                (vm_page_active_count + vm_page_inactive_count + 
                 vm_page_speculative_count + vm_page_free_count +
-                vm_page_purgeable_count ) * 100 /
+                (IP_VALID(memory_manager_default)?0:vm_page_purgeable_count) ) * 100 /
                atop_64(max_mem);
        if (percent_avail <= (kern_memorystatus_level - 5)) {
                kern_memorystatus_level = percent_avail;
@@ -1879,7 +1879,7 @@ vm_page_release(
        percent_avail = 
                (vm_page_active_count + vm_page_inactive_count + 
                 vm_page_speculative_count + vm_page_free_count +
-                vm_page_purgeable_count ) * 100 /
+                (IP_VALID(memory_manager_default)?0:vm_page_purgeable_count)  ) * 100 /
                atop_64(max_mem);
        if (percent_avail >= (kern_memorystatus_level + 5)) {
                kern_memorystatus_level = percent_avail;
@@ -2256,7 +2256,7 @@ vm_page_free_list(
                percent_avail = 
                        (vm_page_active_count + vm_page_inactive_count + 
                         vm_page_speculative_count + vm_page_free_count +
-                        vm_page_purgeable_count ) * 100 /
+                        (IP_VALID(memory_manager_default)?0:vm_page_purgeable_count)  ) * 100 /
                        atop_64(max_mem);
                if (percent_avail >= (kern_memorystatus_level + 5)) {
                        kern_memorystatus_level = percent_avail;
@@ -2372,7 +2372,8 @@ vm_page_unwire(
                if (!IP_VALID(memory_manager_default) && 
                        mem->dirty && mem->object->internal && 
                        (mem->object->purgable == VM_PURGABLE_DENY ||
-                        mem->object->purgable == VM_PURGABLE_NONVOLATILE)) {
+                        mem->object->purgable == VM_PURGABLE_NONVOLATILE ||
+                        mem->object->purgable == VM_PURGABLE_VOLATILE)) {
                        queue_enter(&vm_page_queue_throttled, mem, vm_page_t, pageq);
                        vm_page_throttled_count++;
                        mem->throttled = TRUE;
@@ -2447,7 +2448,8 @@ vm_page_deactivate(
                if (!IP_VALID(memory_manager_default) &&
                        m->dirty && m->object->internal &&
                        (m->object->purgable == VM_PURGABLE_DENY ||
-                        m->object->purgable == VM_PURGABLE_NONVOLATILE)) {
+                        m->object->purgable == VM_PURGABLE_NONVOLATILE ||
+                        m->object->purgable == VM_PURGABLE_VOLATILE )) {
                        queue_enter(&vm_page_queue_throttled, m, vm_page_t, pageq);
                        m->throttled = TRUE;
                        vm_page_throttled_count++;
@@ -2522,7 +2524,8 @@ vm_page_activate(
                if (!IP_VALID(memory_manager_default) && 
                        !m->fictitious && m->dirty && m->object->internal && 
                        (m->object->purgable == VM_PURGABLE_DENY ||
-                        m->object->purgable == VM_PURGABLE_NONVOLATILE)) {
+                        m->object->purgable == VM_PURGABLE_NONVOLATILE ||
+                        m->object->purgable == VM_PURGABLE_VOLATILE )) {
                        queue_enter(&vm_page_queue_throttled, m, vm_page_t, pageq);
                        m->throttled = TRUE;
                        vm_page_throttled_count++;
@@ -3431,7 +3434,7 @@ cpm_allocate(
        percent_avail = 
                (vm_page_active_count + vm_page_inactive_count + 
                 vm_page_speculative_count + vm_page_free_count +
-                vm_page_purgeable_count ) * 100 /
+                (IP_VALID(memory_manager_default)?0:vm_page_purgeable_count)  ) * 100 /
                atop_64(max_mem);
        if (percent_avail <= (kern_memorystatus_level - 5)) {
                kern_memorystatus_level = percent_avail;
index d7d0a3cd4f7548d6318b38fa40414022cb51f878..1d9fd94bd72b0c4d4b48295d69088d5767179480 100644 (file)
@@ -31,7 +31,7 @@ extern boolean_t isargsep( char c);
 extern int argstrcpy(char *from, char *to);
 extern int getval(char *s, int *val);
 
-int argstrcpy2(char *from,char *to, unsigned maxlen);
+static int argstrcpy2(char *from,char *to, unsigned maxlen);
 
 #define        NUM     0
 #define        STR     1
@@ -159,7 +159,7 @@ argstrcpy(
        return(i);
 }
 
-int
+static int
 argstrcpy2(
        char *from, 
        char *to,
index fdf66fb53ba1944f40de607125e1e86c96a21d2c..f526ed0276a3ee58714c8648017c0a3ea5f73f5e 100644 (file)
@@ -21,4 +21,3 @@ int main()
        /* unrecognized type */
        return -1;
 }
-
index 237d14cdce8cea749e1c6439e4b42dd6eeb33ad6..3ef0137ae798bbf3a0bc6dc5df84f9e63cf02840 100644 (file)
 #include <sys/types.h>
 #include <sys/ucred.h>
 #include <sys/uio.h>
+#include "tests.h"
+
+#if !TARGET_OS_EMBEDDED
 #include <XILog/XILog.h>
+#endif
 
-#include "tests.h"
 
 
 /* our table of tests to run  */
@@ -132,12 +135,13 @@ int main( int argc, const char * argv[] )
        struct stat             my_stat_buf;
        char                    my_buffer[64];
        /* vars for XILog */
+#if !TARGET_OS_EMBEDDED
        XILogRef                logRef;
        char                    *logPath = "";
        char                    *config = NULL;
        int                             echo = 0;
        int                             xml = 0;
-       
+#endif
        sranddev( );                            /* set up seed for our random name generator */
        g_cmd_namep = argv[0];
        
@@ -223,12 +227,13 @@ int main( int argc, const char * argv[] )
                        g_skip_setuid_tests = 1;
                        continue;
                }
+#if !TARGET_OS_EMBEDDED        
                if ( strcmp( argv[i], "-x" ) == 0 ||
                         strcmp( argv[i], "-xilog" ) == 0 ) {
                        g_xilog_active = 1;
                        continue;
                }
-
+#endif
                printf( "invalid argument \"%s\" \n", argv[i] );
                usage( );
        }
@@ -253,7 +258,7 @@ int main( int argc, const char * argv[] )
                list_all_tests( );
                return 0;
        }
-
+#if !TARGET_OS_EMBEDDED
        if (g_xilog_active == 1) {      
                logRef = XILogOpenLogExtended( logPath, "xnu_quick_test", "com.apple.coreos", 
                                                                                config, xml, echo, NULL, "ResultOwner", 
@@ -263,6 +268,7 @@ int main( int argc, const char * argv[] )
                        exit(-1);
                }
        }
+#endif
        
        /* build a test target directory that we use as our path to create any test
         * files and directories.
@@ -288,30 +294,38 @@ int main( int argc, const char * argv[] )
                my_testp = &g_tests[i];
                if ( my_testp->test_run_it == 0 || my_testp->test_routine == NULL )
                        continue;
+#if !TARGET_OS_EMBEDDED        
                if (g_xilog_active == 1) {      
                        XILogBeginTestCase( logRef, my_testp->test_infop, my_testp->test_infop );       
                        XILogMsg( "test #%d - %s \n", (i + 1), my_testp->test_infop );
                }
+#endif
                printf( "test #%d - %s \n", (i + 1), my_testp->test_infop );
                my_err = my_testp->test_routine( my_testp->test_input );
                if ( my_err != 0 ) {
                        printf("\t--> FAILED \n");
+#if !TARGET_OS_EMBEDDED        
                        if (g_xilog_active == 1) {      
                                XILogMsg("SysCall %s failed", my_testp->test_infop);
                                XILogErr("Result %d", my_err);
                        }
+#endif
                        my_failures++;
                        if ( my_failures > g_max_failures ) {
+#if !TARGET_OS_EMBEDDED        
                                if (g_xilog_active == 1) {      
                                        XILogEndTestCase( logRef, kXILogTestPassOnErrorLevel );
                                }
+#endif
                                printf( "\n too many failures - test aborted \n" );
                                goto exit_this_routine;
                        }
                }
+#if !TARGET_OS_EMBEDDED        
                if (g_xilog_active == 1) {      
                        XILogEndTestCase(logRef, kXILogTestPassOnErrorLevel);
                }
+#endif
        }
        
 exit_this_routine:
@@ -321,9 +335,11 @@ exit_this_routine:
        /* clean up our test directory */
        rmdir( &g_target_path[0] );     
 
+#if !TARGET_OS_EMBEDDED        
        if (g_xilog_active == 1) {      
                XILogCloseLog(logRef);
        }
+#endif
        
     return 0;
 } /* main */
@@ -513,7 +529,9 @@ static void usage( void )
        printf( "\t -r[un] 1, 3, 10 - 19            # run specific tests.  enter individual test numbers and/or range of numbers.  use -list to list tests.   \n" );
        printf( "\t -s[kip]                         # skip setuid tests   \n" );
        printf( "\t -t[arget] TARGET_PATH           # path to directory where tool will create test files.  defaults to \"/tmp/\"   \n" );
+#if !TARGET_OS_EMBEDDED        
        printf( "\t -x[ilog]                        # use XILog\n");
+#endif
        printf( "\nexamples:  \n" );
        printf( "--- Place all test files and directories at the root of volume \"test_vol\" --- \n" );
        printf( "%s -t /Volumes/test_vol/ \n", (my_ptr != NULL) ? my_ptr : g_cmd_namep );
index 8cdb458d02af76c5d1c33f050d3c6a3429550945..6fc3a0ed2b93ee9ac9212aa79d2cf019d3529df7 100644 (file)
@@ -1,3 +1,14 @@
+Product=$(shell tconf --product)
+Embedded=$(shell tconf --test TARGET_OS_EMBEDDED)
+
+ifeq "$(Embedded)" "YES"
+XILogFLAG =
+else
+XILogFLAG = -framework XILog
+endif
+
+CC=gcc $(SYSROOT)
+
 ifdef RC_BUILDIT
 DOING_BUILDIT=yes
 endif
@@ -23,6 +34,14 @@ else
        
        ifndef ARCH
                ARCH=i386 x86_64 ppc ppc64
+               # this hack should be removed once tconf gets
+               # <rdar://problem/5667139>
+               ifeq "$(Product)" "iPhone"
+               ARCH=armv6
+               endif
+               ifeq "$(Product)" "AppleTV"
+               ARCH=i386
+               endif
        endif
        
        ifdef ARCH
@@ -33,7 +52,8 @@ else
 endif
 
 CFLAGS += -g -I /System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/ -F/AppleInternal/Library/Frameworks/ $(MORECFLAGS)
-LIBFLAGS = -I /System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/ -F/AppleInternal/Library/Frameworks/ -framework XILog
+LIBFLAGS = -I /System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders -F/AppleInternal/Library/Frameworks/ $(XILogFLAG)
+
 #CFLAGS+= $(MY_ARCH) -g -D_POSIX_C_SOURCE=200112L
 
 MY_OBJECTS = $(OBJROOT)/main.o $(OBJROOT)/memory_tests.o $(OBJROOT)/misc.o \
@@ -43,7 +63,7 @@ MY_OBJECTS = $(OBJROOT)/main.o $(OBJROOT)/memory_tests.o $(OBJROOT)/misc.o \
 
 xnu_quick_test : $(OBJROOT) $(DSTROOT) $(MY_OBJECTS) helpers
        sudo rm -rf $(DSTROOT)/xnu_quick_test
-       cc $(MY_ARCH) $(LIBFLAGS) -o $(DSTROOT)/xnu_quick_test $(MY_OBJECTS)
+       $(CC) $(MY_ARCH) $(LIBFLAGS) -o $(DSTROOT)/xnu_quick_test $(MY_OBJECTS)
        sudo chown root $(DSTROOT)/xnu_quick_test
        sudo chmod 4755 $(DSTROOT)/xnu_quick_test
 
@@ -52,17 +72,30 @@ xnu_quick_test : $(OBJROOT) $(DSTROOT) $(MY_OBJECTS) helpers
 # helper processes for the 64-bit version of xnu_quick_test to test the conversion
 # from a 32-bit process to a 64-bit process.
 helpers : helpers/sleep.c helpers/launch.c helpers/arch.c helperdir $(OBJROOT)/misc.o
-       gcc -arch ppc                               helpers/sleep.c -o $(DSTROOT)/helpers/sleep-ppc32
-       gcc -arch i386                              helpers/sleep.c -o $(DSTROOT)/helpers/sleep-i386
-       gcc -arch x86_64 -pagezero_size 0x100000000 helpers/sleep.c -o $(DSTROOT)/helpers/sleep-x86_64-4G
-       gcc -arch x86_64 -pagezero_size 0x1000      helpers/sleep.c -o $(DSTROOT)/helpers/sleep-x86_64-4K
-       gcc -arch ppc64  -pagezero_size 0x100000000 helpers/sleep.c -o $(DSTROOT)/helpers/sleep-ppc64-4G
-       gcc -arch ppc64  -pagezero_size 0x1000      helpers/sleep.c -o $(DSTROOT)/helpers/sleep-ppc64-4K
-       gcc $(LIBFLAGS) -arch i386      $(OBJROOT)/misc.o helpers/launch.c -o $(DSTROOT)/helpers/launch-i386
-       gcc $(LIBFLAGS) -arch x86_64    $(OBJROOT)/misc.o helpers/launch.c -o $(DSTROOT)/helpers/launch-x86_64
-       gcc $(LIBFLAGS) -arch ppc       $(OBJROOT)/misc.o helpers/launch.c -o $(DSTROOT)/helpers/launch-ppc
-       gcc $(LIBFLAGS) -arch ppc64     $(OBJROOT)/misc.o helpers/launch.c -o $(DSTROOT)/helpers/launch-ppc64
-       gcc -arch ppc -arch ppc64 -arch i386 -arch x86_64 helpers/arch.c -o $(DSTROOT)/helpers/arch
+ifneq "$(Product)" "iPhone"
+       $(CC) -arch i386                              helpers/sleep.c -o $(DSTROOT)/helpers/sleep-i386
+endif
+ifeq "$(Product)" "MacOSX"
+       $(CC) -arch x86_64 -pagezero_size 0x100000000 helpers/sleep.c -o $(DSTROOT)/helpers/sleep-x86_64-4G
+       $(CC) -arch x86_64 -pagezero_size 0x1000      helpers/sleep.c -o $(DSTROOT)/helpers/sleep-x86_64-4K
+       $(CC) -arch ppc                               helpers/sleep.c -o $(DSTROOT)/helpers/sleep-ppc32
+       $(CC) -arch ppc64  -pagezero_size 0x100000000 helpers/sleep.c -o $(DSTROOT)/helpers/sleep-ppc64-4G
+       $(CC) -arch ppc64  -pagezero_size 0x1000      helpers/sleep.c -o $(DSTROOT)/helpers/sleep-ppc64-4K
+endif
+ifneq "$(Product)" "iPhone"
+       $(CC) $(LIBFLAGS) -arch i386    $(OBJROOT)/misc.o helpers/launch.c -o $(DSTROOT)/helpers/launch-i386
+endif
+ifeq "$(Product)" "MacOS"
+       $(CC) $(LIBFLAGS) -arch x86_64  $(OBJROOT)/misc.o helpers/launch.c -o $(DSTROOT)/helpers/launch-x86_64
+       $(CC) $(LIBFLAGS) -arch ppc     $(OBJROOT)/misc.o helpers/launch.c -o $(DSTROOT)/helpers/launch-ppc
+       $(CC) $(LIBFLAGS) -arch ppc64   $(OBJROOT)/misc.o helpers/launch.c -o $(DSTROOT)/helpers/launch-ppc64
+       $(CC) $(MY_ARCH)        helpers/arch.c -o $(DSTROOT)/helpers/arch
+endif
+ifeq "$(Product)" "iPhone"
+       $(CC) -arch armv6 helpers/sleep.c -o $(DSTROOT)/helpers/sleep-arm
+       $(CC) $(LIBFLAGS) -arch armv6 $(OBJROOT)/misc.o helpers/launch.c -o $(DSTROOT)/helpers/launch-arm
+endif
+       
        
 helperdir :
        mkdir -p $(DSTROOT)/helpers
@@ -74,32 +107,35 @@ $(DSTROOT) :
        mkdir -p $(DSTROOT);
 
 INCLUDES = /Developer/SDKs/Purple/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders/
-       
 
 $(OBJROOT)/main.o : main.c tests.h
-       cc $(CFLAGS) -c main.c  -o $@
+       $(CC) $(CFLAGS) -c main.c  -o $@
        
 $(OBJROOT)/memory_tests.o : memory_tests.c tests.h
-       cc $(CFLAGS) -c memory_tests.c  -o $@
+       $(CC) $(CFLAGS) -c memory_tests.c  -o $@
 
 # misc.o has to be built 4-way for the helpers to link
 $(OBJROOT)/misc.o : misc.c tests.h
-       cc -arch i386 -arch x86_64 -arch ppc -arch ppc64 $(CFLAGS) -c misc.c   -o $@
+ifeq "$(Product)" "iPhone"
+       $(CC) -arch armv6 $(CFLAGS) -c misc.c   -o $@
+else
+       $(CC) -arch i386 -arch x86_64 -arch ppc -arch ppc64 $(CFLAGS) -c misc.c   -o $@
+endif
        
 $(OBJROOT)/sema_tests.o : sema_tests.c tests.h
-       cc $(CFLAGS) -c sema_tests.c   -o $@
+       $(CC) $(CFLAGS) -c sema_tests.c   -o $@
        
 $(OBJROOT)/shared_memory_tests.o : shared_memory_tests.c tests.h
-       cc $(CFLAGS) -c shared_memory_tests.c   -o $@
+       $(CC) $(CFLAGS) -c shared_memory_tests.c   -o $@
 
 $(OBJROOT)/socket_tests.o : socket_tests.c tests.h
-       cc $(CFLAGS) -c socket_tests.c   -o $@
+       $(CC) $(CFLAGS) -c socket_tests.c   -o $@
 
 $(OBJROOT)/tests.o : tests.c tests.h
-       cc $(CFLAGS) -c tests.c    -o $@
+       $(CC) $(CFLAGS) -c tests.c    -o $@
 
 $(OBJROOT)/xattr_tests.o : xattr_tests.c tests.h
-       cc $(CFLAGS) -c xattr_tests.c    -o $@
+       $(CC) $(CFLAGS) -c xattr_tests.c    -o $@
 
 
 ifndef DOING_BUILDIT
@@ -109,4 +145,3 @@ clean :
        sudo rm -f $(DSTROOT)/helpers/*
        rm -f $(OBJROOT)/*.o
 endif
-
index b274ddfd124779d19aef0f8d0c1de0275824ad7b..fc962b22f1157a8e8003dd1eb69d902e3fdf8f03 100644 (file)
@@ -246,7 +246,7 @@ int do_spawn_test(int arch, int shouldfail)
        posix_spawnattr_t attr;
 
        char * args[] = {"helpers/arch", NULL};
-
+       
        my_err = posix_spawnattr_init(&attr);
        if (my_err != 0) {
                printf("posix_spawnattr_init failed\n");
@@ -320,6 +320,9 @@ int get_architecture()
        case CPU_TYPE_POWERPC64:
                rval = POWERPC;
                break;
+       case CPU_TYPE_ARM:
+               rval = ARM;
+               break;
        }
 
 finished:
index ccb154971753b0782fa7e34d44be8a54e2460f25..279d427448a25415712d20295c079e0218d77773 100644 (file)
@@ -17,6 +17,7 @@
  */
 int sema_tests( void * the_argp ) 
 {
+#if !TARGET_OS_EMBEDDED
        int                             my_err, i;
        int                             my_sem_id = -1;
        union semun             my_sem_union;
@@ -93,6 +94,10 @@ test_passed_exit:
                semctl( my_sem_id, 0, IPC_RMID, my_sem_union );
        }
        return( my_err );
+#else
+       printf( "\t--> Not supported on EMBEDDED TARGET\n" );
+       return 0;
+#endif
 }
 
 
index 362c777edd4d74da0d85493e7342510263ae1911..b7c197800c307b35fd21785d42acf0f068bc21da 100644 (file)
@@ -20,7 +20,8 @@ extern char  g_target_path[ PATH_MAX ];
  *  **************************************************************************************************************
  */
 int shm_tests( void * the_argp )
-{
+{      
+#if !TARGET_OS_EMBEDDED
        int                                     my_err;
        int                                     my_shm_id;
        void *                          my_shm_addr = NULL;
@@ -74,6 +75,10 @@ test_passed_exit:
                shmdt( my_shm_addr );
        }
        return( my_err );
+#else
+       printf( "\t--> Not supported on EMBEDDED TARGET\n" );
+       return 0;
+#endif
 }
 
 
index 4bd3f0e4ab9092d2955d3a5f2fe61d662d7d5e13..19d6af77fa9d9d7d3aa71146e1eca52d6b22868a 100644 (file)
@@ -16,6 +16,7 @@
 #include <AvailabilityMacros.h>        /* for determination of Mac OS X version (tiger, leopard, etc.) */
 #include <libkern/OSByteOrder.h> /* for OSSwap32() */
 
+
 extern char            g_target_path[ PATH_MAX ];
 extern int             g_skip_setuid_tests;
 extern int             g_is_under_rosetta;
@@ -924,12 +925,22 @@ int access_chmod_fchmod_test( void * the_argp )
                goto test_failed_exit;
        }
        else if ( my_err == -1  ) {
+               int tmp = 0;
+               tmp = getuid( );
+               
                /* special case when running as root - we get back EPERM when running as root */
                my_err = errno;
-               if ( (getuid( ) == 0 && my_err != EPERM) || (getuid( ) != 0 && my_err != EACCES) ) {
+#if !TARGET_OS_EMBEDDED
+               if ( ( tmp == 0 && my_err != EPERM) || (tmp != 0 && my_err != EACCES) ) {
+                       printf( "access failed with errno %d - %s. \n", my_err, strerror( my_err ) );
+                       goto test_failed_exit;
+               }
+#else
+               if ( ( tmp == 0 && my_err != EACCES) || (tmp != 0 && my_err != EACCES) ) {
                        printf( "access failed with errno %d - %s. \n", my_err, strerror( my_err ) );
                        goto test_failed_exit;
                }
+#endif
        }
 
        /* verify correct modes are set */
@@ -994,6 +1005,7 @@ test_passed_exit:
  */
 int chown_fchown_lchown_lstat_symlink_test( void * the_argp )
 {
+#if !TARGET_OS_EMBEDDED
        int                             my_err, my_group_count, i;
        int                             my_fd = -1;
        char *                  my_pathp = NULL;
@@ -1039,6 +1051,8 @@ int chown_fchown_lchown_lstat_symlink_test( void * the_argp )
        
        /* set up by getting a list of groups */
        my_group_count = getgroups( NGROUPS_MAX, &my_groups[0] );
+       printf("my_group_count: %d\n", my_group_count);
+       
        if ( my_group_count == -1 || my_group_count < 1 ) {
                printf( "getgroups call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
                goto test_failed_exit;
@@ -1053,6 +1067,9 @@ int chown_fchown_lchown_lstat_symlink_test( void * the_argp )
        /* now change group owner to something other than current value */
        my_orig_gid = my_sb.st_gid;
        my_orig_uid = my_sb.st_uid;
+       
+       printf( "st_gid: %d, st_uid: %d, my_group_count: %d\n" );
+       
        for ( i = 0; i < my_group_count; i++ ) {
                if ( my_orig_gid != my_groups[ i ] ) {
                        if ( my_new_gid1 == 0 ) {
@@ -1174,6 +1191,10 @@ test_passed_exit:
                free( my_link_pathp );
         }
        return( my_err );
+#else
+       printf( "\t--> Test not designed for EMBEDDED TARGET\n" );
+       return 0;
+#endif
 }
 
 /*  **************************************************************************************************************
@@ -1361,7 +1382,7 @@ int fs_stat_tests( void * the_argp )
                printf( "statfs and getattrlist results do not match for volume block size  \n" );
                goto test_failed_exit;
        } 
-       
+               
        my_err = 0;
        goto test_passed_exit;
 
@@ -1377,6 +1398,7 @@ test_passed_exit:
         if ( my_buffer64p != NULL ) {
                free( my_buffer64p );
         }
+        
        return( my_err );
 }
 
@@ -1903,8 +1925,7 @@ int execve_kill_vfork_test( void * the_argp )
        char *  errmsg = NULL; 
        char * argvs[2] = {"", NULL};
        int bits = get_bits();          /* Gets actual processor bit-ness. */
-
-
+       
        if (bits != 32 && bits != 64) {
                printf("Determination of processor bit-ness failed, get_bits() returned %d.\n", get_bits());
                return(-1);
@@ -1914,6 +1935,7 @@ int execve_kill_vfork_test( void * the_argp )
                errmsg = "get_architecture() could not determine the CPU architecture.\n";
                goto test_failed_exit;
        }
+       
        if (get_architecture() == INTEL) {
                if      (bits == 64 && sizeof(long) == 8) {
                        /*
@@ -2076,6 +2098,21 @@ int execve_kill_vfork_test( void * the_argp )
                                goto test_failed_exit;
                }
        }
+       else if(get_architecture() == ARM) {
+               if      (bits == 32) {
+
+                       /* Running on arm hardware. Check cases 2. */
+                       errmsg = "execve failed: from arm forking and exec()ing 32-bit arm process.\n";
+                       argvs[0] = "sleep-arm";
+                       if (do_execve_test("helpers/sleep-arm", argvs, NULL, 1))
+                               goto test_failed_exit;
+
+                       /* Test posix_spawn for arm (should succeed) */
+                       errmsg = NULL;
+                       if (do_spawn_test(CPU_TYPE_ARM, 0))
+                               goto test_failed_exit;
+               }
+       }
        else {
                /* Just in case someone decides we need more architectures in the future */
                printf("get_architecture() returned unknown architecture");
@@ -2097,6 +2134,7 @@ test_failed_exit:
  */
 int groups_test( void * the_argp )
 {
+#if !TARGET_OS_EMBEDDED
        int                     my_err, i;
        int                     my_group_count, my_orig_group_count;
        gid_t           my_real_gid;
@@ -2116,6 +2154,8 @@ int groups_test( void * the_argp )
 
        /* start by getting list of groups the current user belongs to */
        my_orig_group_count = getgroups( NGROUPS_MAX, &my_groups[0] );
+       printf("my_orig_group_count: %d\n", my_orig_group_count);
+
        if ( my_orig_group_count == -1 || my_orig_group_count < 1 ) {
                printf( "getgroups call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
                goto test_failed_exit;
@@ -2148,6 +2188,8 @@ int groups_test( void * the_argp )
        }
 
        my_group_count = getgroups( NGROUPS_MAX, &my_groups[0] );
+       printf("my_group_count: %d\n", my_group_count);
+       
        if ( my_group_count == -1 || my_group_count < 1 ) {
                printf( "getgroups call failed.  got errno %d - %s. \n", errno, strerror( errno ) );
                goto test_failed_exit;
@@ -2224,6 +2266,10 @@ test_failed_exit:
        
 test_passed_exit:
        return( my_err );
+#else
+       printf( "\t--> Test not designed for EMBEDDED TARGET\n" );
+       return 0;
+#endif
 }
 
 
@@ -3192,10 +3238,10 @@ int process_group_test( void * the_argp )
        my_pid = getpid( );
        my_process_group = getpgrp( );
         
-       
        /* test getpgrp and getpgid - they should return the same results when 0 is passed to getpgid */
        if ( my_process_group != getpgid( 0 ) ) {
                printf( "getpgrp and getpgid did not return the same process group ID \n" );
+               printf( "getpgid: %d, my_process_group: %d\n", getpgid( 0 ), my_process_group );
                goto test_failed_exit;
        }
 
@@ -3868,6 +3914,7 @@ test_passed_exit:
  */
 int quotactl_test( void * the_argp )
 {
+#if !TARGET_OS_EMBEDDED
        int                             my_err;
        int                             is_quotas_on = 0;
        struct dqblk    my_quota_blk;
@@ -3905,6 +3952,10 @@ test_failed_exit:
        
 test_passed_exit:
        return( my_err );
+#else
+       printf( "\t--> Not supported on EMBEDDED TARGET\n" );
+       return 0;
+#endif
 }
 
 /*  **************************************************************************************************************
@@ -4080,6 +4131,7 @@ int directory_tests( void * the_argp )
        my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
        my_attrlist.commonattr = (ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID | ATTR_CMN_BKUPTIME); 
        my_err = getattrlist( my_pathp, &my_attrlist, &my_attr_buf[0], sizeof(my_attr_buf[0]), 0 );
+
        if ( my_err != 0 ) {
                if ( errno == ENOTSUP && is_ufs ) {
                        /* getattr calls not supported on ufs */
@@ -4147,7 +4199,8 @@ int directory_tests( void * the_argp )
        goto test_passed_exit;
 
 test_failed_exit:
-       my_err = -1;
+       if(my_err != 0)
+               my_err = -1;
        
 test_passed_exit:
        if ( my_fd != -1 )
@@ -4201,6 +4254,7 @@ int exchangedata_test( void * the_argp )
        /* create a test file */
        my_err = create_random_name( my_file1_pathp, 1 );
        if ( my_err != 0 ) {
+               printf( "create_random_name my_err: %d\n", my_err );
                goto test_failed_exit;
        }
        my_fd1 = open( my_file1_pathp, O_RDWR, 0 );
@@ -4226,6 +4280,7 @@ int exchangedata_test( void * the_argp )
        /* create a test file */
        my_err = create_random_name( my_file2_pathp, 1 );
        if ( my_err != 0 ) {
+               printf( "create_random_name my_err: %d\n", my_err );
                goto test_failed_exit;
        }
        my_fd2 = open( my_file2_pathp, O_RDWR, 0 );
@@ -4514,6 +4569,7 @@ test_passed_exit:
  */
 int aio_tests( void * the_argp )
 {
+#if !TARGET_OS_EMBEDDED
        int                                     my_err, i;
        char *                          my_pathp;
        struct aiocb *          my_aiocbp;
@@ -4776,6 +4832,10 @@ test_passed_exit:
                }
        }
        return( my_err );
+#else
+       printf( "\t--> Not supported on EMBEDDED TARGET\n" );
+       return 0;
+#endif
 }
 
 
@@ -4981,6 +5041,7 @@ test_passed_exit:
  */
 int message_queue_tests( void * the_argp )
 {
+#if !TARGET_OS_EMBEDDED
        int                                     my_err;
        int                                     my_msg_queue_id = -1;
        ssize_t                         my_result;
@@ -5076,6 +5137,10 @@ test_passed_exit:
                msgctl( my_msg_queue_id, IPC_RMID, NULL );
        }
        return( my_err );
+#else
+       printf( "\t--> Not supported on EMBEDDED TARGET \n" );
+       return 0;
+#endif
 }
 
 
index 6505466eaafcfa2dc7c8889abef93b77581df607..268ab0e34b9c1eb51317a31194dd9888aafa072d 100644 (file)
 #include <sys/ucred.h>
 #include <sys/vnode.h>
 #include <sys/wait.h>
-        
+#include <TargetConditionals.h> /* for TARGET_OS_EMBEDDED */
+
 #define MY_BUFFER_SIZE (1024 * 10)
+#define ARM    100  /* I am not sure if the value really matters? */
 #define POWERPC        238947
 #define INTEL  38947                   /* 
                                         * Random values used by execve tests to