unpin-out-of-order-oops-20050125
[openafs.git] / src / afs / afs_call.c
index c0d9565..9266fd7 100644 (file)
@@ -46,6 +46,7 @@ char afs_zeros[AFS_ZEROS];
 char afs_rootVolumeName[64] = "";
 struct afs_icl_set *afs_iclSetp = (struct afs_icl_set *)0;
 struct afs_icl_set *afs_iclLongTermSetp = (struct afs_icl_set *)0;
+afs_uint32 rx_bindhost;
 
 #if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV)
 kmutex_t afs_global_lock;
@@ -64,13 +65,12 @@ simple_lock_data_t afs_global_lock;
 struct lock__bsd__ afs_global_lock;
 #endif
 
-#if defined(AFS_XBSD_ENV)
+#if defined(AFS_XBSD_ENV) && !defined(AFS_FBSD50_ENV)
 struct lock afs_global_lock;
-#ifdef AFS_FBSD50_ENV
-struct thread *afs_global_owner;
-#else
 struct proc *afs_global_owner;
 #endif
+#ifdef AFS_FBSD50_ENV
+struct mtx afs_global_mtx;
 #endif
 
 #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV)
@@ -129,9 +129,9 @@ afs_InitSetup(int preallocs)
 
     /* start RX */
     rx_extraPackets = AFS_NRXPACKETS;  /* smaller # of packets */
-    code = rx_Init(htons(7001));
+    code = rx_InitHost(rx_bindhost, htons(7001));
     if (code) {
-       printf("AFS: RX failed to initialize.\n");
+       printf("AFS: RX failed to initialize %d).\n", code);
        return code;
     }
     rx_SetRxDeadTime(afs_rx_deadtime);
@@ -158,10 +158,17 @@ afsd_thread(void *rock)
 #ifdef SYS_SETPRIORITY_EXPORTED
     int (*sys_setpriority) (int, int, int) = sys_call_table[__NR_setpriority];
 #endif
-    daemonize();               /* doesn't do much, since we were forked from keventd, but
+#if defined(AFS_LINUX26_ENV)
+    daemonize("afsd");
+#else
+    daemonize();
+#endif
+                               /* doesn't do much, since we were forked from keventd, but
                                 * does call mm_release, which wakes up our parent (since it
                                 * used CLONE_VFORK) */
+#if !defined(AFS_LINUX26_ENV)
     reparent_to_init();
+#endif
     afs_osi_MaskSignals();
     switch (parm) {
     case AFSOP_START_RXCALLBACK:
@@ -264,7 +271,7 @@ afsd_thread(void *rock)
        complete_and_exit(0, 0);
        break;
     default:
-       printf("Unknown op %d in StartDaemon()\n");
+       printf("Unknown op %ld in StartDaemon()\n", (long)parm);
        break;
     }
     return 0;
