Subversion Repositories HelenOS

Rev

Rev 2404 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 1987,1997, Prentice Hall
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use of the MINIX operating system in source and
  6.  * binary forms, with or without modification, are permitted provided
  7.  * that the following conditions are met:
  8.  
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  
  12.  * - Redistributions in binary form must reproduce the above
  13.  *   copyright notice, this list of conditions and the following
  14.  *   disclaimer in the documentation and/or other materials provided
  15.  *   with the distribution.
  16.  
  17.  * - Neither the name of Prentice Hall nor the names of the software
  18.  *   authors or contributors may be used to endorse or promote
  19.  *   products derived from this software without specific prior
  20.  *   written permission.
  21.  
  22.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS, AUTHORS, AND
  23.  * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  24.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  25.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  26.  * IN NO EVENT SHALL PRENTICE HALL OR ANY AUTHORS OR CONTRIBUTORS BE
  27.  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29.  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  30.  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  31.  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  32.  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  33.  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34.  */
  35.  
  36. /** @addtogroup FileSystemImpl
  37. * @{
  38. */
  39.  
  40. /**
  41.  * @file    inode.c
  42.  * @brief   This file manages the inode table.  There are procedures to allocate and
  43. *         deallocate inodes, acquire, erase, and release them, and read and write
  44. *         them from the disk.
  45. */
  46.  
  47. #include "fs.h"
  48. #include "block.h"
  49. #include "file.h"
  50. #include "fproc.h"
  51. #include "inode.h"
  52. #include "super.h"
  53.  
  54. inode_t inode[NR_INODES];  /**< A variable to store inode entries */
  55.  
  56. static void v1_copy_inode(inode_t *rip, d1_inode_t *dip, int normal);
  57. static void v2_copy_inode(inode_t *rip, d2_inode_t *dip, int normal);
  58.  
  59. /**
  60.  * Search inode table for a given inode; if not there, read it
  61.  */
  62. inode_t *get_inode(int numb)
  63. {
  64.     /* Find a slot in the inode table, load the specified inode into it, and
  65.      * return a pointer to the slot.
  66.      */
  67.    
  68.     register inode_t *rip, *xp;
  69.    
  70.     /* Search the inode table both for numb and a free slot. */
  71.     xp = NIL_INODE;
  72.     for (rip = &inode[0]; rip < &inode[NR_INODES]; rip++) {
  73.         if (rip->i_count > 0) { /* only check used slots for numb */
  74.                 if (rip->i_num == numb) {
  75.                         /* This is the inode that we are looking for. */
  76.                             rip->i_count++;
  77.                             return rip;    /* numb found */
  78.                     }
  79.             }
  80.         else {
  81.                 xp = rip;   /* remember this free slot for later */
  82.         }          
  83.            
  84.     }
  85.    
  86.     /* Inode we want is not currently in use.  Did we find a free slot? */
  87.     if (xp == NIL_INODE) {        /* inode table completely full */
  88.         err_code = FS_ENFILE;
  89.             return NIL_INODE;
  90.     }
  91.    
  92.     /* A free inode slot has been located.  Load the inode into it. */
  93.     xp->i_num = numb;
  94.     xp->i_count = 1;
  95.     read_inode(xp);
  96.    
  97.     return xp;
  98. }
  99.        
  100. /**
  101.  * Read a disk block and extract an inode
  102.  */    
  103. void read_inode(register inode_t *rip)
  104. {
  105.    
  106.     /* An entry in the inode table is to be copied from the disk. */
  107.    
  108.     register block_t *bp;
  109.     register super_block_t *sp;
  110.     d1_inode_t *dip1;
  111.     d2_inode_t *dip2;
  112.     block_num_t b, offset;
  113.    
  114.     /* Get the block where the inode resides. */
  115.     sp = get_super();           /* get pointer to super block */
  116.     rip->i_sp = sp;               /* inode must contain super block pointer */
  117.     offset = sp->s_imap_blocks + sp->s_zmap_blocks + 2;
  118.     b = (block_num_t)(rip->i_num - 1)/sp->s_inodes_per_block + offset;
  119.     bp = get_block(b);
  120.     dip1  = bp->b.b__v1_ino + (rip->i_num - 1) % V1_INODES_PER_BLOCK;
  121.     dip2  = bp->b.b__v2_ino + (rip->i_num - 1) % V2_INODES_PER_BLOCK;
  122.      
  123.     /* Copy inode to the in-core table, swapping bytes if need be. */
  124.     if (sp->s_version == V1) {
  125.         v1_copy_inode(rip, dip1, sp->s_native);
  126.     }
  127.     else {
  128.         v2_copy_inode(rip, dip2, sp->s_native);
  129.     }    
  130. }
  131.  
  132. /**
  133.  * Copy from disk inode (V1.x) to in-memory inode struct
  134.  */
  135. void v1_copy_inode(inode_t *rip, d1_inode_t *dip, int normal)
  136. {
  137.     /* The V1.x IBM disk, the V1.x 68000 disk, and the V2 disk (same for IBM and
  138.      * 68000) all have different inode layouts.  When an inode is read or written
  139.      * this routine handles the conversions so that the information in the inode
  140.      * table is independent of the disk structure from which the inode came.
  141.      * This routine copies from V1 disks.
  142.      */
  143.  
  144.     int i;
  145.  
  146.     /* Some check is made for valid number of inode. */
  147.     if (rip == NIL_INODE || dip == NULL)
  148.         return;
  149.    
  150.     /* Copy V1.x inode to the in-memory table, swapping bytes if need be. */
  151.     rip->i_mode = conv2(normal, dip->d1_mode);
  152.     rip->i_size = conv4(normal, dip->d1_size);
  153.     rip->i_nlinks = (nlink_t)dip->d1_nlinks;    /* 1 char */
  154.     rip->i_ndzones = V1_NR_DZONES;
  155.     rip->i_nindirs = V1_INDIRECTS; 
  156.        
  157.     for (i = 0; i < V1_NR_TZONES; i++)
  158.         rip->i_zone[i] = conv2(normal, dip->d1_zone[i]);   
  159. }
  160.  
  161. /**
  162.  * Copy from disk inode (V2.x) to in-memory inode structs
  163.  */
  164. void v2_copy_inode(inode_t *rip, d2_inode_t *dip, int normal)
  165. {
  166.     /* Same as old_icopy, but to/from V2 disk layout. */
  167.  
  168.     int i;
  169.    
  170.     /* Some check is made for valid number of inode. */
  171.     if (rip == NIL_INODE || dip == NULL)
  172.         return;
  173.    
  174.     /* Copy V2.x inode to the in-core table, swapping bytes if need be. */
  175.     rip->i_mode = conv2(normal, dip->d2_mode);
  176.     rip->i_size = conv4(normal, dip->d2_size);
  177.     rip->i_nlinks = conv2(normal, dip->d2_nlinks);
  178.     rip->i_ndzones = V2_NR_DZONES;
  179.     rip->i_nindirs = V2_INDIRECTS; 
  180.        
  181.     for (i = 0; i < V2_NR_TZONES; i++)
  182.         rip->i_zone[i] = conv4(normal, dip->d2_zone[i]);   
  183. }
  184.  
  185. /**
  186.  * Indicate that an inode is no longer needed in memory
  187.  */
  188. void put_inode(inode_t *rip)
  189. {
  190.    
  191.     /* The caller is no longer using this inode. */
  192.  
  193.     if (rip == NIL_INODE)
  194.         return;
  195.  
  196.     rip->i_count--;
  197. }
  198.  
  199. /**
  200.  * Indicate that someone else is using an inode table entry
  201.  */
  202. void dup_inode(inode_t *rip)
  203. {
  204.    
  205.     /* This routine is a simplified form of get_inode() for the case where
  206.      * the inode pointer is already known.
  207.      */
  208.  
  209.     if (rip == NIL_INODE)
  210.         return;
  211.  
  212.     rip->i_count++;
  213. }
  214.  
  215.  
  216. /**
  217.  * }
  218.  */
  219.  
  220.