windows-btree-flush-race-20090522
[openafs.git] / src / WINNT / afsd / cm_ioctl.c
index a0d416d..c2b1e2b 100644 (file)
@@ -102,8 +102,14 @@ cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
 
     code = buf_FlushCleanPages(scp, userp, reqp);
         
+    if (scp->fileType == CM_SCACHETYPE_DIRECTORY)
+        lock_ObtainWrite(&scp->dirlock);
     lock_ObtainWrite(&scp->rw);
     cm_DiscardSCache(scp);
+    if (scp->fileType == CM_SCACHETYPE_DIRECTORY) {
+        cm_ResetSCacheDirectory(scp, 1);
+        lock_ReleaseWrite(&scp->dirlock);
+    }
     lock_ReleaseWrite(&scp->rw);
 
     osi_Log2(afsd_logp,"cm_FlushFile scp 0x%x returns error: [%x]",scp, code);
@@ -167,31 +173,6 @@ cm_FlushVolume(cm_user_t *userp, cm_req_t *reqp, afs_uint32 cell, afs_uint32 vol
 }
 
 /*
- * Utility function.  Used within this file.
- * Invalidate ACL info for a user that has just        obtained or lost tokens.
- */
-void 
-cm_ResetACLCache(cm_user_t *userp)
-{
-    cm_scache_t *scp;
-    int hash;
-
-    lock_ObtainWrite(&cm_scacheLock);
-    for (hash=0; hash < cm_data.scacheHashTableSize; hash++) {
-        for (scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) {
-            cm_HoldSCacheNoLock(scp);
-            lock_ReleaseWrite(&cm_scacheLock);
-            lock_ObtainWrite(&scp->rw);
-            cm_InvalidateACLUser(scp, userp);
-            lock_ReleaseWrite(&scp->rw);
-            lock_ObtainWrite(&cm_scacheLock);
-            cm_ReleaseSCacheNoLock(scp);
-        }
-    }
-    lock_ReleaseWrite(&cm_scacheLock);
-}       
-
-/*
  *  TranslateExtendedChars - This is a fix for TR 54482.
  *
  *  If an extended character (80 - FF) is entered into a file
@@ -480,9 +461,13 @@ cm_IoctlGetFileCellName(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scach
             clientchar_t * cellname;
 
             cellname = cm_FsStringToClientStringAlloc(cellp->name, -1, NULL); 
-            cm_UnparseIoctlString(ioctlp, NULL, cellname, -1);
-            free(cellname);
-            code = 0;
+            if (cellname == NULL) {
+                code = CM_ERROR_NOSUCHCELL;
+            } else {
+                cm_UnparseIoctlString(ioctlp, NULL, cellname, -1);
+                free(cellname);
+                code = 0;
+            }
         } else
             code = CM_ERROR_NOSUCHCELL;
     }
@@ -906,7 +891,7 @@ cm_IoctlGetOwner(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *sc
 afs_int32 
 cm_IoctlWhereIs(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp, cm_req_t *reqp)
 {
-    afs_int32 code;
+    afs_int32 code = 0;
     cm_cell_t *cellp;
     cm_volume_t *tvp;
     cm_serverRef_t **tsrpp, *current;
@@ -950,16 +935,19 @@ cm_IoctlWhereIs(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp
        
         cp = ioctlp->outDatap;
         
-        tsrpp = cm_GetVolServers(tvp, volume);
-        lock_ObtainRead(&cm_serverLock);
-        for (current = *tsrpp; current; current = current->next) {
-            tsp = current->server;
-            memcpy(cp, (char *)&tsp->addr.sin_addr.s_addr, sizeof(long));
-            cp += sizeof(long);
+        tsrpp = cm_GetVolServers(tvp, volume, userp, reqp);
+        if (tsrpp == NULL) {
+            code = CM_ERROR_NOSUCHVOLUME;
+        } else {
+            lock_ObtainRead(&cm_serverLock);
+            for (current = *tsrpp; current; current = current->next) {
+                tsp = current->server;
+                memcpy(cp, (char *)&tsp->addr.sin_addr.s_addr, sizeof(long));
+                cp += sizeof(long);
+            }
+            lock_ReleaseRead(&cm_serverLock);
+            cm_FreeServerList(tsrpp, 0);
         }
-        lock_ReleaseRead(&cm_serverLock);
-        cm_FreeServerList(tsrpp, 0);
-
         /* still room for terminating NULL, add it on */
         volume = 0;    /* reuse vbl */
         memcpy(cp, (char *)&volume, sizeof(long));
@@ -968,7 +956,7 @@ cm_IoctlWhereIs(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *scp
         ioctlp->outDatap = cp;
         cm_PutVolume(tvp);
     }
