Subversion Repositories HelenOS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* Superblock support. */
  2.  
  3. /* Methods:
  4.  * init_super:  initializes the superblock structure for later use
  5.  * get_super:   return pointer at the superblock
  6.  * read_super:  read a superblock
  7.  */
  8.  
  9. #include <string.h>
  10. #include "fs.h"
  11. #include "block.h"
  12. #include "inode.h"
  13. #include "super.h"
  14. #include <stdio.h>
  15.  
  16.  
  17. super_block_t* super_block;
  18.      
  19. static int v1(int magic, int *version, int *extend);
  20. static int v2(int magic ,int*version, int *extend);
  21. static int get_native(int magic, int *version, int *extend);
  22.  
  23. int (*versions[TOTAL_VERSIONS])(int , int*, int*)  = {
  24.         v1, /* 0 = V1 version */
  25.         v2  /* 1 = V2 version */
  26.     };
  27.  
  28. int init_super_block()
  29. {
  30.    
  31.     super_block = (super_block_t*)malloc(sizeof(super_block_t));
  32.     if (super_block != NULL)
  33.         return TRUE;
  34.  
  35.         return FALSE;  
  36. }
  37.    
  38. super_block_t *get_super()
  39. {  
  40.     return super_block;
  41. }
  42.  
  43. int read_super(register super_block_t *sp)
  44. {
  45.    
  46.     /* Read a superblock. */
  47.    
  48.     register block_t *bp;
  49.     int magic, version, extend, native;
  50.  
  51.        
  52.     bp = get_block(SUPER_BLOCK);
  53.     memcpy((void *)sp, (void *)(bp->b.b__data), (size_t)SUPER_SIZE);
  54.     magic = sp->s_magic;        /* determines file system type */
  55.    
  56.  
  57.     /* Get file system version and type. */
  58.     native = get_native(magic, &version, &extend);
  59.  
  60.     if (native == FS_EINVAL) {
  61.         print_console("Unknown version of file system\n");
  62.         print_console("Magic is bad\n");
  63.         return FS_EINVAL;  
  64.     }
  65.      
  66.     /* In V1, the device size was kept in a short, s_nzones, which limited
  67.        * devices to 32K zones.  For V2, it was decided to keep the size as a
  68.        * long.  However, just changing s_nzones to a long would not work, since
  69.        * then the position of s_magic in the super block would not be the same
  70.        * in V1 and V2 file systems, and there would be no way to tell whether
  71.        * a newly mounted file system was V1 or V2.  The solution was to introduce
  72.        * a new variable, s_zones, and copy the size there.
  73.        *
  74.        * Calculate some other numbers that depend on the version here too, to
  75.        * hide some of the differences.
  76.        */
  77.  
  78.     if (version == V1) {
  79.         sp->s_zones = sp->s_nzones;     /* only V1 needs this copy */
  80.         sp->s_inodes_per_block = V1_INODES_PER_BLOCK;
  81.         sp->s_ndzones = V1_NR_DZONES;
  82.         sp->s_nindirs = V1_INDIRECTS;
  83.     }
  84.     else {
  85.         sp->s_inodes_per_block = V2_INODES_PER_BLOCK;
  86.         sp->s_ndzones = V2_NR_DZONES;
  87.         sp->s_nindirs = V2_INDIRECTS;
  88.     }
  89.    
  90.     sp->s_isearch = 0;  /* inode searches initially start at 0 */
  91.     sp->s_zsearch = 0;  /* zone searches initially start at 0 */
  92.     sp->s_version = version;
  93.     sp->s_native  = native;    
  94.     sp->s_extend = extend;
  95.  
  96.    
  97.     /* Make a few basic checks to see if super block looks reasonable. */
  98.     if (sp->s_imap_blocks < 1 || sp->s_zmap_blocks < 1
  99.         || sp->s_ninodes < 1 || sp->s_zones < 1
  100.         || (unsigned) sp->s_log_zone_size > 4) {
  101.         return FS_EINVAL;
  102.     }  
  103.      
  104.     return OK;
  105. }
  106.  
  107. int v1(int magic, int* version, int *extend)
  108. {
  109.    
  110.     if (magic == SUPER_MAGIC || magic == conv2(BYTE_SWAP,SUPER_MAGIC)) {
  111.        
  112.         *version = V1; *extend = FALSE;
  113.         return TRUE;
  114.     }
  115.     if (magic == SUPER_MAGIC2 || magic == conv2(BYTE_SWAP,SUPER_MAGIC2)) {
  116.         *version = V1; *extend = TRUE;
  117.         return TRUE;
  118.     }
  119.  
  120.     return FALSE;
  121. }
  122.  
  123. int v2(int magic, int *version, int *extend)
  124. {
  125.    
  126.     if (magic == SUPER_V2 || magic == conv2(BYTE_SWAP,SUPER_V2)) {
  127.         *version = V2; *extend = FALSE;
  128.         return TRUE;
  129.     }
  130.    
  131.     if (magic == SUPER_V2E || magic == conv2(BYTE_SWAP,SUPER_V2E)) {
  132.         *version = V2; *extend = TRUE;
  133.         return TRUE;
  134.     }
  135.  
  136.     return FALSE;
  137. }
  138.  
  139. int get_native(int magic, int *version, int *extend)
  140. {
  141.    
  142.    
  143.     int i, result;
  144.    
  145.     /* Get file system version and type */
  146.     for (i = 0; i < TOTAL_VERSIONS; i++) {
  147.         result = versions[i](magic, version, extend);
  148.         if (result) {
  149.             return result;
  150.         }
  151.     }
  152.  
  153.     return FS_EINVAL;
  154. }
  155.