Subversion Repositories HelenOS

Rev

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

  1. /* This file manages the inode table.  There are procedures to allocate and
  2. * deallocate inodes, acquire, erase, and release them, and read and write
  3. * them from the disk.
  4. */
  5.  
  6. /* Methods:
  7.  * get_inode:       search inode table for a given inode; if not there, read it
  8.  * read_inode:      read a disk block and extract an inode
  9.  * v1_copy_inode    copy from disk inode (V1.x) to in-memory inode struct
  10.  * v2_copy_inode    copy from disk inode (V2.x) to in-memory inode structs
  11.  * put_inode        indicate that an inode is no longer needed in memory
  12.  * dup_inode:       indicate that someone else is using an inode table entry
  13.  */
  14.  
  15. #include "fs.h"
  16. #include "block.h"
  17. #include "file.h"
  18. #include "fproc.h"
  19. #include "inode.h"
  20. #include "super.h"
  21.  
  22.  
  23. inode_t inode[NR_INODES];
  24.  
  25. static void v1_copy_inode(inode_t *rip, d1_inode_t *dip, int normal);
  26. static void v2_copy_inode(inode_t *rip, d2_inode_t *dip, int normal);
  27.  
  28.  
  29. inode_t *get_inode(int numb)
  30. {
  31.     /* Find a slot in the inode table, load the specified inode into it, and
  32.      * return a pointer to the slot.
  33.      */
  34.    
  35.     register inode_t *rip, *xp;
  36.    
  37.     /* Search the inode table both for numb and a free slot. */
  38.     xp = NIL_INODE;
  39.     for (rip = &inode[0]; rip < &inode[NR_INODES]; rip++) {
  40.         if (rip->i_count > 0) { /* only check used slots for numb */
  41.                 if (rip->i_num == numb) {
  42.                         /* This is the inode that we are looking for. */
  43.                             rip->i_count++;
  44.                             return rip;    /* numb found */
  45.                     }
  46.             }
  47.         else {
  48.                 xp = rip;   /* remember this free slot for later */
  49.         }          
  50.            
  51.     }
  52.    
  53.     /* Inode we want is not currently in use.  Did we find a free slot? */
  54.     if (xp == NIL_INODE) {        /* inode table completely full */
  55.         err_code = FS_ENFILE;
  56.             return NIL_INODE;
  57.     }
  58.    
  59.     /* A free inode slot has been located.  Load the inode into it. */
  60.     xp->i_num = numb;
  61.     xp->i_count = 1;
  62.     read_inode(xp);
  63.    
  64.     return xp;
  65. }
  66.        
  67. void read_inode(register inode_t *rip)
  68. {
  69.    
  70.     /* An entry in the inode table is to be copied from the disk. */
  71.    
  72.     register block_t *bp;
  73.     register super_block_t *sp;
  74.     d1_inode_t *dip1;
  75.     d2_inode_t *dip2;
  76.     block_num_t b, offset;
  77.    
  78.     /* Get the block where the inode resides. */
  79.     sp = get_super();           /* get pointer to super block */
  80.     rip->i_sp = sp;               /* inode must contain super block pointer */
  81.     offset = sp->s_imap_blocks + sp->s_zmap_blocks + 2;
  82.     b = (block_num_t)(rip->i_num - 1)/sp->s_inodes_per_block + offset;
  83.     bp = get_block(b);
  84.     dip1  = bp->b.b__v1_ino + (rip->i_num - 1) % V1_INODES_PER_BLOCK;
  85.     dip2  = bp->b.b__v2_ino + (rip->i_num - 1) % V2_INODES_PER_BLOCK;
  86.      
  87.     /* Copy inode to the in-core table, swapping bytes if need be. */
  88.     if (sp->s_version == V1) {
  89.         v1_copy_inode(rip, dip1, sp->s_native);
  90.     }
  91.     else {
  92.         v2_copy_inode(rip, dip2, sp->s_native);
  93.     }    
  94. }
  95.    
  96. void v1_copy_inode(inode_t *rip, d1_inode_t *dip, int normal)
  97. {
  98.  
  99.    
  100.     /* The V1.x IBM disk, the V1.x 68000 disk, and the V2 disk (same for IBM and
  101.      * 68000) all have different inode layouts.  When an inode is read or written
  102.      * this routine handles the conversions so that the information in the inode
  103.      * table is independent of the disk structure from which the inode came.
  104.      * This routine copies from V1 disks.
  105.      */
  106.  
  107.     int i;
  108.  
  109.     /* Some check is made for valid number of inode. */
  110.     if (rip == NIL_INODE || dip == NULL)
  111.         return;
  112.    
  113.     /* Copy V1.x inode to the in-memory table, swapping bytes if need be. */
  114.     rip->i_mode = conv2(normal, dip->d1_mode);
  115.     rip->i_size = conv4(normal, dip->d1_size);
  116.     rip->i_nlinks = (nlink_t)dip->d1_nlinks;    /* 1 char */
  117.     rip->i_ndzones = V1_NR_DZONES;
  118.     rip->i_nindirs = V1_INDIRECTS; 
  119.        
  120.     for (i = 0; i < V1_NR_TZONES; i++)
  121.         rip->i_zone[i] = conv2(normal, dip->d1_zone[i]);   
  122. }
  123.    
  124. void v2_copy_inode(inode_t *rip, d2_inode_t *dip, int normal)
  125. {
  126.    
  127.    
  128.     /* Same as old_icopy, but to/from V2 disk layout. */
  129.  
  130.     int i;
  131.    
  132.     /* Some check is made for valid number of inode. */
  133.     if (rip == NIL_INODE || dip == NULL)
  134.         return;
  135.    
  136.     /* Copy V2.x inode to the in-core table, swapping bytes if need be. */
  137.     rip->i_mode = conv2(normal, dip->d2_mode);
  138.     rip->i_size = conv4(normal, dip->d2_size);
  139.     rip->i_nlinks = conv2(normal, dip->d2_nlinks);
  140.     rip->i_ndzones = V2_NR_DZONES;
  141.     rip->i_nindirs = V2_INDIRECTS; 
  142.        
  143.     for (i = 0; i < V2_NR_TZONES; i++)
  144.         rip->i_zone[i] = conv4(normal, dip->d2_zone[i]);   
  145. }
  146.  
  147. void put_inode(inode_t *rip)
  148. {
  149.    
  150.     /* The caller is no longer using this inode. */
  151.  
  152.     if (rip == NIL_INODE)
  153.         return;
  154.  
  155.     rip->i_count--;
  156. }
  157.    
  158. void dup_inode(inode_t *rip)
  159. {
  160.    
  161.     /* This routine is a simplified form of get_inode() for the case where
  162.      * the inode pointer is already known.
  163.      */
  164.  
  165.     if (rip == NIL_INODE)
  166.         return;
  167.  
  168.     rip->i_count++;
  169. }
  170.  
  171.