Main Page   Compound List   File List   Compound Members   File Members  

filesys.cc

Go to the documentation of this file.
00001 // filesys.cc 
00002 //      Routines to manage the overall operation of the file system.
00003 //      Implements routines to map from textual file names to files.
00004 //
00005 //      Each file in the file system has:
00006 //         A file header, stored in a sector on disk 
00007 //              (the size of the file header data structure is arranged
00008 //              to be precisely the size of 1 disk sector)
00009 //         A number of data blocks
00010 //         An entry in the file system directory
00011 //
00012 //      The file system consists of several data structures:
00013 //         A bitmap of free disk sectors (cf. bitmap.h)
00014 //         A directory of file names and file headers
00015 //
00016 //      Both the bitmap and the directory are represented as normal
00017 //      files.  Their file headers are located in specific sectors
00018 //      (sector 0 and sector 1), so that the file system can find them 
00019 //      on bootup.
00020 //
00021 //      The file system assumes that the bitmap and directory files are
00022 //      kept "open" continuously while Nachos is running.
00023 //
00024 //      For those operations (such as Create, Remove) that modify the
00025 //      directory and/or bitmap, if the operation succeeds, the changes
00026 //      are written immediately back to disk (the two files are kept
00027 //      open during all this time).  If the operation fails, and we have
00028 //      modified part of the directory and/or bitmap, we simply discard
00029 //      the changed version, without writing it back to disk.
00030 //
00031 //      Our implementation at this point has the following restrictions:
00032 //
00033 //         there is no synchronization for concurrent accesses
00034 //         files have a fixed size, set when the file is created
00035 //         files cannot be bigger than about 3KB in size
00036 //         there is no hierarchical directory structure, and only a limited
00037 //           number of files can be added to the system
00038 //         there is no attempt to make the system robust to failures
00039 //          (if Nachos exits in the middle of an operation that modifies
00040 //          the file system, it may corrupt the disk)
00041 //
00042 // Copyright (c) 1992-1993 The Regents of the University of California.
00043 // All rights reserved.  See copyright.h for copyright notice and limitation 
00044 // of liability and disclaimer of warranty provisions.
00045 
00046 #include "copyright.h"
00047 
00048 #include "disk.h"
00049 #include "bitmap.h"
00050 #include "directory.h"
00051 #include "filehdr.h"
00052 #include "filesys.h"
00053 
00054 // Sectors containing the file headers for the bitmap of free sectors,
00055 // and the directory of files.  These file headers are placed in well-known 
00056 // sectors, so that they can be located on boot-up.
00057 #define FreeMapSector           0
00058 #define DirectorySector         1
00059 
00060 // Initial file sizes for the bitmap and directory; until the file system
00061 // supports extensible files, the directory size sets the maximum number 
00062 // of files that can be loaded onto the disk.
00063 #define FreeMapFileSize         (NumSectors / BitsInByte)
00064 #define NumDirEntries           10
00065 #define DirectoryFileSize       (sizeof(DirectoryEntry) * NumDirEntries)
00066 
00067 //----------------------------------------------------------------------
00068 // FileSystem::FileSystem
00069 //      Initialize the file system.  If format = TRUE, the disk has
00070 //      nothing on it, and we need to initialize the disk to contain
00071 //      an empty directory, and a bitmap of free sectors (with almost but
00072 //      not all of the sectors marked as free).  
00073 //
00074 //      If format = FALSE, we just have to open the files
00075 //      representing the bitmap and the directory.
00076 //
00077 //      "format" -- should we initialize the disk?
00078 //----------------------------------------------------------------------
00079 
00080 FileSystem::FileSystem(bool format)
00081 { 
00082     DEBUG('f', "Initializing the file system.\n");
00083     if (format) {
00084         BitMap *freeMap = new BitMap(NumSectors);
00085         Directory *directory = new Directory(NumDirEntries);
00086         FileHeader *mapHdr = new FileHeader;
00087         FileHeader *dirHdr = new FileHeader;
00088 
00089         DEBUG('f', "Formatting the file system.\n");
00090 
00091     // First, allocate space for FileHeaders for the directory and bitmap
00092     // (make sure no one else grabs these!)
00093         freeMap->Mark(FreeMapSector);       
00094         freeMap->Mark(DirectorySector);
00095 
00096     // Second, allocate space for the data blocks containing the contents
00097     // of the directory and bitmap files.  There better be enough space!
00098 
00099         ASSERT(mapHdr->Allocate(freeMap, FreeMapFileSize));
00100         ASSERT(dirHdr->Allocate(freeMap, DirectoryFileSize));
00101 
00102     // Flush the bitmap and directory FileHeaders back to disk
00103     // We need to do this before we can "Open" the file, since open
00104     // reads the file header off of disk (and currently the disk has garbage
00105     // on it!).
00106 
00107         DEBUG('f', "Writing headers back to disk.\n");
00108         mapHdr->WriteBack(FreeMapSector);    
00109         dirHdr->WriteBack(DirectorySector);
00110 
00111     // OK to open the bitmap and directory files now
00112     // The file system operations assume these two files are left open
00113     // while Nachos is running.
00114 
00115         freeMapFile = new OpenFile(FreeMapSector);
00116         directoryFile = new OpenFile(DirectorySector);
00117      
00118     // Once we have the files "open", we can write the initial version
00119     // of each file back to disk.  The directory at this point is completely
00120     // empty; but the bitmap has been changed to reflect the fact that
00121     // sectors on the disk have been allocated for the file headers and
00122     // to hold the file data for the directory and bitmap.
00123 
00124         DEBUG('f', "Writing bitmap and directory back to disk.\n");
00125         freeMap->WriteBack(freeMapFile);         // flush changes to disk
00126         directory->WriteBack(directoryFile);
00127 
00128         if (DebugIsEnabled('f')) {
00129             freeMap->Print();
00130             directory->Print();
00131 
00132         delete freeMap; 
00133         delete directory; 
00134         delete mapHdr; 
00135         delete dirHdr;
00136         }
00137     } else {
00138     // if we are not formatting the disk, just open the files representing
00139     // the bitmap and directory; these are left open while Nachos is running
00140         freeMapFile = new OpenFile(FreeMapSector);
00141         directoryFile = new OpenFile(DirectorySector);
00142     }
00143 }
00144 
00145 //----------------------------------------------------------------------
00146 // FileSystem::Create
00147 //      Create a file in the Nachos file system (similar to UNIX create).
00148 //      Since we can't increase the size of files dynamically, we have
00149 //      to give Create the initial size of the file.
00150 //
00151 //      The steps to create a file are:
00152 //        Make sure the file doesn't already exist
00153 //        Allocate a sector for the file header
00154 //        Allocate space on disk for the data blocks for the file
00155 //        Add the name to the directory
00156 //        Store the new file header on disk 
00157 //        Flush the changes to the bitmap and the directory back to disk
00158 //
00159 //      Return TRUE if everything goes ok, otherwise, return FALSE.
00160 //
00161 //      Create fails if:
00162 //              file is already in directory
00163 //              no free space for file header
00164 //              no free entry for file in directory
00165 //              no free space for data blocks for the file 
00166 //
00167 //      Note that this implementation assumes there is no concurrent access
00168 //      to the file system!
00169 //
00170 //      "name" -- name of file to be created
00171 //      "initialSize" -- size of file to be created
00172 //----------------------------------------------------------------------
00173 
00174 bool
00175 FileSystem::Create(char *name, int initialSize)
00176 {
00177     Directory *directory;
00178     BitMap *freeMap;
00179     FileHeader *hdr;
00180     int sector;
00181     bool success;
00182 
00183     DEBUG('f', "Creating file %s, size %d\n", name, initialSize);
00184 
00185     directory = new Directory(NumDirEntries);
00186     directory->FetchFrom(directoryFile);
00187 
00188     if (directory->Find(name) != -1)
00189       success = FALSE;                  // file is already in directory
00190     else {      
00191         freeMap = new BitMap(NumSectors);
00192         freeMap->FetchFrom(freeMapFile);
00193         sector = freeMap->Find();       // find a sector to hold the file header
00194         if (sector == -1)               
00195             success = FALSE;            // no free block for file header 
00196         else if (!directory->Add(name, sector))
00197             success = FALSE;    // no space in directory
00198         else {
00199             hdr = new FileHeader;
00200             if (!hdr->Allocate(freeMap, initialSize))
00201                 success = FALSE;        // no space on disk for data
00202             else {      
00203                 success = TRUE;
00204                 // everthing worked, flush all changes back to disk
00205                 hdr->WriteBack(sector);                 
00206                 directory->WriteBack(directoryFile);
00207                 freeMap->WriteBack(freeMapFile);
00208             }
00209             delete hdr;
00210         }
00211         delete freeMap;
00212     }
00213     delete directory;
00214     return success;
00215 }
00216 
00217 //----------------------------------------------------------------------
00218 // FileSystem::Open
00219 //      Open a file for reading and writing.  
00220 //      To open a file:
00221 //        Find the location of the file's header, using the directory 
00222 //        Bring the header into memory
00223 //
00224 //      "name" -- the text name of the file to be opened
00225 //----------------------------------------------------------------------
00226 
00227 OpenFile *
00228 FileSystem::Open(char *name)
00229 { 
00230     Directory *directory = new Directory(NumDirEntries);
00231     OpenFile *openFile = NULL;
00232     int sector;
00233 
00234     DEBUG('f', "Opening file %s\n", name);
00235     directory->FetchFrom(directoryFile);
00236     sector = directory->Find(name); 
00237     if (sector >= 0)            
00238         openFile = new OpenFile(sector);        // name was found in directory 
00239     delete directory;
00240     return openFile;                            // return NULL if not found
00241 }
00242 
00243 //----------------------------------------------------------------------
00244 // FileSystem::Remove
00245 //      Delete a file from the file system.  This requires:
00246 //          Remove it from the directory
00247 //          Delete the space for its header
00248 //          Delete the space for its data blocks
00249 //          Write changes to directory, bitmap back to disk
00250 //
00251 //      Return TRUE if the file was deleted, FALSE if the file wasn't
00252 //      in the file system.
00253 //
00254 //      "name" -- the text name of the file to be removed
00255 //----------------------------------------------------------------------
00256 
00257 bool
00258 FileSystem::Remove(char *name)
00259 { 
00260     Directory *directory;
00261     BitMap *freeMap;
00262     FileHeader *fileHdr;
00263     int sector;
00264     
00265     directory = new Directory(NumDirEntries);
00266     directory->FetchFrom(directoryFile);
00267     sector = directory->Find(name);
00268     if (sector == -1) {
00269        delete directory;
00270        return FALSE;                     // file not found 
00271     }
00272     fileHdr = new FileHeader;
00273     fileHdr->FetchFrom(sector);
00274 
00275     freeMap = new BitMap(NumSectors);
00276     freeMap->FetchFrom(freeMapFile);
00277 
00278     fileHdr->Deallocate(freeMap);               // remove data blocks
00279     freeMap->Clear(sector);                     // remove header block
00280     directory->Remove(name);
00281 
00282     freeMap->WriteBack(freeMapFile);            // flush to disk
00283     directory->WriteBack(directoryFile);        // flush to disk
00284     delete fileHdr;
00285     delete directory;
00286     delete freeMap;
00287     return TRUE;
00288 } 
00289 
00290 //----------------------------------------------------------------------
00291 // FileSystem::List
00292 //      List all the files in the file system directory.
00293 //----------------------------------------------------------------------
00294 
00295 void
00296 FileSystem::List()
00297 {
00298     Directory *directory = new Directory(NumDirEntries);
00299 
00300     directory->FetchFrom(directoryFile);
00301     directory->List();
00302     delete directory;
00303 }
00304 
00305 //----------------------------------------------------------------------
00306 // FileSystem::Print
00307 //      Print everything about the file system:
00308 //        the contents of the bitmap
00309 //        the contents of the directory
00310 //        for each file in the directory,
00311 //            the contents of the file header
00312 //            the data in the file
00313 //----------------------------------------------------------------------
00314 
00315 void
00316 FileSystem::Print()
00317 {
00318     FileHeader *bitHdr = new FileHeader;
00319     FileHeader *dirHdr = new FileHeader;
00320     BitMap *freeMap = new BitMap(NumSectors);
00321     Directory *directory = new Directory(NumDirEntries);
00322 
00323     printf("Bit map file header:\n");
00324     bitHdr->FetchFrom(FreeMapSector);
00325     bitHdr->Print();
00326 
00327     printf("Directory file header:\n");
00328     dirHdr->FetchFrom(DirectorySector);
00329     dirHdr->Print();
00330 
00331     freeMap->FetchFrom(freeMapFile);
00332     freeMap->Print();
00333 
00334     directory->FetchFrom(directoryFile);
00335     directory->Print();
00336 
00337     delete bitHdr;
00338     delete dirHdr;
00339     delete freeMap;
00340     delete directory;
00341 } 

Generated on Mon Feb 10 09:54:45 2003 for nachos by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002
The University of Southern California does not screen or control the content on this website and thus does not guarantee the accuracy, integrity, or quality of such content. All content on this website is provided by and is the sole responsibility of the person from which such content originated, and such content does not necessarily reflect the opinions of the University administration or the Board of Trustees