00001 // filehdr.cc 00002 // Routines for managing the disk file header (in UNIX, this 00003 // would be called the i-node). 00004 // 00005 // The file header is used to locate where on disk the 00006 // file's data is stored. We implement this as a fixed size 00007 // table of pointers -- each entry in the table points to the 00008 // disk sector containing that portion of the file data 00009 // (in other words, there are no indirect or doubly indirect 00010 // blocks). The table size is chosen so that the file header 00011 // will be just big enough to fit in one disk sector, 00012 // 00013 // Unlike in a real system, we do not keep track of file permissions, 00014 // ownership, last modification date, etc., in the file header. 00015 // 00016 // A file header can be initialized in two ways: 00017 // for a new file, by modifying the in-memory data structure 00018 // to point to the newly allocated data blocks 00019 // for a file already on disk, by reading the file header from disk 00020 // 00021 // Copyright (c) 1992-1993 The Regents of the University of California. 00022 // All rights reserved. See copyright.h for copyright notice and limitation 00023 // of liability and disclaimer of warranty provisions. 00024 00025 #include "copyright.h" 00026 00027 #include "system.h" 00028 #include "filehdr.h" 00029 00030 //---------------------------------------------------------------------- 00031 // FileHeader::Allocate 00032 // Initialize a fresh file header for a newly created file. 00033 // Allocate data blocks for the file out of the map of free disk blocks. 00034 // Return FALSE if there are not enough free blocks to accomodate 00035 // the new file. 00036 // 00037 // "freeMap" is the bit map of free disk sectors 00038 // "fileSize" is the bit map of free disk sectors 00039 //---------------------------------------------------------------------- 00040 00041 bool 00042 FileHeader::Allocate(BitMap *freeMap, int fileSize) 00043 { 00044 numBytes = fileSize; 00045 numSectors = divRoundUp(fileSize, SectorSize); 00046 if (freeMap->NumClear() < numSectors) 00047 return FALSE; // not enough space 00048 00049 for (int i = 0; i < numSectors; i++) 00050 dataSectors[i] = freeMap->Find(); 00051 return TRUE; 00052 } 00053 00054 //---------------------------------------------------------------------- 00055 // FileHeader::Deallocate 00056 // De-allocate all the space allocated for data blocks for this file. 00057 // 00058 // "freeMap" is the bit map of free disk sectors 00059 //---------------------------------------------------------------------- 00060 00061 void 00062 FileHeader::Deallocate(BitMap *freeMap) 00063 { 00064 for (int i = 0; i < numSectors; i++) { 00065 ASSERT(freeMap->Test((int) dataSectors[i])); // ought to be marked! 00066 freeMap->Clear((int) dataSectors[i]); 00067 } 00068 } 00069 00070 //---------------------------------------------------------------------- 00071 // FileHeader::FetchFrom 00072 // Fetch contents of file header from disk. 00073 // 00074 // "sector" is the disk sector containing the file header 00075 //---------------------------------------------------------------------- 00076 00077 void 00078 FileHeader::FetchFrom(int sector) 00079 { 00080 synchDisk->ReadSector(sector, (char *)this); 00081 } 00082 00083 //---------------------------------------------------------------------- 00084 // FileHeader::WriteBack 00085 // Write the modified contents of the file header back to disk. 00086 // 00087 // "sector" is the disk sector to contain the file header 00088 //---------------------------------------------------------------------- 00089 00090 void 00091 FileHeader::WriteBack(int sector) 00092 { 00093 synchDisk->WriteSector(sector, (char *)this); 00094 } 00095 00096 //---------------------------------------------------------------------- 00097 // FileHeader::ByteToSector 00098 // Return which disk sector is storing a particular byte within the file. 00099 // This is essentially a translation from a virtual address (the 00100 // offset in the file) to a physical address (the sector where the 00101 // data at the offset is stored). 00102 // 00103 // "offset" is the location within the file of the byte in question 00104 //---------------------------------------------------------------------- 00105 00106 int 00107 FileHeader::ByteToSector(int offset) 00108 { 00109 return(dataSectors[offset / SectorSize]); 00110 } 00111 00112 //---------------------------------------------------------------------- 00113 // FileHeader::FileLength 00114 // Return the number of bytes in the file. 00115 //---------------------------------------------------------------------- 00116 00117 int 00118 FileHeader::FileLength() 00119 { 00120 return numBytes; 00121 } 00122 00123 //---------------------------------------------------------------------- 00124 // FileHeader::Print 00125 // Print the contents of the file header, and the contents of all 00126 // the data blocks pointed to by the file header. 00127 //---------------------------------------------------------------------- 00128 00129 void 00130 FileHeader::Print() 00131 { 00132 int i, j, k; 00133 char *data = new char[SectorSize]; 00134 00135 printf("FileHeader contents. File size: %d. File blocks:\n", numBytes); 00136 for (i = 0; i < numSectors; i++) 00137 printf("%d ", dataSectors[i]); 00138 printf("\nFile contents:\n"); 00139 for (i = k = 0; i < numSectors; i++) { 00140 synchDisk->ReadSector(dataSectors[i], data); 00141 for (j = 0; (j < SectorSize) && (k < numBytes); j++, k++) { 00142 if ('\040' <= data[j] && data[j] <= '\176') // isprint(data[j]) 00143 printf("%c", data[j]); 00144 else 00145 printf("\\%x", (unsigned char)data[j]); 00146 } 00147 printf("\n"); 00148 } 00149 delete [] data; 00150 }
1.2.14 written by Dimitri van Heesch,
© 1997-2002