@@ -283,7 +290,11 @@ afs_DaemonOp(long parm, long parm2, long parm3, long parm4, long parm5,
 {
     int code;
     DECLARE_COMPLETION(c);
+#if defined(AFS_LINUX26_ENV)
+    struct work_struct tq;
+#else
     struct tq_struct tq;
+#endif
     struct afsd_thread_info info;
     if (parm == AFSOP_START_RXCALLBACK) {
        if (afs_CB_Running)
@@ -307,11 +318,16 @@ afs_DaemonOp(long parm, long parm2, long parm3, long parm4, long parm5,
     }                          /* other functions don't need setup in the parent */
     info.complete = &c;
     info.parm = parm;
+#if defined(AFS_LINUX26_ENV)
+    INIT_WORK(&tq, afsd_launcher, &info);
+    schedule_work(&tq);
+#else
     tq.sync = 0;
     INIT_LIST_HEAD(&tq.list);
     tq.routine = afsd_launcher;
     tq.data = &info;
     schedule_task(&tq);
+#endif
     AFS_GUNLOCK();
     /* we need to wait cause we passed stack pointers around.... */
     wait_for_completion(&c);
@@ -339,7 +355,7 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6)
        /* only root can run this code */
        return (EACCES);
 #else
-    if (!afs_suser() && (parm != AFSOP_GETMTU)
+    if (!afs_suser(NULL) && (parm != AFSOP_GETMTU)
        && (parm != AFSOP_GETMASK)) {
        /* only root can run this code */
 #if defined(KERNEL_HAVE_UERROR)
@@ -685,6 +701,7 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6)
                cacheNumEntries : 1));
     } else if (parm == AFSOP_ADVISEADDR) {
        /* pass in the host address to the rx package */
+       int rxbind = 0;
        afs_int32 count = parm2;
        afs_int32 *buffer =
            afs_osi_Alloc(sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
@@ -693,7 +710,13 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6)
        afs_int32 *mtubuffer =
            afs_osi_Alloc(sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
        int i;
-       int code;
+
+       /* Bind, but only if there's only one address configured */ 
+       if ( count & 0x80000000) {
+           count &= ~0x80000000;
+           if (count == 1)
+               rxbind=1;
+       }
 
        if (count > AFS_MAX_INTERFACE_ADDR) {
            code = ENOMEM;
@@ -729,6 +752,11 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6)
        }
        afs_uuid_create(&afs_cb_interface.uuid);
        rxi_setaddr(buffer[0]);
+       if (rxbind)
+           rx_bindhost = buffer[0];
+       else
+           rx_bindhost = htonl(INADDR_ANY);
+
        afs_osi_Free(buffer, sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
        afs_osi_Free(maskbuffer, sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
        afs_osi_Free(mtubuffer, sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR);
@@ -761,7 +789,7 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6)
 #endif /* AFS_SGI53_ENV */
     else if (parm == AFSOP_SHUTDOWN) {
        afs_cold_shutdown = 0;
-       if (parm == 1)
+       if (parm2 == 1)
            afs_cold_shutdown = 1;
 #ifndef AFS_DARWIN_ENV
        if (afs_globalVFS != 0) {
@@ -847,7 +875,7 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6)
        char *cellname = afs_osi_Alloc(cellLen);
 
 #ifndef UKERNEL
-       afs_osi_MaskSignals();
+       afs_osi_MaskUserLoop();
 #endif
        AFS_COPYIN((afs_int32 *) parm2, cellname, cellLen, code);
        AFS_COPYIN((afs_int32 *) parm3, kmsg, kmsgLen, code);
@@ -1068,6 +1096,7 @@ struct iparam32 {
 };
 
 
+#if defined(AFS_HPUX_64BIT_ENV) || defined(AFS_SUN57_64BIT_ENV) || (defined(AFS_LINUX_64BIT_KERNEL) && !defined(AFS_ALPHA_LINUX20_ENV) && !defined(AFS_IA64_LINUX20_ENV) && !defined(AFS_AMD64_LINUX20_ENV))
 static void
 iparam32_to_iparam(const struct iparam32 *src, struct iparam *dst)
 {
@@ -1076,6 +1105,7 @@ iparam32_to_iparam(const struct iparam32 *src, struct iparam *dst)
     dst->param3 = src->param3;
     dst->param4 = src->param4;
 }
+#endif
 
 /*
  * If you need to change copyin_iparam(), you may also need to change
@@ -1118,6 +1148,10 @@ copyin_iparam(caddr_t cmarg, struct iparam *dst)
     if (current->tss.flags & SPARC_FLAG_32BIT)
 #elif defined(AFS_AMD64_LINUX20_ENV)
     if (current->thread.flags & THREAD_IA32)
+#elif defined(AFS_PPC64_LINUX20_ENV)
+    if (current->thread.flags & PPC_FLAG_32BIT) 
+#elif defined(AFS_S390X_LINUX20_ENV)
+    if (current->thread.flags & S390_FLAG_31BIT) 
 #else
 #error Not done for this linux version
 #endif
@@ -1480,6 +1514,11 @@ afs_shutdown(void)
     extern struct osi_file *afs_cacheInodep;
 
     AFS_STATCNT(afs_shutdown);
+    if (afs_initState == 0) {
+        afs_warn("AFS not initialized - not shutting down\n");
+      return;
+    }
+
     if (afs_shuttingdown)
        return;
     afs_shuttingdown = 1;
@@ -1491,6 +1530,9 @@ afs_shutdown(void)
 
     afs_termState = AFSOP_STOP_RXCALLBACK;
     rx_WakeupServerProcs();
+#ifdef AFS_AIX51_ENV
+    shutdown_rxkernel();
+#endif
     /* shutdown_rxkernel(); */
     while (afs_termState == AFSOP_STOP_RXCALLBACK)
        afs_osi_Sleep(&afs_termState);
@@ -1561,7 +1603,11 @@ afs_shutdown(void)
     shutdown_rx();
     afs_shutdown_BKG();
     shutdown_bufferpackage();
+#endif
+#ifdef AFS_AIX51_ENV
     shutdown_daemons();
+#endif
+#ifdef notdef
     shutdown_cache();
     shutdown_osi();
     shutdown_osinet();
@@ -1664,7 +1710,7 @@ Afscall_icl(long opcode, long p1, long p2, long p3, long p4, long *retval)
        return (EACCES);
     }
 #else
-    if (!afs_suser()) {                /* only root can run this code */
+    if (!afs_suser(NULL)) {    /* only root can run this code */
 #if defined(KERNEL_HAVE_UERROR)
        setuerror(EACCES);
        return EACCES;
@@ -2571,10 +2617,10 @@ afs_icl_LogFreeUse(register struct afs_icl_log *logp)
     ObtainWriteLock(&logp->lock, 189);
     if (--logp->setCount == 0) {
        /* no more users -- free it (but keep log structure around) */
-       afs_osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
 #ifdef KERNEL_HAVE_PIN
        unpin((char *)logp->datap, sizeof(afs_int32) * logp->logSize);
 #endif
+       afs_osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
        logp->firstUsed = logp->firstFree = 0;
        logp->logElements = 0;
        logp->datap = NULL;
@@ -2597,10 +2643,10 @@ afs_icl_LogSetSize(register struct afs_icl_log *logp, afs_int32 logSize)
        logp->logElements = 0;
 
        /* free and allocate a new one */
-       afs_osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
 #ifdef KERNEL_HAVE_PIN
        unpin((char *)logp->datap, sizeof(afs_int32) * logp->logSize);
 #endif
+       afs_osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
        logp->datap =
            (afs_int32 *) afs_osi_Alloc(sizeof(afs_int32) * logSize);
 #ifdef KERNEL_HAVE_PIN
@@ -2624,7 +2670,10 @@ afs_icl_ZapLog(register struct afs_icl_log *logp)
            /* found the dude we want to remove */
            *lpp = logp->nextp;
            osi_FreeSmallSpace(logp->name);
-           osi_FreeSmallSpace(logp->datap);
+#ifdef KERNEL_HAVE_PIN
+           unpin((char *)logp->datap, sizeof(afs_int32) * logp->logSize);
+#endif
+           afs_osi_Free(logp->datap, sizeof(afs_int32) * logp->logSize);
            osi_FreeSmallSpace(logp);
            break;              /* won't find it twice */
        }
@@ -2882,10 +2931,10 @@ afs_icl_ZapSet(register struct afs_icl_set *setp)
            /* found the dude we want to remove */
            *lpp = setp->nextp;
            osi_FreeSmallSpace(setp->name);
-           afs_osi_Free(setp->eventFlags, ICL_DEFAULTEVENTS);
 #ifdef KERNEL_HAVE_PIN
            unpin((char *)setp->eventFlags, ICL_DEFAULTEVENTS);
 #endif
+           afs_osi_Free(setp->eventFlags, ICL_DEFAULTEVENTS);
            for (i = 0; i < ICL_LOGSPERSET; i++) {
                if ((tlp = setp->logs[i]))
                    afs_icl_LogReleNL(tlp);
@@ -2974,7 +3023,7 @@ afs_icl_EnumerateSets(int (*aproc)
     for (tp = afs_icl_allSets; tp; tp = np) {
        tp->refCount++;         /* hold this guy */
        ReleaseWriteLock(&afs_icl_lock);
-       code = (*aproc) (tp->name, arock, tp);
+       code = (*aproc) (tp->name, arock, (struct afs_icl_log *)tp);
        ObtainWriteLock(&afs_icl_lock, 206);
        np = tp->nextp;         /* tp may disappear next, but not np */
        if (--tp->refCount == 0 && (tp->states & ICL_SETF_DELETED))