de_diskio.c

Go to the documentation of this file.
00001 /****************************************************************/
00002 /*                                                              */
00003 /*      de_diskio.c                                             */
00004 /*                                                              */
00005 /*              Reading and writing to a file system device.    */
00006 /*                                                              */
00007 /****************************************************************/
00008 /*  origination         1989-Jan-15        Terrence W. Holm     */
00009 /****************************************************************/
00010 
00011 
00012 #include <minix/config.h>
00013 #include <sys/types.h>
00014 #include <unistd.h>
00015 #include <limits.h>
00016 #include <string.h>
00017 #include <dirent.h>
00018 
00019 #include <minix/const.h>
00020 #include <minix/type.h>
00021 #include "../../servers/fs/const.h"
00022 #include "../../servers/fs/type.h"
00023 #include "../../servers/fs/super.h"
00024 #include "../../servers/fs/inode.h"
00025 #include <minix/fslib.h>
00026 
00027 #include "de.h"
00028 
00029 
00030 
00031 
00032 /****************************************************************/
00033 /*                                                              */
00034 /*      Read_Disk( state, block_addr, buffer )                  */
00035 /*                                                              */
00036 /*              Reads a 1k block at "block_addr" into "buffer". */
00037 /*                                                              */
00038 /****************************************************************/
00039 
00040 
00041 void Read_Disk( s, block_addr, buffer )
00042   de_state *s;
00043   off_t  block_addr;
00044   char  *buffer;
00045 
00046   {
00047   if ( lseek( s->device_d, block_addr, SEEK_SET ) == -1 )
00048     Error( "Error seeking %s", s->device_name );
00049 
00050   if ( read( s->device_d, buffer, s->block_size ) != s->block_size )
00051     Error( "Error reading %s", s->device_name );
00052   }
00053 
00054 
00055 
00056 
00057 
00058 
00059 /****************************************************************/
00060 /*                                                              */
00061 /*      Read_Block( state, buffer )                             */
00062 /*                                                              */
00063 /*              Reads a 1k block from "state->address" into     */
00064 /*              "buffer". Checks "address", and updates         */
00065 /*              "block" and "offset".                           */
00066 /*                                                              */
00067 /****************************************************************/
00068 
00069 
00070 void Read_Block( s, buffer )
00071   de_state *s;
00072   char *buffer;
00073 
00074   {
00075   off_t end_addr;
00076   off_t block_addr;
00077   end_addr = (long) s->device_size * s->block_size - 1;
00078 
00079   if ( s->address < 0 )
00080     s->address = 0L;
00081 
00082   if ( s->address > end_addr )
00083     s->address = end_addr;
00084 
00085   /*  The address must be rounded off for  */
00086   /*  certain visual display modes.        */
00087 
00088   if ( s->mode == WORD )
00089     s->address &= ~1L;
00090   else if ( s->mode == MAP )
00091     s->address &= ~3L;
00092 
00093 
00094   block_addr = s->address & K_MASK;
00095 
00096   s->block  = (zone_t) (block_addr >> K_SHIFT);
00097   s->offset = (unsigned) (s->address - block_addr);
00098 
00099   Read_Disk( s, block_addr, buffer );
00100   }
00101 
00102 
00103 
00104 
00105 
00106 
00107 /****************************************************************/
00108 /*                                                              */
00109 /*      Read_Super_Block( state )                               */
00110 /*                                                              */
00111 /*              Read and check the super block.                 */
00112 /*                                                              */
00113 /****************************************************************/
00114 
00115 
00116 void Read_Super_Block( s )
00117   de_state *s;
00118 
00119   {
00120   struct super_block *super = (struct super_block *) s->buffer;
00121   unsigned inodes_per_block;
00122   off_t size;
00123 
00124   s->block_size = K;
00125   Read_Disk( s, (long) SUPER_BLOCK_BYTES, s->buffer );
00126 
00127   s->magic = super->s_magic;
00128   if ( s->magic == SUPER_MAGIC )
00129     {
00130     s->is_fs = TRUE;
00131     s->v1 = TRUE;
00132     s->inode_size = V1_INODE_SIZE;
00133     inodes_per_block = V1_INODES_PER_BLOCK;
00134     s->nr_indirects = V1_INDIRECTS;
00135     s->zone_num_size = V1_ZONE_NUM_SIZE;
00136     s->zones = super->s_nzones;
00137     s->ndzones = V1_NR_DZONES;
00138     s->block_size = _STATIC_BLOCK_SIZE;
00139     }
00140   else if ( s->magic == SUPER_V2 || s->magic == SUPER_V3)
00141     {
00142     if(s->magic == SUPER_V3)
00143         s->block_size = super->s_block_size;
00144     else
00145         s->block_size = _STATIC_BLOCK_SIZE;
00146     s->is_fs = TRUE;
00147     s->v1 = FALSE;
00148     s->inode_size = V2_INODE_SIZE;
00149     inodes_per_block = V2_INODES_PER_BLOCK(s->block_size);
00150     s->nr_indirects = V2_INDIRECTS(s->block_size);
00151     s->zone_num_size = V2_ZONE_NUM_SIZE;
00152     s->zones = super->s_zones;
00153     s->ndzones = V2_NR_DZONES;
00154     }
00155   else  
00156     {
00157     if ( super->s_magic == SUPER_REV )
00158       Warning( "V1-bytes-swapped file system (?)" );
00159     else if ( super->s_magic == SUPER_V2_REV )
00160       Warning( "V2-bytes-swapped file system (?)" );
00161     else  
00162       Warning( "Not a Minix file system" );
00163     Warning( "The file system features will not be available" );  
00164     s->zones = 100000L;
00165     return;
00166     }
00167 
00168   s->inodes = super->s_ninodes;
00169   s->inode_maps = bitmapsize( (bit_t) s->inodes + 1 , s->block_size);
00170   if ( s->inode_maps != super->s_imap_blocks )
00171     {
00172     if ( s->inode_maps > super->s_imap_blocks )
00173       Error( "Corrupted inode map count or inode count in super block" );
00174     else  
00175       Warning( "Count of inode map blocks in super block suspiciously high" );
00176     s->inode_maps = super->s_imap_blocks;
00177     }
00178 
00179   s->zone_maps = bitmapsize( (bit_t) s->zones , s->block_size);
00180   if ( s->zone_maps != super->s_zmap_blocks )
00181     {
00182     if ( s->zone_maps > super->s_zmap_blocks )
00183       Error( "Corrupted zone map count or zone count in super block" );
00184     else
00185       Warning( "Count of zone map blocks in super block suspiciously high" );
00186     s->zone_maps = super->s_zmap_blocks;
00187     }
00188 
00189   s->inode_blocks = (s->inodes + inodes_per_block - 1) / inodes_per_block;
00190   s->first_data   = 2 + s->inode_maps + s->zone_maps + s->inode_blocks;
00191   if ( s->first_data != super->s_firstdatazone )
00192   {
00193     if ( s->first_data > super->s_firstdatazone )
00194       Error( "Corrupted first data zone offset or inode count in super block" );
00195     else
00196       Warning( "First data zone in super block suspiciously high" );
00197     s->first_data = super->s_firstdatazone;
00198   }  
00199 
00200   s->inodes_in_map = s->inodes + 1;
00201   s->zones_in_map  = s->zones + 1 - s->first_data;
00202 
00203   /*
00204   if ( s->zones != s->device_size )
00205     Warning( "Zone count does not equal device size" );
00206   */
00207 
00208   s->device_size = s->zones;
00209 
00210   if ( super->s_log_zone_size != 0 )
00211     Error( "Can not handle multiple blocks per zone" );
00212   }
00213 
00214 
00215 
00216 
00217 
00218 
00219 /****************************************************************/
00220 /*                                                              */
00221 /*      Read_Bit_Maps( state )                                  */
00222 /*                                                              */
00223 /*              Read in the i-node and zone bit maps from the   */
00224 /*              specified file system device.                   */
00225 /*                                                              */
00226 /****************************************************************/
00227 
00228 
00229 void Read_Bit_Maps( s )
00230   de_state *s;
00231 
00232   {
00233   int i;
00234 
00235   if ( s->inode_maps > I_MAP_SLOTS  ||  s->zone_maps > Z_MAP_SLOTS )
00236     {
00237     Warning( "Super block specifies too many bit map blocks" );
00238     return;
00239     }
00240 
00241   for ( i = 0;  i < s->inode_maps;  ++i )
00242     {
00243     Read_Disk( s, (long) (2 + i) * K,
00244                (char *) &s->inode_map[ i * K / sizeof (bitchunk_t ) ] );
00245     }
00246 
00247   for ( i = 0;  i < s->zone_maps;  ++i )
00248     {
00249     Read_Disk( s, (long) (2 + s->inode_maps + i) * K,
00250                (char *) &s->zone_map[ i * K / sizeof (bitchunk_t ) ] );
00251     }
00252   }
00253 
00254 
00255 
00256 
00257 
00258 
00259 /****************************************************************/
00260 /*                                                              */
00261 /*      Search( state, string )                                 */
00262 /*                                                              */
00263 /*              Search from the current address for the ASCII   */
00264 /*              "string" on the device.                         */
00265 /*                                                              */
00266 /****************************************************************/
00267 
00268 
00269 off_t Search( s, string )
00270   de_state *s;
00271   char *string;
00272 
00273   {
00274   off_t address   = s->address + 1;
00275   off_t last_addr = address;
00276   char  buffer[ SEARCH_BUFFER ];
00277   int   offset;
00278   int   tail_length = strlen( string ) - 1;
00279   int   count = SEARCH_BUFFER;
00280   int   last_offset;
00281 
00282 
00283   for (  ;  count == SEARCH_BUFFER;  address += SEARCH_BUFFER - tail_length )
00284     {
00285     if ( lseek( s->device_d, address, SEEK_SET ) == -1 )
00286       Error( "Error seeking %s", s->device_name );
00287 
00288     if ( (count = read( s->device_d, buffer, SEARCH_BUFFER)) == -1 )
00289       Error( "Error reading %s", s->device_name );
00290 
00291 
00292     if ( address - last_addr >= 500L * K )
00293       {
00294       putchar( '.' );
00295       fflush( stdout );
00296 
00297       last_addr += 500L * K;
00298       }
00299 
00300 
00301     last_offset = count - tail_length;
00302 
00303     for ( offset = 0;  offset < last_offset;  ++offset )
00304       {
00305       register char c = buffer[ offset ];
00306 
00307       if ( c == *string )
00308         {
00309         char *tail_buffer = &buffer[ offset + 1 ];
00310         char *tail_string = string + 1;
00311 
00312         do
00313           {
00314           if ( *tail_string == '\0' )
00315             return( address + offset );
00316           }
00317           while ( *tail_buffer++ == *tail_string++ );
00318         }
00319       }  /*  end for ( offset )  */
00320     }  /*  end for ( address )  */
00321 
00322   return( -1L );
00323   }
00324 
00325 
00326 
00327 
00328 
00329 
00330 /****************************************************************/
00331 /*                                                              */
00332 /*      Write_Word( state, word )                               */
00333 /*                                                              */
00334 /*              Write a word at address.                        */
00335 /*                                                              */
00336 /****************************************************************/
00337 
00338 
00339 void Write_Word( s, word )
00340   de_state *s;
00341   word_t word;
00342 
00343   {
00344   if ( s->address & 01 )
00345     Error( "Internal fault (unaligned address)" );
00346 
00347   if ( lseek( s->device_d, s->address, SEEK_SET ) == -1 )
00348     Error( "Error seeking %s", s->device_name );
00349 
00350   if ( write( s->device_d, (char *) &word, sizeof word ) != sizeof word )
00351     Error( "Error writing %s", s->device_name );
00352   }

Generated on Fri Apr 14 22:56:47 2006 for minix by  doxygen 1.4.6