/* * This function returns a free (not in the LRU queue) acl cache entry. * It must be called with the cm_aclLock lock held */ static cm_aclent_t *GetFreeACLEnt(cm_scache_t * scp) { cm_aclent_t *aclp; cm_scache_t *ascp = 0; if (cm_data.aclLRUp == NULL) osi_panic("empty aclent LRU", __FILE__, __LINE__); if (cm_data.aclLRUEndp == NULL) osi_panic("inconsistent aclent LRUEndp == NULL", __FILE__, __LINE__); aclp = cm_data.aclLRUEndp; osi_QRemoveHT((osi_queue_t **) &cm_data.aclLRUp, (osi_queue_t **) &cm_data.aclLRUEndp, &aclp->q); if (aclp->backp && scp != aclp->backp) { ascp = aclp->backp; lock_ReleaseWrite(&cm_aclLock); lock_ObtainWrite(&ascp->rw); lock_ObtainWrite(&cm_aclLock); } CleanupACLEnt(aclp); if (ascp) lock_ReleaseWrite(&ascp->rw); return aclp; }
void lock_VerifyOrderRW(osi_queue_t *lockRefH, osi_queue_t *lockRefT, osi_rwlock_t *lockp) { char msg[512]; osi_lock_ref_t * lockRefp; for (lockRefp = (osi_lock_ref_t *)lockRefH ; lockRefp; lockRefp = (osi_lock_ref_t *)osi_QNext(&lockRefp->q)) { if (lockRefp->type == OSI_LOCK_RW) { if (lockRefp->rw == lockp) { sprintf(msg, "RW Lock 0x%p level %d already held", lockp, lockp->level); osi_panic(msg, __FILE__, __LINE__); } if (lockRefp->rw->level > lockp->level) { sprintf(msg, "Lock hierarchy violation Held lock 0x%p level %d > Requested lock 0x%p level %d", lockRefp->rw, lockRefp->rw->level, lockp, lockp->level); osi_panic(msg, __FILE__, __LINE__); } } else { if (lockRefp->mx->level > lockp->level) { sprintf(msg, "Lock hierarchy violation Held lock 0x%p level %d > Requested lock 0x%p level %d", lockRefp->mx, lockRefp->mx->level, lockp, lockp->level); osi_panic(msg, __FILE__, __LINE__); } osi_assertx(lockRefp->mx->level <= lockp->level, "Lock hierarchy violation"); } } }
void osi_BaseInit(void) { int i; for(i=0; i<OSI_MUTEXHASHSIZE; i++) InitializeCriticalSection(&osi_baseAtomicCS[i]); if ((tls_LockRefH = TlsAlloc()) == TLS_OUT_OF_INDEXES) osi_panic("TlsAlloc(tls_LockRefH) failure", __FILE__, __LINE__); if ((tls_LockRefT = TlsAlloc()) == TLS_OUT_OF_INDEXES) osi_panic("TlsAlloc(tls_LockRefT) failure", __FILE__, __LINE__); InitializeCriticalSection(&lock_ref_CS); }
static osi_lock_ref_t * lock_GetLockRef(void * lockp, char type) { osi_lock_ref_t * lockRefp = NULL; EnterCriticalSection(&lock_ref_CS); if (lock_ref_FreeListp) { lockRefp = lock_ref_FreeListp; osi_QRemoveHT( (osi_queue_t **) &lock_ref_FreeListp, (osi_queue_t **) &lock_ref_FreeListEndp, &lockRefp->q); } LeaveCriticalSection(&lock_ref_CS); if (lockRefp == NULL) lockRefp = (osi_lock_ref_t *)malloc(sizeof(osi_lock_ref_t)); memset(lockRefp, 0, sizeof(osi_lock_ref_t)); lockRefp->type = type; switch (type) { case OSI_LOCK_MUTEX: lockRefp->mx = lockp; break; case OSI_LOCK_RW: lockRefp->rw = lockp; break; default: osi_panic("Invalid Lock Type", __FILE__, __LINE__); } return lockRefp; }
/* This must be called with cm_aclLock and the aclp->back->mx held */ static void CleanupACLEnt(cm_aclent_t * aclp) { cm_aclent_t *taclp; cm_aclent_t **laclpp; if (aclp->backp) { if (aclp->backp->randomACLp) { /* * Remove the entry from the vnode's list */ lock_AssertWrite(&aclp->backp->rw); laclpp = &aclp->backp->randomACLp; for (taclp = *laclpp; taclp; laclpp = &taclp->nextp, taclp = *laclpp) { if (taclp == aclp) break; } if (!taclp) osi_panic("CleanupACLEnt race", __FILE__, __LINE__); *laclpp = aclp->nextp; /* remove from vnode list */ } aclp->backp = NULL; } /* release the old user */ if (aclp->userp) { cm_ReleaseUser(aclp->userp); aclp->userp = NULL; } aclp->randomAccess = 0; aclp->tgtLifetime = 0; }
cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, afs_uint32 flags) { cm_cell_t *cp, *cp2; long code; char fullname[CELL_MAXNAMELEN]=""; char linkedName[CELL_MAXNAMELEN]=""; char name[CELL_MAXNAMELEN]=""; int hasWriteLock = 0; int hasMutex = 0; afs_uint32 hash; cm_cell_rock_t rock; size_t len; if (namep == NULL || !namep[0] || !strcmp(namep,CM_IOCTL_FILENAME_NOSLASH)) return NULL; /* * Strip off any trailing dots at the end of the cell name. * Failure to do so results in an undesireable alias as the * result of DNS AFSDB record lookups where a trailing dot * has special meaning. */ strncpy(name, namep, CELL_MAXNAMELEN); for (len = strlen(namep); len > 0 && namep[len-1] == '.'; len--) { name[len-1] = '\0'; } if (len == 0) return NULL; namep = name; hash = CM_CELL_NAME_HASH(namep); lock_ObtainRead(&cm_cellLock); for (cp = cm_data.cellNameHashTablep[hash]; cp; cp=cp->nameNextp) { if (cm_stricmp_utf8(namep, cp->name) == 0) { strncpy(fullname, cp->name, CELL_MAXNAMELEN); fullname[CELL_MAXNAMELEN-1] = '\0'; break; } } if (!cp) { for (cp = cm_data.allCellsp; cp; cp=cp->allNextp) { if (strnicmp(namep, cp->name, strlen(namep)) == 0) { strncpy(fullname, cp->name, CELL_MAXNAMELEN); fullname[CELL_MAXNAMELEN-1] = '\0'; break; } } } if (cp) { lock_ReleaseRead(&cm_cellLock); cm_UpdateCell(cp, flags); } else if (flags & CM_FLAG_CREATE) { lock_ConvertRToW(&cm_cellLock); hasWriteLock = 1; /* when we dropped the lock the cell could have been added * to the list so check again while holding the write lock */ for (cp = cm_data.cellNameHashTablep[hash]; cp; cp=cp->nameNextp) { if (cm_stricmp_utf8(namep, cp->name) == 0) { strncpy(fullname, cp->name, CELL_MAXNAMELEN); fullname[CELL_MAXNAMELEN-1] = '\0'; break; } } if (cp) goto done; for (cp = cm_data.allCellsp; cp; cp=cp->allNextp) { if (strnicmp(namep, cp->name, strlen(namep)) == 0) { strncpy(fullname, cp->name, CELL_MAXNAMELEN); fullname[CELL_MAXNAMELEN-1] = '\0'; break; } } if (cp) { lock_ReleaseWrite(&cm_cellLock); lock_ObtainMutex(&cp->mx); lock_ObtainWrite(&cm_cellLock); cm_AddCellToNameHashTable(cp); cm_AddCellToIDHashTable(cp); lock_ReleaseMutex(&cp->mx); goto done; } if ( cm_data.freeCellsp != NULL ) { cp = cm_data.freeCellsp; cm_data.freeCellsp = cp->freeNextp; /* * The magic, cellID, and mx fields are already set. */ } else { if ( cm_data.currentCells >= cm_data.maxCells ) osi_panic("Exceeded Max Cells", __FILE__, __LINE__); /* don't increment currentCells until we know that we * are going to keep this entry */ cp = &cm_data.cellBaseAddress[cm_data.currentCells]; memset(cp, 0, sizeof(cm_cell_t)); cp->magic = CM_CELL_MAGIC; /* the cellID cannot be 0 */ cp->cellID = ++cm_data.currentCells; /* otherwise we found the cell, and so we're nearly done */ lock_InitializeMutex(&cp->mx, "cm_cell_t mutex", LOCK_HIERARCHY_CELL); } lock_ReleaseWrite(&cm_cellLock); hasWriteLock = 0; rock.cellp = cp; rock.flags = flags; code = cm_SearchCellRegistry(1, namep, fullname, linkedName, cm_AddCellProc, &rock); if (code && code != CM_ERROR_FORCE_DNS_LOOKUP) code = cm_SearchCellFileEx(namep, fullname, linkedName, cm_AddCellProc, &rock); if (code) { osi_Log4(afsd_logp,"in cm_GetCell_gen cm_SearchCellFileEx(%s) returns code= %d fullname= %s linkedName= %s", osi_LogSaveString(afsd_logp,namep), code, osi_LogSaveString(afsd_logp,fullname), osi_LogSaveString(afsd_logp,linkedName)); if (cm_dnsEnabled) { int ttl; code = cm_SearchCellByDNS(namep, fullname, &ttl, cm_AddCellProc, &rock); if ( code ) { osi_Log3(afsd_logp,"in cm_GetCell_gen cm_SearchCellByDNS(%s) returns code= %d fullname= %s", osi_LogSaveString(afsd_logp,namep), code, osi_LogSaveString(afsd_logp,fullname)); lock_ObtainMutex(&cp->mx); lock_ObtainWrite(&cm_cellLock); hasWriteLock = 1; cm_RemoveCellFromIDHashTable(cp); cm_RemoveCellFromNameHashTable(cp); lock_ReleaseMutex(&cp->mx); cm_FreeCell(cp); cp = NULL; goto done; } else { /* got cell from DNS */ lock_ObtainMutex(&cp->mx); hasMutex = 1; _InterlockedOr(&cp->flags, CM_CELLFLAG_DNS); _InterlockedAnd(&cp->flags, ~CM_CELLFLAG_VLSERVER_INVALID); cp->timeout = time(0) + ttl; } } else { lock_ObtainMutex(&cp->mx); lock_ObtainWrite(&cm_cellLock); hasWriteLock = 1; cm_RemoveCellFromIDHashTable(cp); cm_RemoveCellFromNameHashTable(cp); lock_ReleaseMutex(&cp->mx); cm_FreeCell(cp); cp = NULL; goto done; } } else { lock_ObtainMutex(&cp->mx); hasMutex = 1; cp->timeout = time(0) + 7200; /* two hour timeout */ } /* we have now been given the fullname of the cell. It may * be that we already have a cell with that name. If so, * we should use it instead of completing the allocation * of a new cm_cell_t */ lock_ObtainRead(&cm_cellLock); hash = CM_CELL_NAME_HASH(fullname); for (cp2 = cm_data.cellNameHashTablep[hash]; cp2; cp2=cp2->nameNextp) { if (cm_stricmp_utf8(fullname, cp2->name) == 0) { break; } } if (cp2) { if (!hasMutex) { lock_ObtainMutex(&cp->mx); hasMutex = 1; } lock_ConvertRToW(&cm_cellLock); hasWriteLock = 1; cm_RemoveCellFromIDHashTable(cp); cm_RemoveCellFromNameHashTable(cp); lock_ReleaseMutex(&cp->mx); hasMutex = 0; cm_FreeCell(cp); cp = cp2; goto done; } lock_ReleaseRead(&cm_cellLock); /* randomise among those vlservers having the same rank*/ cm_RandomizeServer(&cp->vlServersp); if (!hasMutex) lock_ObtainMutex(&cp->mx); /* copy in name */ strncpy(cp->name, fullname, CELL_MAXNAMELEN); cp->name[CELL_MAXNAMELEN-1] = '\0'; strncpy(cp->linkedName, linkedName, CELL_MAXNAMELEN); cp->linkedName[CELL_MAXNAMELEN-1] = '\0'; lock_ObtainWrite(&cm_cellLock); hasWriteLock = 1; cm_AddCellToNameHashTable(cp); cm_AddCellToIDHashTable(cp); lock_ReleaseMutex(&cp->mx); hasMutex = 0; /* append cell to global list */ if (cm_data.allCellsp == NULL) { cm_data.allCellsp = cp; } else { for (cp2 = cm_data.allCellsp; cp2->allNextp; cp2=cp2->allNextp) ; cp2->allNextp = cp; } cp->allNextp = NULL; } else { lock_ReleaseRead(&cm_cellLock); } done: if (hasMutex && cp) lock_ReleaseMutex(&cp->mx); if (hasWriteLock) lock_ReleaseWrite(&cm_cellLock); /* fullname is not valid if cp == NULL */ if (newnamep) { if (cp) { strncpy(newnamep, fullname, CELL_MAXNAMELEN); newnamep[CELL_MAXNAMELEN-1]='\0'; } else { newnamep[0] = '\0'; } } if (cp && cp->linkedName[0]) { cm_cell_t * linkedCellp = NULL; if (!strcmp(cp->name, cp->linkedName)) { cp->linkedName[0] = '\0'; } else if (!(flags & CM_FLAG_NOMOUNTCHASE)) { linkedCellp = cm_GetCell(cp->linkedName, CM_FLAG_CREATE|CM_FLAG_NOPROBE|CM_FLAG_NOMOUNTCHASE); lock_ObtainWrite(&cm_cellLock); if (!linkedCellp || (linkedCellp->linkedName[0] && strcmp(cp->name, linkedCellp->linkedName))) { cp->linkedName[0] = '\0'; } else { strncpy(linkedCellp->linkedName, cp->name, CELL_MAXNAMELEN); linkedCellp->linkedName[CELL_MAXNAMELEN-1]='\0'; } lock_ReleaseWrite(&cm_cellLock); } } return cp; }
/* initialize the process. Reads the init files to get the appropriate * information. */ BOOL InitInstance( HANDLE hInstance, int nCmdShow) { HWND hWnd; HDC hDC; TEXTMETRIC textmetric; INT nLineHeight; long code, cnt; char *reason; /* remember this, since it is a useful thing for some of the Windows * calls */ main_inst = hInstance; /* create our window */ hWnd = CreateWindow( "AFSDWinClass", "AFSD", WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); if (!hWnd) return (FALSE); /* lookup text dimensions */ hDC = GetDC(hWnd); GetTextMetrics(hDC, &textmetric); nLineHeight = textmetric.tmExternalLeading + textmetric.tmHeight; main_rect.left = GetDeviceCaps(hDC, LOGPIXELSX) / 4; /* 1/4 inch */ main_rect.right = GetDeviceCaps(hDC, HORZRES); main_rect.top = GetDeviceCaps(hDC, LOGPIXELSY) / 4; /* 1/4 inch */ ReleaseDC(hWnd, hDC); main_rect.bottom = main_rect.top + nLineHeight; osi_InitPanic(afsd_notifier); afsi_start(); code = afsd_InitCM(&reason); if (code != 0) osi_panic(reason, __FILE__, __LINE__); code = afsd_InitDaemons(&reason); if (code != 0) osi_panic(reason, __FILE__, __LINE__); code = afsd_InitSMB(&reason, MessageBox); if (code != 0) osi_panic(reason, __FILE__, __LINE__); ShowWindow(hWnd, SW_SHOWMINNOACTIVE); UpdateWindow(hWnd); return (TRUE); }