89b387b9f3367d7ec50c39560c31e97560349567
[openafs.git] / src / WINNT / afsd / cm_memmap.c
1 #include <windows.h>
2 #include "afsd.h"
3 #include "cm_memmap.h"
4
5 extern void afsi_log(char *pattern, ...);
6 extern DWORD cm_ValidateCache;
7
8 DWORD
9 GranularityAdjustment(DWORD size)
10 {
11     SYSTEM_INFO sysInfo;
12     static DWORD dwGranularity = 0;
13
14     if ( !dwGranularity ) {
15         GetSystemInfo(&sysInfo);
16         afsi_log("Granularity - %lX", sysInfo.dwAllocationGranularity);
17         dwGranularity = sysInfo.dwAllocationGranularity;
18     }
19
20     size = (size + (dwGranularity - 1)) & ~(dwGranularity - 1);
21     return size;
22 }
23
24 DWORD 
25 ComputeSizeOfConfigData(void)
26 {
27     DWORD size;
28     size = sizeof(cm_config_data_t);
29     return size;
30 }
31
32 DWORD
33 ComputeSizeOfVolumes(DWORD maxvols)
34 {
35     DWORD size;
36     size = maxvols * sizeof(cm_volume_t);
37     return size;
38 }
39
40 DWORD
41 ComputeSizeOfCells(DWORD maxcells)
42 {
43     DWORD size;
44     size = maxcells * sizeof(cm_cell_t);
45     return size;
46 }
47
48 DWORD 
49 ComputeSizeOfACLCache(DWORD stats)
50 {
51     DWORD size;
52     size = 2 * (stats + 10) * sizeof(cm_aclent_t);
53     return size;
54 }
55
56 DWORD 
57 ComputeSizeOfSCache(DWORD stats)
58 {
59     DWORD size;
60     size = (stats + 10) * sizeof(cm_scache_t);
61     return size;
62 }
63
64 DWORD 
65 ComputeSizeOfSCacheHT(DWORD stats)
66 {
67     DWORD size;
68     size = (stats + 10) / 2 * sizeof(cm_scache_t *);;
69     return size;
70 }
71
72 DWORD 
73 ComputeSizeOfDNLCache(void)
74 {
75     DWORD size;
76     size = NHSIZE * sizeof(cm_nc_t *) + NCSIZE * sizeof(cm_nc_t);
77     return size;
78 }
79
80 DWORD 
81 ComputeSizeOfDataBuffers(DWORD cacheBlocks, DWORD blockSize)
82 {
83     DWORD size;
84     size = cacheBlocks * blockSize;
85     return size;
86 }
87
88 DWORD 
89 ComputeSizeOfDataHT(void)
90 {
91     DWORD size;
92     size = osi_PrimeLessThan(CM_BUF_HASHSIZE) * sizeof(cm_buf_t *);
93     return size;
94 }
95
96 DWORD 
97 ComputeSizeOfDataHeaders(DWORD cacheBlocks)
98 {
99     DWORD size;
100     size = cacheBlocks * sizeof(cm_buf_t);
101     return size;
102 }
103
104 DWORD
105 ComputeSizeOfMappingFile(DWORD stats, DWORD chunkSize, DWORD cacheBlocks, DWORD blockSize)
106 {
107     DWORD size;
108     
109     size       =  ComputeSizeOfConfigData()
110                +  ComputeSizeOfVolumes(stats/2) 
111                +  ComputeSizeOfCells(stats/4) 
112                +  ComputeSizeOfACLCache(stats)
113                +  ComputeSizeOfSCache(stats)
114                +  ComputeSizeOfSCacheHT(stats)
115                +  ComputeSizeOfDNLCache()
116                +  ComputeSizeOfDataBuffers(cacheBlocks, blockSize) 
117                +  2 * ComputeSizeOfDataHT() 
118                +  ComputeSizeOfDataHeaders(cacheBlocks);
119     return size;    
120 }
121
122 /* Create a security attribute structure suitable for use when the cache file
123  * is created.  What we mainly want is that only the administrator should be
124  * able to do anything with the file.  We create an ACL with only one entry,
125  * an entry that grants all rights to the administrator.
126  */
127 PSECURITY_ATTRIBUTES CreateCacheFileSA()
128 {
129     PSECURITY_ATTRIBUTES psa;
130     PSECURITY_DESCRIPTOR psd;
131     SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY;
132     PSID AdminSID;
133     DWORD AdminSIDlength;
134     PACL AdminOnlyACL;
135     DWORD ACLlength;
136
137     /* Get Administrator SID */
138     AllocateAndInitializeSid(&authority, 2,
139                               SECURITY_BUILTIN_DOMAIN_RID,
140                               DOMAIN_ALIAS_RID_ADMINS,
141                               0, 0, 0, 0, 0, 0,
142                               &AdminSID);
143
144     /* Create Administrator-only ACL */
145     AdminSIDlength = GetLengthSid(AdminSID);
146     ACLlength = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE)
147         + AdminSIDlength - sizeof(DWORD);
148     AdminOnlyACL = GlobalAlloc(GMEM_FIXED, ACLlength);
149     InitializeAcl(AdminOnlyACL, ACLlength, ACL_REVISION);
150     AddAccessAllowedAce(AdminOnlyACL, ACL_REVISION,
151                          STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
152                          AdminSID);
153
154     /* Create security descriptor */
155     psd = GlobalAlloc(GMEM_FIXED, sizeof(SECURITY_DESCRIPTOR));
156     InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION);
157     SetSecurityDescriptorDacl(psd, TRUE, AdminOnlyACL, FALSE);
158
159     /* Create security attributes structure */
160     psa = GlobalAlloc(GMEM_FIXED, sizeof(SECURITY_ATTRIBUTES));
161     psa->nLength = sizeof(SECURITY_ATTRIBUTES);
162     psa->lpSecurityDescriptor = psd;
163     psa->bInheritHandle = TRUE;
164
165     return psa;
166 }       
167
168
169 /* Free a security attribute structure created by CreateCacheFileSA() */
170 VOID FreeCacheFileSA(PSECURITY_ATTRIBUTES psa)
171 {
172     BOOL b1, b2;
173     PACL pAcl;
174
175     GetSecurityDescriptorDacl(psa->lpSecurityDescriptor, &b1, &pAcl, &b2);
176     GlobalFree(pAcl);
177     GlobalFree(psa->lpSecurityDescriptor);
178     GlobalFree(psa);
179 }       
180
181 static HANDLE hMemoryMappedFile = NULL;
182
183 int
184 cm_IsCacheValid(void)
185 {
186     int rc = 1;
187
188     afsi_log("Validating Cache Contents");
189
190     if (cm_ValidateACLCache()) {
191         afsi_log("ACL Cache validation failure");
192         rc = 0;
193     } else if (cm_ValidateDCache()) {
194         afsi_log("Data Cache validation failure");
195         rc = 0;
196     } else if (cm_ValidateVolume()) {
197         afsi_log("Volume validation failure");
198         rc = 0;
199     } else if (cm_ValidateCell()) {
200         afsi_log("Cell validation failure");
201         rc = 0;
202     } else if (cm_ValidateSCache()) {
203         afsi_log("Stat Cache validation failure");
204         rc = 0;
205     }
206
207     return rc;
208 }
209
210 int
211 cm_ShutdownMappedMemory(void)
212 {
213     cm_config_data_t * config_data_p = (cm_config_data_t *)cm_data.baseAddress;
214     int dirty = 0;
215
216     cm_ShutdownDCache();
217     cm_ShutdownSCache();
218     cm_ShutdownACLCache();
219     cm_ShutdownCell();
220     cm_ShutdownVolume();
221
222     if (cm_ValidateCache == 2)
223         dirty = !cm_IsCacheValid();
224
225     *config_data_p = cm_data;
226     config_data_p->dirty = dirty;
227     UnmapViewOfFile(config_data_p);
228     CloseHandle(hMemoryMappedFile);
229     hMemoryMappedFile = NULL;
230
231     afsi_log("Memory Mapped File has been closed");
232 }
233
234 int
235 cm_ValidateMappedMemory(char * cachePath)
236 {
237     HANDLE hf = INVALID_HANDLE_VALUE, hm;
238     PSECURITY_ATTRIBUTES psa;
239     BY_HANDLE_FILE_INFORMATION fileInfo;
240     int newFile = 1;
241     DWORD mappingSize;
242     char * baseAddress = NULL;
243     cm_config_data_t * config_data_p;
244         
245     psa = CreateCacheFileSA();
246     hf = CreateFile( cachePath,
247                      GENERIC_READ | GENERIC_WRITE,
248                      FILE_SHARE_READ | FILE_SHARE_WRITE,
249                      psa,
250                      OPEN_EXISTING,
251                      FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | 
252                      FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_FLAG_RANDOM_ACCESS,
253                      NULL);
254     FreeCacheFileSA(psa);
255
256     if (hf == INVALID_HANDLE_VALUE) {
257         fprintf(stderr, "Error creating cache file \"%s\" error %d\n", 
258                  cachePath, GetLastError());
259         return CM_ERROR_INVAL;
260     }
261
262     /* The file is being re-used; check to see if the existing data can be reused */
263     if ( !GetFileInformationByHandle(hf, &fileInfo) ) {
264         CloseHandle(hf);
265         fprintf(stderr, "Unable to obtain File Information\n");
266         return CM_ERROR_INVAL;
267     }
268
269     afsi_log("Existing File Size: %08X:%08X",
270               fileInfo.nFileSizeHigh,
271               fileInfo.nFileSizeLow);
272             
273     hm = CreateFileMapping( hf,
274                             NULL,
275                             PAGE_READWRITE,
276                             0, 
277                             sizeof(cm_config_data_t),
278                             NULL);
279     if (hm == NULL) {
280         if (GetLastError() == ERROR_DISK_FULL) {
281             fprintf(stderr, "Error creating file mapping for \"%s\": disk full (%lX)\n",
282                      cachePath, sizeof(cm_config_data_t));
283
284             hm = CreateFileMapping( hf,
285                                     NULL,
286                                     PAGE_READWRITE,
287                                     0, 
288                                     fileInfo.nFileSizeLow,
289                                     NULL);
290             if (hm == NULL) {
291                 if (GetLastError() == ERROR_DISK_FULL) {
292                     CloseHandle(hf);
293                     return CM_ERROR_TOOMANYBUFS;
294                 } else {
295                     fprintf(stderr,"Error creating file mapping for \"%s\": %d\n",
296                               cachePath, GetLastError());
297                     CloseHandle(hf);
298                     return CM_ERROR_INVAL;
299                 }
300             } else {
301                 fprintf(stderr, "Retry with file size (%lX) succeeds", 
302                          fileInfo.nFileSizeLow);
303             }
304         } else {
305             afsi_log("Error creating file mapping for \"%s\": %d",
306                       cachePath, GetLastError());
307             CloseHandle(hf);
308             return CM_ERROR_INVAL;
309         }
310     }
311
312     config_data_p = MapViewOfFile( hm,
313                                    FILE_MAP_READ,
314                                    0, 0,   
315                                    sizeof(cm_config_data_t));
316     if ( config_data_p == NULL ) {
317         fprintf(stderr, "Unable to MapViewOfFile\n");
318         if (hf != INVALID_HANDLE_VALUE)
319             CloseHandle(hf);
320         CloseHandle(hm);
321         return CM_ERROR_INVAL;
322     }
323
324     if ( config_data_p->dirty ) {
325         fprintf(stderr, "Previous session terminated prematurely\n");
326         UnmapViewOfFile(config_data_p);
327         CloseHandle(hm);               
328         CloseHandle(hf);
329         return CM_ERROR_INVAL;
330     }
331
332     mappingSize = config_data_p->bufferSize;
333     baseAddress = config_data_p->baseAddress;
334     UnmapViewOfFile(config_data_p);
335     CloseHandle(hm);
336
337     hm = CreateFileMapping( hf,
338                             NULL,
339                             PAGE_READWRITE,
340                             0, mappingSize,
341                             NULL);
342     if (hm == NULL) {
343         if (GetLastError() == ERROR_DISK_FULL) {
344             fprintf(stderr, "Error creating file mapping for \"%s\": disk full [2]\n",
345                   cachePath);
346             CloseHandle(hf);
347             return CM_ERROR_TOOMANYBUFS;
348         }
349         fprintf(stderr, "Error creating file mapping for \"%s\": %d\n",
350                 cachePath, GetLastError());
351         CloseHandle(hf);
352         return CM_ERROR_INVAL;
353     }
354     
355     baseAddress = MapViewOfFileEx( hm,
356                                    FILE_MAP_ALL_ACCESS,
357                                    0, 0,   
358                                    mappingSize,
359                                    baseAddress );
360     if (baseAddress == NULL) {
361         fprintf(stderr, "Error mapping view of file: %d\n", GetLastError());
362         baseAddress = MapViewOfFile( hm,
363                                      FILE_MAP_ALL_ACCESS,
364                                      0, 0,   
365                                      mappingSize );
366         if (baseAddress == NULL) {
367             CloseHandle(hm);
368             if (hf != INVALID_HANDLE_VALUE)
369                 CloseHandle(hf);
370             return CM_ERROR_INVAL;
371         }
372         fprintf(stderr, "Unable to re-load cache file at base address\n");
373         CloseHandle(hm);
374         if (hf != INVALID_HANDLE_VALUE)
375             CloseHandle(hf);
376         return CM_ERROR_INVAL;
377     }
378     CloseHandle(hm);
379
380     config_data_p = (cm_config_data_t *) baseAddress;
381
382     fprintf(stderr,"AFS Cache data:\n");
383     fprintf(stderr,"  Base Address   = %lX\n",baseAddress);
384     fprintf(stderr,"  stats          = %d\n", config_data_p->stats);
385     fprintf(stderr,"  chunkSize      = %d\n", config_data_p->chunkSize);
386     fprintf(stderr,"  blockSize      = %d\n", config_data_p->blockSize);
387     fprintf(stderr,"  bufferSize     = %d\n", config_data_p->bufferSize);
388     fprintf(stderr,"  cacheType      = %d\n", config_data_p->cacheType);
389     fprintf(stderr,"  currentVolumes = %d\n", config_data_p->currentVolumes);
390     fprintf(stderr,"  maxVolumes     = %d\n", config_data_p->maxVolumes);
391     fprintf(stderr,"  currentCells   = %d\n", config_data_p->currentCells);
392     fprintf(stderr,"  maxCells       = %d\n", config_data_p->maxCells);
393     fprintf(stderr,"  hashTableSize  = %d\n", config_data_p->hashTableSize );
394     fprintf(stderr,"  currentSCaches = %d\n", config_data_p->currentSCaches);
395     fprintf(stderr,"  maxSCaches     = %d\n", config_data_p->maxSCaches);
396     cm_data = *config_data_p;      
397
398     // perform validation of persisted data structures
399     // if there is a failure, start from scratch
400     if (!cm_IsCacheValid()) {
401         fprintf(stderr,"Cache file fails validation test\n");
402         UnmapViewOfFile(config_data_p);
403         CloseHandle(hm);
404         return CM_ERROR_INVAL;
405     }
406
407     fprintf(stderr,"Cache passes validation test\n");
408     UnmapViewOfFile(config_data_p);
409     CloseHandle(hm);
410     return 0;
411 }
412
413 int
414 cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD chunkSize, DWORD cacheBlocks)
415 {
416     HANDLE hf = INVALID_HANDLE_VALUE, hm;
417     PSECURITY_ATTRIBUTES psa;
418     int newFile = 1;
419     DWORD mappingSize;
420     char * baseAddress = NULL;
421     cm_config_data_t * config_data_p;
422     char * p;
423
424     mappingSize = ComputeSizeOfMappingFile(stats, chunkSize, cacheBlocks, CM_CONFIGDEFAULT_BLOCKSIZE);
425
426     if ( !virtualCache ) {
427         psa = CreateCacheFileSA();
428         hf = CreateFile( cachePath,
429                          GENERIC_READ | GENERIC_WRITE,
430                          FILE_SHARE_READ | FILE_SHARE_WRITE,
431                          psa,
432                          OPEN_ALWAYS,
433                          FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | 
434                          FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_FLAG_RANDOM_ACCESS,
435                          NULL);
436         FreeCacheFileSA(psa);
437
438         if (hf == INVALID_HANDLE_VALUE) {
439             afsi_log("Error creating cache file \"%s\" error %d", 
440                       cachePath, GetLastError());
441             return CM_ERROR_INVAL;
442         }
443         
444         if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
445             BY_HANDLE_FILE_INFORMATION fileInfo;
446
447             /* The file is being re-used; check to see if the existing data can be reused */
448             afsi_log("Cache File \"%s\" already exists", cachePath);
449
450             if ( GetFileInformationByHandle(hf, &fileInfo) ) {
451                 afsi_log("Existing File Size: %08X:%08X",
452                           fileInfo.nFileSizeHigh,
453                           fileInfo.nFileSizeLow);
454                 if (fileInfo.nFileSizeLow > GranularityAdjustment(mappingSize)) {
455                     psa = CreateCacheFileSA();
456                     hf = CreateFile( cachePath,
457                                      GENERIC_READ | GENERIC_WRITE,
458                                      FILE_SHARE_READ | FILE_SHARE_WRITE,
459                                      psa,
460                                      TRUNCATE_EXISTING,
461                                      FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | 
462                                      FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_FLAG_RANDOM_ACCESS,
463                                      NULL);
464                     FreeCacheFileSA(psa);
465
466                     if (hf == INVALID_HANDLE_VALUE) {
467                         afsi_log("Error creating cache file \"%s\" error %d", 
468                                   cachePath, GetLastError());
469                         return CM_ERROR_INVAL;
470                     }
471
472                     GetFileInformationByHandle(hf, &fileInfo);
473                     afsi_log("     New File Size: %08X:%08X",
474                               fileInfo.nFileSizeHigh,
475                               fileInfo.nFileSizeLow);
476                 }
477
478             }
479
480             hm = CreateFileMapping( hf,
481                                     NULL,
482                                     PAGE_READWRITE,
483                                     0, 
484                                     sizeof(cm_config_data_t),
485                                     NULL);
486             if (hm == NULL) {
487                 if (GetLastError() == ERROR_DISK_FULL) {
488                     afsi_log("Error creating file mapping for \"%s\": disk full (%lX)",
489                               cachePath, sizeof(cm_config_data_t));
490
491                     hm = CreateFileMapping( hf,
492                                             NULL,
493                                             PAGE_READWRITE,
494                                             0, 
495                                             mappingSize,
496                                             NULL);
497                     if (hm == NULL) {
498                         if (GetLastError() == ERROR_DISK_FULL) {
499                             CloseHandle(hf);
500                             return CM_ERROR_TOOMANYBUFS;
501                         } else {
502                             afsi_log("Error creating file mapping for \"%s\": %d",
503                                       cachePath, GetLastError());
504                             CloseHandle(hf);
505                             return CM_ERROR_INVAL;
506                         }
507                     } else {
508                         afsi_log("Retry with mapping size (%lX) succeeds", mappingSize);
509                     }
510                 } else {
511                     afsi_log("Error creating file mapping for \"%s\": %d",
512                               cachePath, GetLastError());
513                     CloseHandle(hf);
514                     return CM_ERROR_INVAL;
515                 }
516             }
517
518             config_data_p = MapViewOfFile( hm,
519                                            FILE_MAP_READ,
520                                            0, 0,   
521                                            sizeof(cm_config_data_t));
522             if ( config_data_p == NULL ) {
523                 if (hf != INVALID_HANDLE_VALUE)
524                     CloseHandle(hf);
525                 CloseHandle(hm);
526                 return CM_ERROR_INVAL;
527             }
528
529             if ( config_data_p->size == sizeof(cm_config_data_t) &&
530                  config_data_p->magic == CM_CONFIG_DATA_MAGIC &&
531                  config_data_p->stats == stats &&
532                  config_data_p->chunkSize == chunkSize &&
533                  config_data_p->buf_nbuffers == cacheBlocks &&
534                  config_data_p->blockSize == CM_CONFIGDEFAULT_BLOCKSIZE &&
535                  config_data_p->bufferSize == mappingSize)
536             {
537                 if ( config_data_p->dirty ) {
538                     afsi_log("Previous session terminated prematurely");
539                 } else {
540                     baseAddress = config_data_p->baseAddress;
541                     newFile = 0;
542                 }
543             } else {
544                 afsi_log("Configuration changed or Not a persistent cache file");
545             }
546             UnmapViewOfFile(config_data_p);
547             CloseHandle(hm);
548         }
549     }
550
551     hm = CreateFileMapping( hf,
552                             NULL,
553                             PAGE_READWRITE,
554                             0, mappingSize,
555                             NULL);
556     if (hm == NULL) {
557         if (GetLastError() == ERROR_DISK_FULL) {
558             afsi_log("Error creating file mapping for \"%s\": disk full [2]",
559                       cachePath);
560             return CM_ERROR_TOOMANYBUFS;
561         }
562         afsi_log("Error creating file mapping for \"%s\": %d",
563                   cachePath, GetLastError());
564         return CM_ERROR_INVAL;
565     }
566     baseAddress = MapViewOfFileEx( hm,
567                                    FILE_MAP_ALL_ACCESS,
568                                    0, 0,   
569                                    mappingSize,
570                                    baseAddress );
571     if (baseAddress == NULL) {
572         afsi_log("Error mapping view of file: %d", GetLastError());
573         baseAddress = MapViewOfFile( hm,
574                                      FILE_MAP_ALL_ACCESS,
575                                      0, 0,   
576                                      mappingSize );
577         if (baseAddress == NULL) {
578             if (hf != INVALID_HANDLE_VALUE)
579                 CloseHandle(hf);
580             CloseHandle(hm);
581             return CM_ERROR_INVAL;
582         }
583         newFile = 1;
584     }
585     CloseHandle(hm);
586
587     config_data_p = (cm_config_data_t *) baseAddress;
588
589     if (!newFile) {
590         afsi_log("Reusing existing AFS Cache data: Base Address = %lX",baseAddress);
591         cm_data = *config_data_p;      
592
593         // perform validation of persisted data structures
594         // if there is a failure, start from scratch
595         if (cm_ValidateCache && !cm_IsCacheValid()) {
596             newFile = 1;
597         }
598     }
599
600     if ( newFile ) {
601         afsi_log("Building AFS Cache from scratch");
602         cm_data.size = sizeof(cm_config_data_t);
603         cm_data.magic = CM_CONFIG_DATA_MAGIC;
604         cm_data.baseAddress = baseAddress;
605         cm_data.stats = stats;
606         cm_data.chunkSize = chunkSize;
607         cm_data.blockSize = CM_CONFIGDEFAULT_BLOCKSIZE;
608         cm_data.bufferSize = mappingSize;
609         cm_data.hashTableSize = osi_PrimeLessThan(stats / 2 + 1);
610         if (virtualCache) {
611             cm_data.cacheType = CM_BUF_CACHETYPE_VIRTUAL;
612         } else {
613             cm_data.cacheType = CM_BUF_CACHETYPE_FILE;
614         }
615
616         cm_data.buf_nbuffers = cacheBlocks;
617         cm_data.buf_nOrigBuffers = 0;
618         cm_data.buf_blockSize = CM_BUF_BLOCKSIZE;
619         cm_data.buf_hashSize = CM_BUF_HASHSIZE;
620
621         cm_data.mountRootGen = time(NULL);
622
623         baseAddress += ComputeSizeOfConfigData();
624         cm_data.volumeBaseAddress = (cm_volume_t *) baseAddress;
625         baseAddress += ComputeSizeOfVolumes(stats/2);
626         cm_data.cellBaseAddress = (cm_cell_t *) baseAddress;
627         baseAddress += ComputeSizeOfCells(stats/4);
628         cm_data.aclBaseAddress = (cm_aclent_t *) baseAddress;
629         baseAddress += ComputeSizeOfACLCache(stats);
630         cm_data.scacheBaseAddress = (cm_scache_t *) baseAddress;
631         baseAddress += ComputeSizeOfSCache(stats);
632         cm_data.hashTablep = (cm_scache_t **) baseAddress;
633         baseAddress += ComputeSizeOfSCacheHT(stats);
634         cm_data.dnlcBaseAddress = (cm_nc_t *) baseAddress;
635         baseAddress += ComputeSizeOfDNLCache();
636         cm_data.buf_hashTablepp = (cm_buf_t **) baseAddress;
637         baseAddress += ComputeSizeOfDataHT();
638         cm_data.buf_fileHashTablepp = (cm_buf_t **) baseAddress;
639         baseAddress += ComputeSizeOfDataHT();
640         cm_data.bufHeaderBaseAddress = (cm_buf_t *) baseAddress;
641         baseAddress += ComputeSizeOfDataHeaders(cacheBlocks);
642         cm_data.bufDataBaseAddress = (char *) baseAddress;
643         baseAddress += ComputeSizeOfDataBuffers(cacheBlocks, CM_CONFIGDEFAULT_BLOCKSIZE);
644         cm_data.bufEndOfData = (char *) baseAddress;
645
646         cm_data.fakeDirVersion = 0x8;
647
648         UuidCreate((UUID *)&cm_data.Uuid);
649     }
650
651     UuidToString((UUID *)&cm_data.Uuid, &p);
652     afsi_log("Initializing Uuid to %s",p);
653     RpcStringFree(&p);
654
655     afsi_log("Initializing Volume Data");
656     cm_InitVolume(newFile, stats/2);
657
658     afsi_log("Initializing Cell Data");
659     cm_InitCell(newFile, stats/4);
660
661     afsi_log("Initializing ACL Data");
662     cm_InitACLCache(newFile, 2*stats);
663
664     afsi_log("Initializing Stat Data");
665     cm_InitSCache(newFile, stats);
666         
667     afsi_log("Initializing Data Buffers");
668     cm_InitDCache(newFile, 0, cacheBlocks);
669
670     *config_data_p = cm_data;
671     config_data_p->dirty = 1;
672     
673     hMemoryMappedFile = hf;
674     afsi_log("Cache Initialization Complete");
675     return 0;
676 }
677