11 extern void afsi_log(char *pattern, ...);
12 extern DWORD cm_ValidateCache;
14 static HANDLE hMemoryMappedFile = NULL;
15 static HANDLE hCacheHeap = NULL;
18 GranularityAdjustment(afs_uint64 size)
21 static afs_uint64 qwGranularity = 0;
23 if ( !qwGranularity ) {
24 GetSystemInfo(&sysInfo);
25 afsi_log("Granularity - %lX", sysInfo.dwAllocationGranularity);
26 qwGranularity = sysInfo.dwAllocationGranularity;
29 size = (size + (qwGranularity - 1)) & ~(qwGranularity - 1);
34 ComputeSizeOfConfigData(void)
37 size = sizeof(cm_config_data_t);
42 ComputeSizeOfVolumes(DWORD maxvols)
45 size = maxvols * sizeof(cm_volume_t);
50 ComputeSizeOfCellHT(DWORD maxcells)
53 size = cm_NextHighestPowerOf2((afs_uint32)(maxcells/7)) * sizeof(cm_cell_t *);
58 ComputeSizeOfVolumeHT(DWORD maxvols)
61 size = cm_NextHighestPowerOf2((afs_uint32)(maxvols/7)) * sizeof(cm_volume_t *);
66 ComputeSizeOfCells(DWORD maxcells)
69 size = maxcells * sizeof(cm_cell_t);
74 ComputeSizeOfACLCache(DWORD stats)
77 size = 2 * (stats + 10) * sizeof(cm_aclent_t);
82 ComputeSizeOfSCache(DWORD stats)
85 size = (stats + 10) * sizeof(cm_scache_t);
90 ComputeSizeOfSCacheHT(DWORD stats)
93 size = cm_NextHighestPowerOf2(stats / 2 ) * sizeof(cm_scache_t *);;
98 ComputeSizeOfDNLCache(void)
101 size = NHSIZE * sizeof(cm_nc_t *) + NCSIZE * sizeof(cm_nc_t);
106 ComputeSizeOfDataBuffers(afs_uint64 cacheBlocks, DWORD blockSize)
109 size = cacheBlocks * blockSize;
114 ComputeSizeOfDataHT(afs_uint64 cacheBlocks)
117 size = cm_NextHighestPowerOf2((afs_uint32)(cacheBlocks/7)) * sizeof(cm_buf_t *);
122 ComputeSizeOfDataHeaders(afs_uint64 cacheBlocks)
125 size = cacheBlocks * sizeof(cm_buf_t);
130 ComputeSizeOfMappingFile(DWORD stats, DWORD maxVols, DWORD maxCells, DWORD chunkSize, afs_uint64 cacheBlocks, DWORD blockSize)
134 size = ComputeSizeOfConfigData()
135 + ComputeSizeOfVolumes(maxVols)
136 + 4 * ComputeSizeOfVolumeHT(maxVols)
137 + ComputeSizeOfCells(maxCells)
138 + 2 * ComputeSizeOfCellHT(maxCells)
139 + ComputeSizeOfACLCache(stats)
140 + ComputeSizeOfSCache(stats)
141 + ComputeSizeOfSCacheHT(stats)
142 + ComputeSizeOfDNLCache()
143 + ComputeSizeOfDataBuffers(cacheBlocks, blockSize)
144 + 2 * ComputeSizeOfDataHT(cacheBlocks)
145 + ComputeSizeOfDataHeaders(cacheBlocks);
149 /* Create a security attribute structure suitable for use when the cache file
150 * is created. What we mainly want is that only the administrator should be
151 * able to do anything with the file. We create an ACL with only one entry,
152 * an entry that grants all rights to the administrator.
154 PSECURITY_ATTRIBUTES CreateCacheFileSA()
156 PSECURITY_ATTRIBUTES psa;
157 PSECURITY_DESCRIPTOR psd;
158 SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY;
160 DWORD AdminSIDlength;
164 /* Get Administrator SID */
165 AllocateAndInitializeSid(&authority, 2,
166 SECURITY_BUILTIN_DOMAIN_RID,
167 DOMAIN_ALIAS_RID_ADMINS,
171 /* Create Administrator-only ACL */
172 AdminSIDlength = GetLengthSid(AdminSID);
173 ACLlength = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE)
174 + AdminSIDlength - sizeof(DWORD);
175 AdminOnlyACL = GlobalAlloc(GMEM_FIXED, ACLlength);
176 InitializeAcl(AdminOnlyACL, ACLlength, ACL_REVISION);
177 AddAccessAllowedAce(AdminOnlyACL, ACL_REVISION,
178 STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
181 /* Create security descriptor */
182 psd = GlobalAlloc(GMEM_FIXED, sizeof(SECURITY_DESCRIPTOR));
183 InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION);
184 SetSecurityDescriptorDacl(psd, TRUE, AdminOnlyACL, FALSE);
186 /* Create security attributes structure */
187 psa = GlobalAlloc(GMEM_FIXED, sizeof(SECURITY_ATTRIBUTES));
188 psa->nLength = sizeof(SECURITY_ATTRIBUTES);
189 psa->lpSecurityDescriptor = psd;
190 psa->bInheritHandle = FALSE;
196 /* Free a security attribute structure created by CreateCacheFileSA() */
197 VOID FreeCacheFileSA(PSECURITY_ATTRIBUTES psa)
202 GetSecurityDescriptorDacl(psa->lpSecurityDescriptor, &b1, &pAcl, &b2);
204 GlobalFree(psa->lpSecurityDescriptor);
209 cm_IsCacheValid(void)
213 afsi_log("Validating Cache Contents");
215 if (cm_ValidateACLCache()) {
216 afsi_log("ACL Cache validation failure");
218 } else if (cm_ValidateDCache()) {
219 afsi_log("Data Cache validation failure");
221 } else if (cm_ValidateVolume()) {
222 afsi_log("Volume validation failure");
224 } else if (cm_ValidateCell()) {
225 afsi_log("Cell validation failure");
227 } else if (cm_ValidateSCache()) {
228 afsi_log("Stat Cache validation failure");
236 cm_ShutdownMappedMemory(void)
238 cm_config_data_t * config_data_p = (cm_config_data_t *)cm_data.baseAddress;
241 afsi_log("Closing AFS Cache:");
242 afsi_log(" Base Address = %p", config_data_p);
243 afsi_log(" stats = %u", cm_data.stats);
244 afsi_log(" chunkSize = %u", cm_data.chunkSize);
245 afsi_log(" blockSize = %u", cm_data.blockSize);
246 afsi_log(" bufferSize = %I64u", cm_data.bufferSize);
247 afsi_log(" cacheType = %u", cm_data.cacheType);
248 afsi_log(" volumeHashTableSize = %u", cm_data.volumeHashTableSize);
249 afsi_log(" currentVolumes = %u", cm_data.currentVolumes);
250 afsi_log(" maxVolumes = %u", cm_data.maxVolumes);
251 afsi_log(" cellHashTableSize = %u", cm_data.cellHashTableSize);
252 afsi_log(" currentCells = %u", cm_data.currentCells);
253 afsi_log(" maxCells = %u", cm_data.maxCells);
254 afsi_log(" scacheHashTableSize = %u", cm_data.scacheHashTableSize);
255 afsi_log(" currentSCaches = %u", cm_data.currentSCaches);
256 afsi_log(" maxSCaches = %u", cm_data.maxSCaches);
260 cm_ShutdownACLCache();
265 HeapFree(hCacheHeap, 0, cm_data.baseAddress);
266 HeapDestroy(hCacheHeap);
267 afsi_log("Memory Heap has been destroyed");
269 if (cm_ValidateCache == 2)
270 dirty = !cm_IsCacheValid();
272 *config_data_p = cm_data;
273 config_data_p->dirty = dirty;
274 UnmapViewOfFile(config_data_p);
275 CloseHandle(hMemoryMappedFile);
276 hMemoryMappedFile = NULL;
277 afsi_log("Memory Mapped File has been closed");
283 cm_ValidateMappedMemory(char * cachePath)
285 HANDLE hf = INVALID_HANDLE_VALUE, hm;
286 PSECURITY_ATTRIBUTES psa;
287 BY_HANDLE_FILE_INFORMATION fileInfo;
289 afs_uint64 mappingSize;
290 char * baseAddress = NULL;
291 cm_config_data_t * config_data_p;
293 psa = CreateCacheFileSA();
294 hf = CreateFile( cachePath,
295 GENERIC_READ | GENERIC_WRITE,
296 FILE_SHARE_READ | FILE_SHARE_WRITE,
299 FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM |
300 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_FLAG_RANDOM_ACCESS,
302 FreeCacheFileSA(psa);
304 if (hf == INVALID_HANDLE_VALUE) {
305 fprintf(stderr, "Error creating cache file \"%s\" error %d\n",
306 cachePath, GetLastError());
307 return CM_ERROR_INVAL;
310 /* The file is being re-used; check to see if the existing data can be reused */
311 if ( !GetFileInformationByHandle(hf, &fileInfo) ) {
313 fprintf(stderr, "Unable to obtain File Information\n");
314 return CM_ERROR_INVAL;
317 afsi_log("Existing File Size: %08X:%08X",
318 fileInfo.nFileSizeHigh,
319 fileInfo.nFileSizeLow);
321 hm = CreateFileMapping( hf,
325 sizeof(cm_config_data_t),
328 if (GetLastError() == ERROR_DISK_FULL) {
329 fprintf(stderr, "Error creating file mapping for \"%s\": disk full (%lX)\n",
330 cachePath, sizeof(cm_config_data_t));
332 hm = CreateFileMapping( hf,
336 fileInfo.nFileSizeLow,
339 if (GetLastError() == ERROR_DISK_FULL) {
341 return CM_ERROR_TOOMANYBUFS;
343 fprintf(stderr,"Error creating file mapping for \"%s\": %d\n",
344 cachePath, GetLastError());
346 return CM_ERROR_INVAL;
349 fprintf(stderr, "Retry with file size (%lX) succeeds",
350 fileInfo.nFileSizeLow);
353 afsi_log("Error creating file mapping for \"%s\": %d",
354 cachePath, GetLastError());
356 return CM_ERROR_INVAL;
360 config_data_p = MapViewOfFile( hm,
363 sizeof(cm_config_data_t));
364 if ( config_data_p == NULL ) {
365 fprintf(stderr, "Unable to MapViewOfFile\n");
366 if (hf != INVALID_HANDLE_VALUE)
369 return CM_ERROR_INVAL;
372 if ( config_data_p->size != sizeof(cm_config_data_t) ) {
373 fprintf(stderr, "AFSCache Header Size 0x%08X != afsd_service Header Size 0x%08X\n",
374 config_data_p->size, sizeof(cm_config_data_t));
375 UnmapViewOfFile(config_data_p);
378 return CM_ERROR_INVAL;
381 if ( config_data_p->magic != CM_CONFIG_DATA_MAGIC ) {
382 fprintf(stderr, "AFSCache Magic 0x%08X != afsd_service Magic 0x%08X\n",
383 config_data_p->magic, CM_CONFIG_DATA_MAGIC);
384 UnmapViewOfFile(config_data_p);
387 return CM_ERROR_INVAL;
390 if ( config_data_p->dirty ) {
391 fprintf(stderr, "Previous session terminated prematurely\n");
392 UnmapViewOfFile(config_data_p);
395 return CM_ERROR_INVAL;
398 mappingSize = config_data_p->bufferSize;
399 baseAddress = config_data_p->baseAddress;
400 UnmapViewOfFile(config_data_p);
403 hm = CreateFileMapping( hf,
406 (DWORD)(mappingSize >> 32),
407 (DWORD)(mappingSize & 0xFFFFFFFF),
410 if (GetLastError() == ERROR_DISK_FULL) {
411 fprintf(stderr, "Error creating file mapping for \"%s\": disk full [2]\n",
414 return CM_ERROR_TOOMANYBUFS;
416 fprintf(stderr, "Error creating file mapping for \"%s\": %d\n",
417 cachePath, GetLastError());
419 return CM_ERROR_INVAL;
422 baseAddress = MapViewOfFileEx( hm,
427 if (baseAddress == NULL) {
428 fprintf(stderr, "Error mapping view of file: %d\n", GetLastError());
429 baseAddress = MapViewOfFile( hm,
432 (SIZE_T)mappingSize);
433 if (baseAddress == NULL) {
435 if (hf != INVALID_HANDLE_VALUE)
437 return CM_ERROR_INVAL;
439 fprintf(stderr, "Unable to re-load cache file at base address\n");
441 if (hf != INVALID_HANDLE_VALUE)
443 return CM_ERROR_INVAL;
447 config_data_p = (cm_config_data_t *) baseAddress;
449 fprintf(stderr,"AFS Cache data:\n");
450 fprintf(stderr," Header size = %u\n", config_data_p->size);
451 fprintf(stderr," Magic = %08x\n", config_data_p->magic);
452 fprintf(stderr," Base Address = %p\n", baseAddress);
453 fprintf(stderr," stats = %u\n", config_data_p->stats);
454 fprintf(stderr," chunkSize = %u\n", config_data_p->chunkSize);
455 fprintf(stderr," blockSize = %u\n", config_data_p->blockSize);
456 fprintf(stderr," bufferSize = %I64u\n", config_data_p->bufferSize);
457 fprintf(stderr," cacheType = %u\n", config_data_p->cacheType);
458 fprintf(stderr," dirty = %u\n", config_data_p->dirty);
459 fprintf(stderr," volumeHashTableSize = %u\n", config_data_p->volumeHashTableSize);
460 fprintf(stderr," currentVolumes = %u\n", config_data_p->currentVolumes);
461 fprintf(stderr," maxVolumes = %u\n", config_data_p->maxVolumes);
462 fprintf(stderr," cellHashTableSize = %u\n", config_data_p->cellHashTableSize);
463 fprintf(stderr," currentCells = %u\n", config_data_p->currentCells);
464 fprintf(stderr," maxCells = %u\n", config_data_p->maxCells);
465 fprintf(stderr," scacheHashTableSize = %u\n", config_data_p->scacheHashTableSize);
466 fprintf(stderr," currentSCaches = %u\n", config_data_p->currentSCaches);
467 fprintf(stderr," maxSCaches = %u\n", config_data_p->maxSCaches);
468 cm_data = *config_data_p;
470 // perform validation of persisted data structures
471 // if there is a failure, start from scratch
472 if (!cm_IsCacheValid()) {
473 fprintf(stderr,"Cache file fails validation test\n");
474 UnmapViewOfFile(config_data_p);
475 return CM_ERROR_INVAL;
478 fprintf(stderr,"Cache passes validation test\n");
479 UnmapViewOfFile(config_data_p);
484 GetVolSerialNumber(char * cachePath)
490 if ( cachePath[0] == '\\' && cachePath[1] == '\\' ||
491 cachePath[0] == '/' && cachePath[1] == '/' )
493 rootpath[0]=rootpath[1]='\\';
494 for ( i=2; cachePath[i]; i++ ) {
495 rootpath[i] = cachePath[i];
496 if ( cachePath[i] == '\\' || cachePath[i] == '/' ) {
501 } else if ( cachePath[1] == ':' ) {
502 rootpath[0] = cachePath[0];
507 for ( ; cachePath[i]; i++ ) {
508 rootpath[i] = cachePath[i];
509 if ( cachePath[i] == '\\' || cachePath[i] == '/' ) {
516 GetVolumeInformation(rootpath, NULL, 0, &serial, NULL, NULL, NULL, 0);
520 BOOL GetTextualSid( PSID pSid, PBYTE TextualSid, LPDWORD lpdwBufferLen )
522 PSID_IDENTIFIER_AUTHORITY psia;
523 DWORD dwSubAuthorities;
524 DWORD dwSidRev=SID_REVISION;
528 // Validate the binary SID.
529 if(!IsValidSid(pSid))
532 // Get the identifier authority value from the SID.
534 psia = GetSidIdentifierAuthority(pSid);
536 // Get the number of subauthorities in the SID.
538 dwSubAuthorities = *GetSidSubAuthorityCount(pSid);
540 // Compute the buffer length.
541 // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL
543 dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1);
545 // Check input buffer length.
546 // If too small, indicate the proper size and set the last error.
548 if (TextualSid == NULL || *lpdwBufferLen < dwSidSize)
550 *lpdwBufferLen = dwSidSize;
551 SetLastError(ERROR_INSUFFICIENT_BUFFER);
555 // Add 'S' prefix and revision number to the string.
556 dwSidSize=sprintf(TextualSid, "S-%lu-", dwSidRev );
558 // Add a SID identifier authority to the string.
559 if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )
561 dwSidSize+=sprintf(TextualSid + strlen(TextualSid),
562 "0x%02hx%02hx%02hx%02hx%02hx%02hx",
563 (USHORT)psia->Value[0],
564 (USHORT)psia->Value[1],
565 (USHORT)psia->Value[2],
566 (USHORT)psia->Value[3],
567 (USHORT)psia->Value[4],
568 (USHORT)psia->Value[5]);
572 dwSidSize+=sprintf(TextualSid + strlen(TextualSid),
574 (ULONG)(psia->Value[5] ) +
575 (ULONG)(psia->Value[4] << 8) +
576 (ULONG)(psia->Value[3] << 16) +
577 (ULONG)(psia->Value[2] << 24) );
580 // Add SID subauthorities to the string.
582 for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
584 dwSidSize+=sprintf(TextualSid + dwSidSize, "-%lu",
585 *GetSidSubAuthority(pSid, dwCounter) );
592 IsSubAuthValid( PBYTE SidData, DWORD SidLength )
597 if ( SidLength % sizeof(DWORD) == 0 ) {
598 for ( sidPtr = SidData + SidLength - 5*sizeof(DWORD);
600 sidPtr -= sizeof(DWORD) )
601 if ( ((PDWORD)sidPtr)[1] == 0x05000000 &&
602 ((PDWORD)sidPtr)[2] == 0x00000015 )
604 if ( sidPtr < SidData )
611 GetMachineSid(PBYTE SidBuffer, DWORD SidSize)
624 // Read the last subauthority of the current computer SID
626 if( RegOpenKey( HKEY_LOCAL_MACHINE, "SECURITY\\SAM\\Domains\\Account",
627 &hKey) != ERROR_SUCCESS ) {
632 RegQueryValueEx( hKey, "V", NULL, &dwType, vData, &dwLen );
633 vData = (PBYTE) malloc( dwLen );
634 dwStatus = RegQueryValueEx( hKey, "V", NULL, &dwType, vData, &dwLen );
636 if( dwStatus != ERROR_SUCCESS ) {
641 // Make sure that we're dealing with a SID we understand
643 pSid = IsSubAuthValid( vData, dwLen );
645 if( !pSid || SidSize < dwLen - (pSid - vData)) {
650 memset(SidBuffer, 0, SidSize);
651 memcpy(SidBuffer, pSid, dwLen - (pSid - vData) );
657 cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD maxVols, DWORD maxCells,
658 DWORD chunkSize, afs_uint64 cacheBlocks, afs_uint32 blockSize)
660 afs_uint64 mappingSize;
662 DWORD volumeSerialNumber = 0;
663 DWORD sidStringSize = 0;
665 CHAR machineSid[6 * sizeof(DWORD)]="";
666 char * baseAddress = NULL;
667 cm_config_data_t * config_data_p;
670 volumeSerialNumber = GetVolSerialNumber(cachePath);
671 GetMachineSid(machineSid, sizeof(machineSid));
673 mappingSize = ComputeSizeOfMappingFile(stats, maxVols, maxCells, chunkSize, cacheBlocks, blockSize);
675 if ( virtualCache ) {
676 hCacheHeap = HeapCreate( HEAP_GENERATE_EXCEPTIONS, 0, 0);
678 baseAddress = HeapAlloc(hCacheHeap, 0, mappingSize);
680 if (baseAddress == NULL) {
681 afsi_log("Error allocating Virtual Memory gle=%d",
683 return CM_ERROR_INVAL;
687 HANDLE hf = INVALID_HANDLE_VALUE, hm;
688 PSECURITY_ATTRIBUTES psa;
690 psa = CreateCacheFileSA();
691 hf = CreateFile( cachePath,
692 GENERIC_READ | GENERIC_WRITE,
693 FILE_SHARE_READ | FILE_SHARE_WRITE,
696 FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM |
697 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_FLAG_RANDOM_ACCESS,
699 FreeCacheFileSA(psa);
701 if (hf == INVALID_HANDLE_VALUE) {
702 afsi_log("Error creating cache file \"%s\" error %d",
703 cachePath, GetLastError());
704 return CM_ERROR_INVAL;
707 if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
708 BY_HANDLE_FILE_INFORMATION fileInfo;
710 /* The file is being re-used; check to see if the existing data can be reused */
711 afsi_log("Cache File \"%s\" already exists", cachePath);
713 if ( GetFileInformationByHandle(hf, &fileInfo) ) {
715 afsi_log("Existing File Size: %08X:%08X",
716 fileInfo.nFileSizeHigh,
717 fileInfo.nFileSizeLow);
718 filesize = fileInfo.nFileSizeHigh;
720 filesize += fileInfo.nFileSizeLow;
721 if (filesize > GranularityAdjustment(mappingSize)) {
722 psa = CreateCacheFileSA();
723 hf = CreateFile( cachePath,
724 GENERIC_READ | GENERIC_WRITE,
725 FILE_SHARE_READ | FILE_SHARE_WRITE,
728 FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM |
729 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_FLAG_RANDOM_ACCESS,
731 FreeCacheFileSA(psa);
733 if (hf == INVALID_HANDLE_VALUE) {
734 afsi_log("Error creating cache file \"%s\" error %d",
735 cachePath, GetLastError());
736 return CM_ERROR_INVAL;
739 GetFileInformationByHandle(hf, &fileInfo);
740 afsi_log(" New File Size: %08X:%08X",
741 fileInfo.nFileSizeHigh,
742 fileInfo.nFileSizeLow);
746 hm = CreateFileMapping( hf,
750 sizeof(cm_config_data_t),
753 if (GetLastError() == ERROR_DISK_FULL) {
754 afsi_log("Error creating file mapping for \"%s\": disk full (%lX)",
755 cachePath, sizeof(cm_config_data_t));
757 hm = CreateFileMapping( hf,
760 (DWORD)(mappingSize >> 32),
761 (DWORD)(mappingSize & 0xFFFFFFFF),
764 if (GetLastError() == ERROR_DISK_FULL) {
766 return CM_ERROR_TOOMANYBUFS;
768 afsi_log("Error creating file mapping for \"%s\": %d",
769 cachePath, GetLastError());
771 return CM_ERROR_INVAL;
774 afsi_log("Retry with mapping size (%lX) succeeds", mappingSize);
777 afsi_log("Error creating file mapping for \"%s\": %d",
778 cachePath, GetLastError());
780 return CM_ERROR_INVAL;
784 config_data_p = MapViewOfFile( hm,
787 sizeof(cm_config_data_t));
788 if ( config_data_p == NULL ) {
789 if (hf != INVALID_HANDLE_VALUE)
792 return CM_ERROR_INVAL;
795 if ( config_data_p->size == sizeof(cm_config_data_t) &&
796 config_data_p->magic == CM_CONFIG_DATA_MAGIC &&
797 config_data_p->stats == stats &&
798 config_data_p->maxVolumes == maxVols &&
799 config_data_p->maxCells == maxCells &&
800 config_data_p->chunkSize == chunkSize &&
801 config_data_p->buf_nbuffers == cacheBlocks &&
802 config_data_p->blockSize == blockSize &&
803 config_data_p->bufferSize == mappingSize)
805 if ( config_data_p->dirty ) {
806 afsi_log("Previous session terminated prematurely");
808 baseAddress = config_data_p->baseAddress;
812 afsi_log("Configuration changed or Not a persistent cache file");
814 UnmapViewOfFile(config_data_p);
818 hm = CreateFileMapping( hf,
821 (DWORD)(mappingSize >> 32),
822 (DWORD)(mappingSize & 0xFFFFFFFF),
825 if (GetLastError() == ERROR_DISK_FULL) {
826 afsi_log("Error creating file mapping for \"%s\": disk full [2]",
828 return CM_ERROR_TOOMANYBUFS;
830 afsi_log("Error creating file mapping for \"%s\": %d",
831 cachePath, GetLastError());
832 return CM_ERROR_INVAL;
834 baseAddress = MapViewOfFileEx( hm,
840 if (baseAddress == NULL) {
841 afsi_log("Error mapping view of file: %d", GetLastError());
842 baseAddress = MapViewOfFile( hm,
846 (SIZE_T)mappingSize);
847 if (baseAddress == NULL) {
848 if (hf != INVALID_HANDLE_VALUE)
851 return CM_ERROR_INVAL;
856 hMemoryMappedFile = hf;
859 config_data_p = (cm_config_data_t *) baseAddress;
862 afsi_log("Reusing existing AFS Cache data:");
863 cm_data = *config_data_p;
865 afsi_log(" Map Address = %p", baseAddress);
866 afsi_log(" baseAddress = %p", config_data_p->baseAddress);
867 afsi_log(" stats = %u", config_data_p->stats);
868 afsi_log(" chunkSize = %u", config_data_p->chunkSize);
869 afsi_log(" blockSize = %u", config_data_p->blockSize);
870 afsi_log(" bufferSize = %I64u", config_data_p->bufferSize);
871 afsi_log(" cacheType = %u", config_data_p->cacheType);
872 afsi_log(" volumeHashTableSize = %u", config_data_p->volumeHashTableSize);
873 afsi_log(" currentVolumes = %u", config_data_p->currentVolumes);
874 afsi_log(" maxVolumes = %u", config_data_p->maxVolumes);
875 afsi_log(" cellHashTableSize = %u", config_data_p->cellHashTableSize);
876 afsi_log(" currentCells = %u", config_data_p->currentCells);
877 afsi_log(" maxCells = %u", config_data_p->maxCells);
878 afsi_log(" scacheHashTableSize = %u", config_data_p->scacheHashTableSize);
879 afsi_log(" currentSCaches = %u", config_data_p->currentSCaches);
880 afsi_log(" maxSCaches = %u", config_data_p->maxSCaches);
883 * perform validation of persisted data structures
884 * if there is a failure, start from scratch
886 * if the baseAddress changed then the embedded pointers
887 * within the data structures are no longer valid.
888 * in theory we could walk the tree and adjust the pointer
889 * values based on the offet but that has not been
892 if (baseAddress != cm_data.baseAddress ||
893 cm_ValidateCache && !cm_IsCacheValid()) {
899 afsi_log("Building AFS Cache from scratch");
900 memset(&cm_data, 0, sizeof(cm_config_data_t));
901 cm_data.size = sizeof(cm_config_data_t);
902 cm_data.magic = CM_CONFIG_DATA_MAGIC;
903 cm_data.baseAddress = baseAddress;
904 cm_data.stats = stats;
905 cm_data.chunkSize = chunkSize;
906 cm_data.blockSize = blockSize;
907 cm_data.bufferSize = mappingSize;
909 cm_data.scacheHashTableSize = cm_NextHighestPowerOf2(stats / 2);
910 cm_data.volumeHashTableSize = cm_NextHighestPowerOf2((afs_uint32)(maxVols/7));
911 cm_data.cellHashTableSize = cm_NextHighestPowerOf2((afs_uint32)(maxCells/7));
913 cm_data.cacheType = CM_BUF_CACHETYPE_VIRTUAL;
915 cm_data.cacheType = CM_BUF_CACHETYPE_FILE;
918 cm_data.buf_nbuffers = cacheBlocks;
919 cm_data.buf_nOrigBuffers = cacheBlocks;
920 cm_data.buf_usedCount = 0;
921 cm_data.buf_blockSize = blockSize;
922 cm_data.buf_hashSize = cm_NextHighestPowerOf2((afs_uint32)(cacheBlocks/7));
924 cm_data.mountRootGen = 0;
926 baseAddress += ComputeSizeOfConfigData();
927 cm_data.volumeBaseAddress = (cm_volume_t *) baseAddress;
928 baseAddress += ComputeSizeOfVolumes(maxVols);
929 cm_data.volumeNameHashTablep = (cm_volume_t **)baseAddress;
930 baseAddress += ComputeSizeOfVolumeHT(maxVols);
931 cm_data.volumeRWIDHashTablep = (cm_volume_t **)baseAddress;
932 baseAddress += ComputeSizeOfVolumeHT(maxVols);
933 cm_data.volumeROIDHashTablep = (cm_volume_t **)baseAddress;
934 baseAddress += ComputeSizeOfVolumeHT(maxVols);
935 cm_data.volumeBKIDHashTablep = (cm_volume_t **)baseAddress;
936 baseAddress += ComputeSizeOfVolumeHT(maxVols);
937 cm_data.cellNameHashTablep = (cm_cell_t **)baseAddress;
938 baseAddress += ComputeSizeOfCellHT(maxCells);
939 cm_data.cellIDHashTablep = (cm_cell_t **)baseAddress;
940 baseAddress += ComputeSizeOfCellHT(maxCells);
941 cm_data.cellBaseAddress = (cm_cell_t *) baseAddress;
942 baseAddress += ComputeSizeOfCells(maxCells);
943 cm_data.aclBaseAddress = (cm_aclent_t *) baseAddress;
944 baseAddress += ComputeSizeOfACLCache(stats);
945 cm_data.scacheBaseAddress = (cm_scache_t *) baseAddress;
946 baseAddress += ComputeSizeOfSCache(stats);
947 cm_data.scacheHashTablep = (cm_scache_t **) baseAddress;
948 baseAddress += ComputeSizeOfSCacheHT(stats);
949 cm_data.dnlcBaseAddress = (cm_nc_t *) baseAddress;
950 baseAddress += ComputeSizeOfDNLCache();
951 cm_data.buf_scacheHashTablepp = (cm_buf_t **) baseAddress;
952 baseAddress += ComputeSizeOfDataHT(cacheBlocks);
953 cm_data.buf_fileHashTablepp = (cm_buf_t **) baseAddress;
954 baseAddress += ComputeSizeOfDataHT(cacheBlocks);
955 cm_data.bufHeaderBaseAddress = (cm_buf_t *) baseAddress;
956 baseAddress += ComputeSizeOfDataHeaders(cacheBlocks);
957 cm_data.bufDataBaseAddress = (char *) baseAddress;
958 baseAddress += ComputeSizeOfDataBuffers(cacheBlocks, blockSize);
959 cm_data.bufEndOfData = (char *) baseAddress;
960 cm_data.buf_dirtyListp = NULL;
961 cm_data.buf_dirtyListEndp = NULL;
962 /* Make sure the fakeDirVersion is always increasing */
963 cm_data.fakeDirVersion = time(NULL);
964 cm_data.fakeUnique = 0;
965 UuidCreate((UUID *)&cm_data.Uuid);
966 cm_data.volSerialNumber = volumeSerialNumber;
967 memcpy(cm_data.Sid, machineSid, sizeof(machineSid));
970 * make sure that the file is fully allocated
971 * by writing a non-zero byte to the end
973 cm_data.baseAddress[mappingSize-1] = 0xFF;
977 if ( volumeSerialNumber == 0 || volumeSerialNumber != cm_data.volSerialNumber ) {
979 afsi_log("Volume serial number change, generating new UUID");
980 afsi_log("Old volume Serial Number: 0x%x", cm_data.volSerialNumber);
981 } else if ( machineSid[0] && memcmp(machineSid, cm_data.Sid, sizeof(machineSid))) {
983 afsi_log("Machine Sid changed, generating new UUID");
984 GetTextualSid( (PSID)cm_data.Sid, NULL, &sidStringSize );
986 p = malloc(sidStringSize * sizeof(TCHAR));
988 rc = GetTextualSid( (PSID)cm_data.Sid, p, &sidStringSize );
989 afsi_log("Old Machine SID: %s", rc ? p : "unknown");
993 afsi_log("Old Machine SID: unknown");
998 UuidCreate((UUID *)&cm_data.Uuid);
999 cm_data.volSerialNumber = volumeSerialNumber;
1000 memcpy(cm_data.Sid, machineSid, sizeof(machineSid));
1004 afsi_log("Volume Serial Number: 0x%x", cm_data.volSerialNumber);
1006 GetTextualSid( (PSID)cm_data.Sid, NULL, &sidStringSize );
1007 if (sidStringSize) {
1008 p = malloc(sidStringSize * sizeof(TCHAR));
1010 rc = GetTextualSid( (PSID)cm_data.Sid, p, &sidStringSize );
1011 afsi_log("Machine SID: %s", rc ? p : "unknown");
1015 afsi_log("Machine SID: unknown");
1018 UuidToString((UUID *)&cm_data.Uuid, &p);
1019 afsi_log("Initializing Uuid to %s",p);
1022 afsi_log("Initializing Volume Data");
1023 cm_InitVolume(newCache, maxVols);
1025 afsi_log("Initializing Cell Data");
1026 cm_InitCell(newCache, maxCells);
1028 afsi_log("Initializing ACL Data");
1029 cm_InitACLCache(newCache, 2*stats);
1031 afsi_log("Initializing Stat Data");
1032 cm_InitSCache(newCache, stats);
1034 afsi_log("Initializing Data Buffers");
1035 cm_InitDCache(newCache, 0, cacheBlocks);
1037 *config_data_p = cm_data;
1038 config_data_p->dirty = 1;
1040 afsi_log("Cache Initialization Complete");