home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / filesy~1 / mfs609s.zoo / minixfs / inode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-25  |  5.6 KB  |  246 lines

  1. /* This file is part of 'minixfs' Copyright 1991,1992,1993 S.N.Henson */
  2.  
  3. #include "minixfs.h"
  4. #include "proto.h"
  5. #include "global.h"
  6.  
  7. /* Inode routines */
  8.  
  9. /* Read an inode from the cache , if the filesystem is V1 convert to V2
  10.  * first , this greatly simplifies matters as other routines can then deal
  11.  * exclusively with V2 inodes.
  12.  */
  13.  
  14. int read_inode(num,rip,drv)
  15. unsigned num;
  16. d_inode *rip;
  17. int drv;
  18. {
  19.     bufr *tmp;
  20.     super_info *psblk=super_ptr[drv];
  21.     num-=1;
  22.     tmp=cget_block(num/psblk->ipb+psblk->ioff,drv,&icache);
  23.     if(psblk->version) *rip=tmp->binode[num%psblk->ipb];
  24.     else
  25.     {
  26.         d_inode1 *oldrip;
  27.         int i;
  28.         oldrip=&tmp->binode1[num%psblk->ipb];
  29.         /* Convert V1 inode to V2 */
  30.         rip->i_mode=oldrip->i_mode;
  31.         rip->i_nlinks=oldrip->i_nlinks;
  32.         rip->i_uid=oldrip->i_uid;
  33.         rip->i_gid=oldrip->i_gid;
  34.         rip->i_size=oldrip->i_size;
  35.         rip->i_atime=oldrip->i_mtime;
  36.         rip->i_mtime=oldrip->i_mtime;
  37.         rip->i_ctime=oldrip->i_mtime;
  38.         for(i=0;i< NR_ZONE_NUMS;i++) rip->i_zone[i]=oldrip->i_zone[i];
  39.         rip->i_zone[NR_ZONE_NUMS]=0;
  40.     }
  41.     return(0);
  42. }
  43.  
  44. /* Write out an inode , assuming it is V2. If the filesystem is V1 it converts
  45.  * the supplied inode first.
  46.  */
  47.  
  48. int write_inode(num,rip,drv)
  49. unsigned num;
  50. d_inode *rip;
  51. int drv;
  52. {
  53.     cache *tmp;
  54.     super_info *psblk=super_ptr[drv];
  55.     num-=1;
  56.     tmp=cache_get(num/psblk->ipb+psblk->ioff,drv,&icache,NOGUESS);
  57.     if(psblk->version) tmp->buffer->binode[num%psblk->ipb]=*rip;
  58.     else
  59.     {
  60.         d_inode1 *oldrip;
  61.         int i;
  62.         oldrip=&tmp->buffer->binode1[num%psblk->ipb];
  63.         /* Convert V2 inode to V1 */
  64.         oldrip->i_mode=rip->i_mode;
  65.         oldrip->i_nlinks=rip->i_nlinks;
  66.         oldrip->i_uid=rip->i_uid;
  67.         oldrip->i_gid=rip->i_gid;
  68.         oldrip->i_size=rip->i_size;
  69.         oldrip->i_mtime=rip->i_mtime;
  70.         for(i=0;i<NR_ZONE_NUMS;i++) oldrip->i_zone[i]=rip->i_zone[i];
  71.     }
  72.     tmp->status=2;
  73.     return(0);
  74. }
  75.  
  76. /* 'get' an inode from the cache, return a pointer to the inode and
  77.  * if the pointer 'flag' is non-zero, return a pointer to the 'status' 
  78.  * flag as well. Need two versions for this as well.
  79.  */
  80.  
  81. d_inode1 *get_inode1(inum,drive,flag,guess)
  82. unsigned inum;
  83. int drive;
  84. int **flag;
  85. cache **guess;
  86. {
  87.     cache *tmp;
  88.     super_info *psblk=super_ptr[drive];
  89.     inum-=1;
  90.     tmp=cache_get((inum>>L_IPB)+psblk->ioff,drive,&icache,guess);
  91.     if(flag) *flag=&tmp->status;
  92.  
  93.     return &tmp->buffer->binode1[inum & (INODES_PER_BLOCK-1)] ;
  94. }
  95.  
  96. d_inode *get_inode2(inum,drive,flag,guess)
  97. unsigned inum;
  98. int drive;
  99. int **flag;
  100. cache **guess;
  101. {
  102.     cache *tmp;
  103.     super_info *psblk=super_ptr[drive];
  104.     inum-=1;
  105.     tmp=cache_get((inum>>L_IPB2)+psblk->ioff,drive,&icache,guess);
  106.  
  107.     if(flag) *flag=&tmp->status;
  108.  
  109.     return &tmp->buffer->binode[inum & (INODES_PER_BLOCK2-1)] ;
  110. }
  111.  
  112. /* Truncate an inode to 'count' zones, this is used by unlink() as well as
  113.  * (f)truncate() . Bit tricky this , we have to note which blocks to free,
  114.  * and free indirection/double indirection blocks too but iff all the blocks
  115.  * inside them are free too. We also need to keep count of how much to leave 
  116.  * alone , sparse files complicate this a bit .... so do 2 fs versions ....
  117.  */
  118.  
  119. void trunc_inode(rip,drive,count,zap)
  120. d_inode *rip;    
  121. int drive;
  122. long count;            /* number of blocks to leave */
  123. int zap;            /* flag to alter inode */
  124. {
  125.     int i,j;
  126.     bufr *tmp;
  127.     char some,dirty;
  128.     super_info *psblk=super_ptr[drive];
  129.     char vers;
  130.     vers=psblk->version;
  131.     /* Handle zones in inode first */
  132.     if(count<psblk->dzpi)
  133.     {
  134.         for(i=count;i<psblk->dzpi;i++) {
  135.             if(rip->i_zone[i])
  136.                 free_zone(rip->i_zone[i],drive);
  137.             if(zap)rip->i_zone[i]=0;
  138.         }
  139.         count=0;
  140.     }
  141.     else count-=psblk->dzpi;
  142. /* Handle indirect zone */
  143.     if(count< psblk->zpind) {
  144.         some=0;
  145.         dirty=0;
  146.         if(rip->i_zone[7]) {
  147.             tmp=get_zone(rip->i_zone[7],drive);
  148.             for(i=0;i<psblk->zpind;i++) {
  149.                 if(PIND(vers,tmp,i)) {
  150.                     if(count)some=1;
  151.                     else {
  152.                         free_zone(PIND(vers,tmp,i),drive);
  153.                         if(zap)PIND(vers,tmp,i)=0;
  154.                         dirty=1;
  155.                     }
  156.                 }    
  157.                 if(count)count--;
  158.             }
  159.             if(!some) {
  160.                 free_zone(rip->i_zone[7],drive);
  161.                 if(zap)rip->i_zone[7]=0;
  162.             }
  163.             else if(dirty) 
  164.                 write_zone(rip->i_zone[7],tmp,drive,&syscache);
  165.         }
  166.     }
  167.     else count-=psblk->zpind;
  168.     /* Handle double indirect ... */
  169.     if(rip->i_zone[8]) {
  170.         some=0;
  171.         dirty=0;
  172.         read_zone(rip->i_zone[8],&temp,drive,&syscache);
  173.         for(i=0;i<psblk->zpind;i++) {
  174.             if(IND(vers,temp,i)) {
  175.                 char lsome,ldirty; /* local some,dirty for inds */
  176.                 lsome=0;
  177.                 ldirty=0;
  178.                 tmp=get_zone(IND(vers,temp,i),drive);
  179.                 for(j=0;j<psblk->zpind;j++) {
  180.                 if(PIND(vers,tmp,j)) {
  181.                     if(count) { 
  182.                         some=1;
  183.                         lsome=1;
  184.                     }
  185.                     else {
  186.                         free_zone(PIND(vers,tmp,j),drive);
  187.                         if(zap)PIND(vers,tmp,j)=0;
  188.                         ldirty=1;
  189.                         dirty=1;
  190.                     }
  191.                 }
  192.                 if(count)count--;
  193.                 }
  194.                 if(!lsome) {
  195.                 free_zone(IND(vers,temp,i),drive);
  196.                 if(zap)IND(vers,temp,i)=0;
  197.                 }
  198.                 else if(ldirty)
  199.                 write_zone(IND(vers,temp,i),tmp,drive,&syscache);
  200.             }
  201.             else 
  202.             {
  203.                 if(count>=psblk->zpind)count-=psblk->zpind;
  204.                 else count=0;
  205.             }
  206.         }
  207.         if(!some) {
  208.             free_zone(rip->i_zone[8],drive);
  209.             if(zap)rip->i_zone[8]=0;
  210.         }
  211.         else if(dirty)write_zone(rip->i_zone[8],&temp,drive,&syscache);
  212.     }
  213. }
  214.  
  215. /* Inode version of (f)truncate , truncates a file to size 'length' ,
  216.  * not used at present ...
  217.  */
  218.  
  219. long itruncate(inum,drive,length)
  220. unsigned inum;
  221. int drive;
  222. long length;
  223. {
  224.     long count;
  225.     d_inode rip;
  226.     read_inode(inum,&rip,drive);
  227.     /* Regulars only , clever directory compaction stuff later ... */
  228.     if(!IS_REG(rip))return EACCDN;
  229.     /* If file smaller than 'length' nothing to do */
  230.     if(rip.i_size <= length)
  231.     {
  232. #if 0
  233.         rip.i_size=length;
  234. #endif
  235.         return 0;
  236.     }
  237.     count=(length+1023)/1024;
  238.     trunc_inode(&rip,drive,count,1);
  239.     rip.i_size=length;    
  240.     write_inode(inum,&rip,drive);
  241.     if(cache_mode) l_sync();
  242.     return 0;
  243. }
  244.  
  245.  
  246.