-    return 0;
+    return code;
 }       
 
 /* 
@@ -1374,8 +1362,12 @@ cm_IoctlGetCell(struct cm_ioctl *ioctlp, struct cm_user *userp)
         ioctlp->outDatap = basep + max * sizeof(afs_int32);
 
         cellnamep = cm_FsStringToClientStringAlloc(tcellp->name, -1, NULL);
-        cm_UnparseIoctlString(ioctlp, NULL, cellnamep, -1);
-        free(cellnamep);
+        if (cellnamep) {
+            cm_UnparseIoctlString(ioctlp, NULL, cellnamep, -1);
+            free(cellnamep);
+        } else {
+            tcellp = NULL;
+        }
     }
 
     if (tcellp) 
@@ -1416,7 +1408,7 @@ cm_IoctlNewCell(struct cm_ioctl *ioctlp, struct cm_user *userp)
 
         rock.cellp = cp;
         rock.flags = 0;
-        code = cm_SearchCellFile(cp->name, cp->name, cm_AddCellProc, &rock);
+        code = cm_SearchCellFileEx(cp->name, cp->name, cp->linkedName, cm_AddCellProc, &rock);
 #ifdef AFS_AFSDB_ENV
         if (code) {
             if (cm_dnsEnabled) {
@@ -1472,8 +1464,12 @@ cm_IoctlGetWsCell(cm_ioctl_t *ioctlp, cm_user_t *userp)
     } else if (cm_data.rootCellp) {
         clientchar_t * cellnamep = cm_FsStringToClientStringAlloc(cm_data.rootCellp->name, -1, NULL);
         /* return the default cellname to the caller */
-        cm_UnparseIoctlString(ioctlp, NULL, cellnamep, -1);
-        free(cellnamep);
+        if (cellnamep) {
+            cm_UnparseIoctlString(ioctlp, NULL, cellnamep, -1);
+            free(cellnamep);
+        } else {
+            code = CM_ERROR_NOSUCHCELL;
+        }
     } else {
         /* if we don't know our default cell, return failure */
         code = CM_ERROR_NOSUCHCELL;
@@ -1695,7 +1691,7 @@ cm_IoctlSetSPrefs(struct cm_ioctl *ioctlp, struct cm_user *userp)
         }
         else   /* add a new server without a cell */
         {
-            tsp = cm_NewServer(&tmp, type, NULL, CM_FLAG_NOPROBE); /* refcount = 1 */
+            tsp = cm_NewServer(&tmp, type, NULL, NULL, CM_FLAG_NOPROBE); /* refcount = 1 */
             tsp->ipRank = rank;
         }
        lock_ObtainMutex(&tsp->mx);
@@ -2165,6 +2161,7 @@ cm_UsernameToId(char *uname, cm_ucell_t * ucellp, afs_uint32* uid)
     int i;
     char * p, * r;
 
+    memset(&info, 0, sizeof(info));
     tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
     code = afsconf_GetCellInfo(tdir, ucellp->cellp->name, "afsprot", &info);
     afsconf_Close(tdir);
@@ -2190,6 +2187,8 @@ cm_UsernameToId(char *uname, cm_ucell_t * ucellp, afs_uint32* uid)
 
     code = ubik_ClientInit(serverconns, &pruclient);
     if (code) {
+        if (info.linkedCell)
+            free(info.linkedCell);
        return code;
     }
 
@@ -2223,6 +2222,8 @@ cm_UsernameToId(char *uname, cm_ucell_t * ucellp, afs_uint32* uid)
        pruclient = NULL;
     }
 
+    if (info.linkedCell)
+        free(info.linkedCell);
     return 0;
 }
 #endif /* QUERY_AFSID */
@@ -2357,7 +2358,7 @@ cm_IoctlSetToken(struct cm_ioctl *ioctlp, struct cm_user *userp)
         ioctlp->flags |= CM_IOCTLFLAG_LOGON;
     }
 
-    cm_ResetACLCache(userp);
+    cm_ResetACLCache(cellp, userp);
 
     if (release_userp)
        cm_ReleaseUser(userp);
@@ -2580,7 +2581,7 @@ cm_IoctlDelToken(struct cm_ioctl *ioctlp, struct cm_user *userp)
 
     lock_ReleaseMutex(&userp->mx);
 
-    cm_ResetACLCache(userp);
+    cm_ResetACLCache(cellp, userp);
 
     return 0;
 }
@@ -2615,7 +2616,7 @@ cm_IoctlDelAllToken(struct cm_ioctl *ioctlp, struct cm_user *userp)
 
     lock_ReleaseMutex(&userp->mx);
 
-    cm_ResetACLCache(userp);
+    cm_ResetACLCache(NULL, userp);
 
     return 0;
 }
@@ -3019,7 +3020,10 @@ cm_IoctlMemoryDump(struct cm_ioctl *ioctlp, struct cm_user *userp)
     cm_DumpVolumes(hLogFile, cookie, 1);
     cm_DumpSCache(hLogFile, cookie, 1);
     cm_DumpBufHashTable(hLogFile, cookie, 1);
+    cm_DumpServers(hLogFile, cookie, 1);
     smb_DumpVCP(hLogFile, cookie, 1);
+    rx_DumpCalls(hLogFile, cookie);
+    rx_DumpPackets(hLogFile, cookie);
 
     CloseHandle(hLogFile);                          
   
@@ -3046,6 +3050,8 @@ cm_CheckServersStatus(cm_serverRef_t *serversp)
 
     lock_ObtainRead(&cm_serverLock);
     for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
+        if (tsrp->status == srv_deleted)
+            continue;
         if (tsp = tsrp->server) {
             cm_GetServerNoLock(tsp);
             lock_ReleaseRead(&cm_serverLock);