Page principale | Liste des namespaces | Hiérarchie des classes | Liste des classes | Répertoires | Liste des fichiers | Membres de namespace | Membres de classe | Membres de fichier

filesys.cc

Aller à la documentation de ce fichier.
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 #ifndef FILESYS_STUB
00046 
00047 #include "copyright.h"
00048 #include "debug.h"
00049 #include "disk.h"
00050 #include "pbitmap.h"
00051 #include "directory.h"
00052 #include "filehdr.h"
00053 #include "filesys.h"
00054 
00055 // Sectors containing the file headers for the bitmap of free sectors,
00056 // and the directory of files.  These file headers are placed in well-known 
00057 // sectors, so that they can be located on boot-up.
00058 #define FreeMapSector           0
00059 #define DirectorySector         1
00060 
00061 // Initial file sizes for the bitmap and directory; until the file system
00062 // supports extensible files, the directory size sets the maximum number 
00063 // of files that can be loaded onto the disk.
00064 #define FreeMapFileSize         (NumSectors / BitsInByte)
00065 #define NumDirEntries           10
00066 #define DirectoryFileSize       (sizeof(DirectoryEntry) * NumDirEntries)
00067 
00068 //----------------------------------------------------------------------
00069 // FileSystem::FileSystem
00070 //      Initialize the file system.  If format = TRUE, the disk has
00071 //      nothing on it, and we need to initialize the disk to contain
00072 //      an empty directory, and a bitmap of free sectors (with almost but
00073 //      not all of the sectors marked as free).  
00074 //
00075 //      If format = FALSE, we just have to open the files
00076 //      representing the bitmap and the directory.
00077 //
00078 //      "format" -- should we initialize the disk?
00079 //----------------------------------------------------------------------
00080 
00081 FileSystem::FileSystem(bool format)
00082 { 
00083     DEBUG(dbgFile, "Initializing the file system.");
00084     if (format) {
00085         PersistentBitmap *freeMap = new PersistentBitmap(NumSectors);
00086         Directory *directory = new Directory(NumDirEntries);
00087         FileHeader *mapHdr = new FileHeader;
00088         FileHeader *dirHdr = new FileHeader;
00089 
00090         DEBUG(dbgFile, "Formatting the file system.");
00091 
00092     // First, allocate space for FileHeaders for the directory and bitmap
00093     // (make sure no one else grabs these!)
00094         freeMap->Mark(FreeMapSector);       
00095         freeMap->Mark(DirectorySector);
00096 
00097     // Second, allocate space for the data blocks containing the contents
00098     // of the directory and bitmap files.  There better be enough space!
00099 
00100         ASSERT(mapHdr->Allocate(freeMap, FreeMapFileSize));
00101         ASSERT(dirHdr->Allocate(freeMap, DirectoryFileSize));
00102 
00103     // Flush the bitmap and directory FileHeaders back to disk
00104     // We need to do this before we can "Open" the file, since open
00105     // reads the file header off of disk (and currently the disk has garbage
00106     // on it!).
00107 
00108         DEBUG(dbgFile, "Writing headers back to disk.");
00109         mapHdr->WriteBack(FreeMapSector);    
00110         dirHdr->WriteBack(DirectorySector);
00111 
00112     // OK to open the bitmap and directory files now
00113     // The file system operations assume these two files are left open
00114     // while Nachos is running.
00115 
00116         freeMapFile = new OpenFile(FreeMapSector);
00117         directoryFile = new OpenFile(DirectorySector);
00118      
00119     // Once we have the files "open", we can write the initial version
00120     // of each file back to disk.  The directory at this point is completely
00121     // empty; but the bitmap has been changed to reflect the fact that
00122     // sectors on the disk have been allocated for the file headers and
00123     // to hold the file data for the directory and bitmap.
00124 
00125         DEBUG(dbgFile, "Writing bitmap and directory back to disk.");
00126         freeMap->WriteBack(freeMapFile);         // flush changes to disk
00127         directory->WriteBack(directoryFile);
00128 
00129         if (debug->IsEnabled('f')) {
00130             freeMap->Print();
00131             directory->Print();
00132         }
00133         delete freeMap; 
00134         delete directory; 
00135         delete mapHdr; 
00136         delete dirHdr;
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     PersistentBitmap *freeMap;
00179     FileHeader *hdr;
00180     int sector;
00181     bool success;
00182 
00183     DEBUG(dbgFile, "Creating file " << name << " size " << 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 PersistentBitmap(freeMapFile,NumSectors);
00192         sector = freeMap->FindAndSet(); // find a sector to hold the file header
00193         if (sector == -1)               
00194             success = FALSE;            // no free block for file header 
00195         else if (!directory->Add(name, sector))
00196             success = FALSE;    // no space in directory
00197         else {
00198             hdr = new FileHeader;
00199             if (!hdr->Allocate(freeMap, initialSize))
00200                 success = FALSE;        // no space on disk for data
00201             else {      
00202                 success = TRUE;
00203                 // everthing worked, flush all changes back to disk
00204                 hdr->WriteBack(sector);                 
00205                 directory->WriteBack(directoryFile);
00206                 freeMap->WriteBack(freeMapFile);
00207             }
00208             delete hdr;
00209         }
00210         delete freeMap;
00211     }
00212     delete directory;
00213     return success;
00214 }
00215 
00216 //----------------------------------------------------------------------
00217 // FileSystem::Open
00218 //      Open a file for reading and writing.  
00219 //      To open a file:
00220 //        Find the location of the file's header, using the directory 
00221 //        Bring the header into memory
00222 //
00223 //      "name" -- the text name of the file to be opened
00224 //----------------------------------------------------------------------
00225 
00226 OpenFile *
00227 FileSystem::Open(char *name)
00228 { 
00229     Directory *directory = new Directory(NumDirEntries);
00230     OpenFile *openFile = NULL;
00231     int sector;
00232 
00233     DEBUG(dbgFile, "Opening file" << name);
00234     directory->FetchFrom(directoryFile);
00235     sector = directory->Find(name); 
00236     if (sector >= 0)            
00237         openFile = new OpenFile(sector);        // name was found in directory 
00238     delete directory;
00239     return openFile;                            // return NULL if not found
00240 }
00241 
00242 //----------------------------------------------------------------------
00243 // FileSystem::Remove
00244 //      Delete a file from the file system.  This requires:
00245 //          Remove it from the directory
00246 //          Delete the space for its header
00247 //          Delete the space for its data blocks
00248 //          Write changes to directory, bitmap back to disk
00249 //
00250 //      Return TRUE if the file was deleted, FALSE if the file wasn't
00251 //      in the file system.
00252 //
00253 //      "name" -- the text name of the file to be removed
00254 //----------------------------------------------------------------------
00255 
00256 bool
00257 FileSystem::Remove(char *name)
00258 { 
00259     Directory *directory;
00260     PersistentBitmap *freeMap;
00261     FileHeader *fileHdr;
00262     int sector;
00263     
00264     directory = new Directory(NumDirEntries);
00265     directory->FetchFrom(directoryFile);
00266     sector = directory->Find(name);
00267     if (sector == -1) {
00268        delete directory;
00269        return FALSE;                     // file not found 
00270     }
00271     fileHdr = new FileHeader;
00272     fileHdr->FetchFrom(sector);
00273 
00274     freeMap = new PersistentBitmap(freeMapFile,NumSectors);
00275 
00276     fileHdr->Deallocate(freeMap);               // remove data blocks
00277     freeMap->Clear(sector);                     // remove header block
00278     directory->Remove(name);
00279 
00280     freeMap->WriteBack(freeMapFile);            // flush to disk
00281     directory->WriteBack(directoryFile);        // flush to disk
00282     delete fileHdr;
00283     delete directory;
00284     delete freeMap;
00285     return TRUE;
00286 } 
00287 
00288 //----------------------------------------------------------------------
00289 // FileSystem::List
00290 //      List all the files in the file system directory.
00291 //----------------------------------------------------------------------
00292 
00293 void
00294 FileSystem::List()
00295 {
00296     Directory *directory = new Directory(NumDirEntries);
00297 
00298     directory->FetchFrom(directoryFile);
00299     directory->List();
00300     delete directory;
00301 }
00302 
00303 //----------------------------------------------------------------------
00304 // FileSystem::Print
00305 //      Print everything about the file system:
00306 //        the contents of the bitmap
00307 //        the contents of the directory
00308 //        for each file in the directory,
00309 //            the contents of the file header
00310 //            the data in the file
00311 //----------------------------------------------------------------------
00312 
00313 void
00314 FileSystem::Print()
00315 {
00316     FileHeader *bitHdr = new FileHeader;
00317     FileHeader *dirHdr = new FileHeader;
00318     PersistentBitmap *freeMap = new PersistentBitmap(freeMapFile,NumSectors);
00319     Directory *directory = new Directory(NumDirEntries);
00320 
00321     printf("Bit map file header:\n");
00322     bitHdr->FetchFrom(FreeMapSector);
00323     bitHdr->Print();
00324 
00325     printf("Directory file header:\n");
00326     dirHdr->FetchFrom(DirectorySector);
00327     dirHdr->Print();
00328 
00329     freeMap->Print();
00330 
00331     directory->FetchFrom(directoryFile);
00332     directory->Print();
00333 
00334     delete bitHdr;
00335     delete dirHdr;
00336     delete freeMap;
00337     delete directory;
00338 } 
00339 
00340 #endif // FILESYS_STUB

Généré le Sun Jan 15 00:45:45 2006 pour Système NachOS : par  doxygen 1.4.4