home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V6 / usr / sys / ken / iget.c < prev    next >
Encoding:
C/C++ Source or Header  |  1975-07-18  |  4.3 KB  |  235 lines

  1. #
  2. #include "../param.h"
  3. #include "../systm.h"
  4. #include "../user.h"
  5. #include "../inode.h"
  6. #include "../filsys.h"
  7. #include "../conf.h"
  8. #include "../buf.h"
  9.  
  10. /*
  11.  * Look up an inode by device,inumber.
  12.  * If it is in core (in the inode structure),
  13.  * honor the locking protocol.
  14.  * If it is not in core, read it in from the
  15.  * specified device.
  16.  * If the inode is mounted on, perform
  17.  * the indicated indirection.
  18.  * In all cases, a pointer to a locked
  19.  * inode structure is returned.
  20.  *
  21.  * printf warning: no inodes -- if the inode
  22.  *    structure is full
  23.  * panic: no imt -- if the mounted file
  24.  *    system is not in the mount table.
  25.  *    "cannot happen"
  26.  */
  27. iget(dev, ino)
  28. {
  29.     register struct inode *p;
  30.     register *ip2;
  31.     int *ip1;
  32.     register struct mount *ip;
  33.  
  34. loop:
  35.     ip = NULL;
  36.     for(p = &inode[0]; p < &inode[NINODE]; p++) {
  37.         if(dev==p->i_dev && ino==p->i_number) {
  38.             if((p->i_flag&ILOCK) != 0) {
  39.                 p->i_flag =| IWANT;
  40.                 sleep(p, PINOD);
  41.                 goto loop;
  42.             }
  43.             if((p->i_flag&IMOUNT) != 0) {
  44.                 for(ip = &mount[0]; ip < &mount[NMOUNT]; ip++)
  45.                 if(ip->m_inodp == p) {
  46.                     dev = ip->m_dev;
  47.                     ino = ROOTINO;
  48.                     goto loop;
  49.                 }
  50.                 panic("no imt");
  51.             }
  52.             p->i_count++;
  53.             p->i_flag =| ILOCK;
  54.             return(p);
  55.         }
  56.         if(ip==NULL && p->i_count==0)
  57.             ip = p;
  58.     }
  59.     if((p=ip) == NULL) {
  60.         printf("Inode table overflow\n");
  61.         u.u_error = ENFILE;
  62.         return(NULL);
  63.     }
  64.     p->i_dev = dev;
  65.     p->i_number = ino;
  66.     p->i_flag = ILOCK;
  67.     p->i_count++;
  68.     p->i_lastr = -1;
  69.     ip = bread(dev, ldiv(ino+31,16));
  70.     /*
  71.      * Check I/O errors
  72.      */
  73.     if (ip->b_flags&B_ERROR) {
  74.         brelse(ip);
  75.         iput(p);
  76.         return(NULL);
  77.     }
  78.     ip1 = ip->b_addr + 32*lrem(ino+31, 16);
  79.     ip2 = &p->i_mode;
  80.     while(ip2 < &p->i_addr[8])
  81.         *ip2++ = *ip1++;
  82.     brelse(ip);
  83.     return(p);
  84. }
  85.  
  86. /*
  87.  * Decrement reference count of
  88.  * an inode structure.
  89.  * On the last reference,
  90.  * write the inode out and if necessary,
  91.  * truncate and deallocate the file.
  92.  */
  93. iput(p)
  94. struct inode *p;
  95. {
  96.     register *rp;
  97.  
  98.     rp = p;
  99.     if(rp->i_count == 1) {
  100.         rp->i_flag =| ILOCK;
  101.         if(rp->i_nlink <= 0) {
  102.             itrunc(rp);
  103.             rp->i_mode = 0;
  104.             ifree(rp->i_dev, rp->i_number);
  105.         }
  106.         iupdat(rp, time);
  107.         prele(rp);
  108.         rp->i_flag = 0;
  109.         rp->i_number = 0;
  110.     }
  111.     rp->i_count--;
  112.     prele(rp);
  113. }
  114.  
  115. /*
  116.  * Check accessed and update flags on
  117.  * an inode structure.
  118.  * If either is on, update the inode
  119.  * with the corresponding dates
  120.  * set to the argument tm.
  121.  */
  122. iupdat(p, tm)
  123. int *p;
  124. int *tm;
  125. {
  126.     register *ip1, *ip2, *rp;
  127.     int *bp, i;
  128.  
  129.     rp = p;
  130.     if((rp->i_flag&(IUPD|IACC)) != 0) {
  131.         if(getfs(rp->i_dev)->s_ronly)
  132.             return;
  133.         i = rp->i_number+31;
  134.         bp = bread(rp->i_dev, ldiv(i,16));
  135.         ip1 = bp->b_addr + 32*lrem(i, 16);
  136.         ip2 = &rp->i_mode;
  137.         while(ip2 < &rp->i_addr[8])
  138.             *ip1++ = *ip2++;
  139.         if(rp->i_flag&IACC) {
  140.             *ip1++ = time[0];
  141.             *ip1++ = time[1];
  142.         } else
  143.             ip1 =+ 2;
  144.         if(rp->i_flag&IUPD) {
  145.             *ip1++ = *tm++;
  146.             *ip1++ = *tm;
  147.         }
  148.         bwrite(bp);
  149.     }
  150. }
  151.  
  152. /*
  153.  * Free all the disk blocks associated
  154.  * with the specified inode structure.
  155.  * The blocks of the file are removed
  156.  * in reverse order. This FILO
  157.  * algorithm will tend to maintain
  158.  * a contiguous free list much longer
  159.  * than FIFO.
  160.  */
  161. itrunc(ip)
  162. int *ip;
  163. {
  164.     register *rp, *bp, *cp;
  165.     int *dp, *ep;
  166.  
  167.     rp = ip;
  168.     if((rp->i_mode&(IFCHR&IFBLK)) != 0)
  169.         return;
  170.     for(ip = &rp->i_addr[7]; ip >= &rp->i_addr[0]; ip--)
  171.     if(*ip) {
  172.         if((rp->i_mode&ILARG) != 0) {
  173.             bp = bread(rp->i_dev, *ip);
  174.             for(cp = bp->b_addr+512; cp >= bp->b_addr; cp--)
  175.             if(*cp) {
  176.                 if(ip == &rp->i_addr[7]) {
  177.                     dp = bread(rp->i_dev, *cp);
  178.                     for(ep = dp->b_addr+512; ep >= dp->b_addr; ep--)
  179.                     if(*ep)
  180.                         free(rp->i_dev, *ep);
  181.                     brelse(dp);
  182.                 }
  183.                 free(rp->i_dev, *cp);
  184.             }
  185.             brelse(bp);
  186.         }
  187.         free(rp->i_dev, *ip);
  188.         *ip = 0;
  189.     }
  190.     rp->i_mode =& ~ILARG;
  191.     rp->i_size0 = 0;
  192.     rp->i_size1 = 0;
  193.     rp->i_flag =| IUPD;
  194. }
  195.  
  196. /*
  197.  * Make a new file.
  198.  */
  199. maknode(mode)
  200. {
  201.     register *ip;
  202.  
  203.     ip = ialloc(u.u_pdir->i_dev);
  204.     if (ip==NULL)
  205.         return(NULL);
  206.     ip->i_flag =| IACC|IUPD;
  207.     ip->i_mode = mode|IALLOC;
  208.     ip->i_nlink = 1;
  209.     ip->i_uid = u.u_uid;
  210.     ip->i_gid = u.u_gid;
  211.     wdir(ip);
  212.     return(ip);
  213. }
  214.  
  215. /*
  216.  * Write a directory entry with
  217.  * parameters left as side effects
  218.  * to a call to namei.
  219.  */
  220. wdir(ip)
  221. int *ip;
  222. {
  223.     register char *cp1, *cp2;
  224.  
  225.     u.u_dent.u_ino = ip->i_number;
  226.     cp1 = &u.u_dent.u_name[0];
  227.     for(cp2 = &u.u_dbuf[0]; cp2 < &u.u_dbuf[DIRSIZ];)
  228.         *cp1++ = *cp2++;
  229.     u.u_count = DIRSIZ+2;
  230.     u.u_segflg = 1;
  231.     u.u_base = &u.u_dent;
  232.     writei(u.u_pdir);
  233.     iput(u.u_pdir);
  234. }
  235.