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

  1. #
  2. /*
  3.  */
  4.  
  5. #include "../param.h"
  6. #include "../conf.h"
  7. #include "../inode.h"
  8. #include "../user.h"
  9. #include "../buf.h"
  10. #include "../systm.h"
  11.  
  12. /*
  13.  * Bmap defines the structure of file system storage
  14.  * by returning the physical block number on a device given the
  15.  * inode and the logical block number in a file.
  16.  * When convenient, it also leaves the physical
  17.  * block number of the next block of the file in rablock
  18.  * for use in read-ahead.
  19.  */
  20. bmap(ip, bn)
  21. struct inode *ip;
  22. int bn;
  23. {
  24.     register *bp, *bap, nb;
  25.     int *nbp, d, i;
  26.  
  27.     d = ip->i_dev;
  28.     if(bn & ~077777) {
  29.         u.u_error = EFBIG;
  30.         return(0);
  31.     }
  32.  
  33.     if((ip->i_mode&ILARG) == 0) {
  34.  
  35.         /*
  36.          * small file algorithm
  37.          */
  38.  
  39.         if((bn & ~7) != 0) {
  40.  
  41.             /*
  42.              * convert small to large
  43.              */
  44.  
  45.             if ((bp = alloc(d)) == NULL)
  46.                 return(NULL);
  47.             bap = bp->b_addr;
  48.             for(i=0; i<8; i++) {
  49.                 *bap++ = ip->i_addr[i];
  50.                 ip->i_addr[i] = 0;
  51.             }
  52.             ip->i_addr[0] = bp->b_blkno;
  53.             bdwrite(bp);
  54.             ip->i_mode =| ILARG;
  55.             goto large;
  56.         }
  57.         nb = ip->i_addr[bn];
  58.         if(nb == 0 && (bp = alloc(d)) != NULL) {
  59.             bdwrite(bp);
  60.             nb = bp->b_blkno;
  61.             ip->i_addr[bn] = nb;
  62.             ip->i_flag =| IUPD;
  63.         }
  64.         rablock = 0;
  65.         if (bn<7)
  66.             rablock = ip->i_addr[bn+1];
  67.         return(nb);
  68.     }
  69.  
  70.     /*
  71.      * large file algorithm
  72.      */
  73.  
  74.     large:
  75.     i = bn>>8;
  76.     if(bn & 0174000)
  77.         i = 7;
  78.     if((nb=ip->i_addr[i]) == 0) {
  79.         ip->i_flag =| IUPD;
  80.         if ((bp = alloc(d)) == NULL)
  81.             return(NULL);
  82.         ip->i_addr[i] = bp->b_blkno;
  83.     } else
  84.         bp = bread(d, nb);
  85.     bap = bp->b_addr;
  86.  
  87.     /*
  88.      * "huge" fetch of double indirect block
  89.      */
  90.  
  91.     if(i == 7) {
  92.         i = ((bn>>8) & 0377) - 7;
  93.         if((nb=bap[i]) == 0) {
  94.             if((nbp = alloc(d)) == NULL) {
  95.                 brelse(bp);
  96.                 return(NULL);
  97.             }
  98.             bap[i] = nbp->b_blkno;
  99.             bdwrite(bp);
  100.         } else {
  101.             brelse(bp);
  102.             nbp = bread(d, nb);
  103.         }
  104.         bp = nbp;
  105.         bap = bp->b_addr;
  106.     }
  107.  
  108.     /*
  109.      * normal indirect fetch
  110.      */
  111.  
  112.     i = bn & 0377;
  113.     if((nb=bap[i]) == 0 && (nbp = alloc(d)) != NULL) {
  114.         nb = nbp->b_blkno;
  115.         bap[i] = nb;
  116.         bdwrite(nbp);
  117.         bdwrite(bp);
  118.     } else
  119.         brelse(bp);
  120.     rablock = 0;
  121.     if(i < 255)
  122.         rablock = bap[i+1];
  123.     return(nb);
  124. }
  125.  
  126. /*
  127.  * Pass back  c  to the user at his location u_base;
  128.  * update u_base, u_count, and u_offset.  Return -1
  129.  * on the last character of the user's read.
  130.  * u_base is in the user address space unless u_segflg is set.
  131.  */
  132. passc(c)
  133. char c;
  134. {
  135.  
  136.     if(u.u_segflg)
  137.         *u.u_base = c; else
  138.         if(subyte(u.u_base, c) < 0) {
  139.             u.u_error = EFAULT;
  140.             return(-1);
  141.         }
  142.     u.u_count--;
  143.     if(++u.u_offset[1] == 0)
  144.         u.u_offset[0]++;
  145.     u.u_base++;
  146.     return(u.u_count == 0? -1: 0);
  147. }
  148.  
  149. /*
  150.  * Pick up and return the next character from the user's
  151.  * write call at location u_base;
  152.  * update u_base, u_count, and u_offset.  Return -1
  153.  * when u_count is exhausted.  u_base is in the user's
  154.  * address space unless u_segflg is set.
  155.  */
  156. cpass()
  157. {
  158.     register c;
  159.  
  160.     if(u.u_count == 0)
  161.         return(-1);
  162.     if(u.u_segflg)
  163.         c = *u.u_base; else
  164.         if((c=fubyte(u.u_base)) < 0) {
  165.             u.u_error = EFAULT;
  166.             return(-1);
  167.         }
  168.     u.u_count--;
  169.     if(++u.u_offset[1] == 0)
  170.         u.u_offset[0]++;
  171.     u.u_base++;
  172.     return(c&0377);
  173. }
  174.  
  175. /*
  176.  * Routine which sets a user error; placed in
  177.  * illegal entries in the bdevsw and cdevsw tables.
  178.  */
  179. nodev()
  180. {
  181.  
  182.     u.u_error = ENODEV;
  183. }
  184.  
  185. /*
  186.  * Null routine; placed in insignificant entries
  187.  * in the bdevsw and cdevsw tables.
  188.  */
  189. nulldev()
  190. {
  191. }
  192.  
  193. /*
  194.  * copy count words from from to to.
  195.  */
  196. bcopy(from, to, count)
  197. int *from, *to;
  198. {
  199.     register *a, *b, c;
  200.  
  201.     a = from;
  202.     b = to;
  203.     c = count;
  204.     do
  205.         *b++ = *a++;
  206.     while(--c);
  207. }
  208.