home *** CD-ROM | disk | FTP | other *** search
- #
- /*
- */
-
- #include "../param.h"
- #include "../conf.h"
- #include "../inode.h"
- #include "../user.h"
- #include "../buf.h"
- #include "../systm.h"
-
- /*
- * Bmap defines the structure of file system storage
- * by returning the physical block number on a device given the
- * inode and the logical block number in a file.
- * When convenient, it also leaves the physical
- * block number of the next block of the file in rablock
- * for use in read-ahead.
- */
- bmap(ip, bn)
- struct inode *ip;
- int bn;
- {
- register *bp, *bap, nb;
- int *nbp, d, i;
-
- d = ip->i_dev;
- if(bn & ~077777) {
- u.u_error = EFBIG;
- return(0);
- }
-
- if((ip->i_mode&ILARG) == 0) {
-
- /*
- * small file algorithm
- */
-
- if((bn & ~7) != 0) {
-
- /*
- * convert small to large
- */
-
- if ((bp = alloc(d)) == NULL)
- return(NULL);
- bap = bp->b_addr;
- for(i=0; i<8; i++) {
- *bap++ = ip->i_addr[i];
- ip->i_addr[i] = 0;
- }
- ip->i_addr[0] = bp->b_blkno;
- bdwrite(bp);
- ip->i_mode =| ILARG;
- goto large;
- }
- nb = ip->i_addr[bn];
- if(nb == 0 && (bp = alloc(d)) != NULL) {
- bdwrite(bp);
- nb = bp->b_blkno;
- ip->i_addr[bn] = nb;
- ip->i_flag =| IUPD;
- }
- rablock = 0;
- if (bn<7)
- rablock = ip->i_addr[bn+1];
- return(nb);
- }
-
- /*
- * large file algorithm
- */
-
- large:
- i = bn>>8;
- if(bn & 0174000)
- i = 7;
- if((nb=ip->i_addr[i]) == 0) {
- ip->i_flag =| IUPD;
- if ((bp = alloc(d)) == NULL)
- return(NULL);
- ip->i_addr[i] = bp->b_blkno;
- } else
- bp = bread(d, nb);
- bap = bp->b_addr;
-
- /*
- * "huge" fetch of double indirect block
- */
-
- if(i == 7) {
- i = ((bn>>8) & 0377) - 7;
- if((nb=bap[i]) == 0) {
- if((nbp = alloc(d)) == NULL) {
- brelse(bp);
- return(NULL);
- }
- bap[i] = nbp->b_blkno;
- bdwrite(bp);
- } else {
- brelse(bp);
- nbp = bread(d, nb);
- }
- bp = nbp;
- bap = bp->b_addr;
- }
-
- /*
- * normal indirect fetch
- */
-
- i = bn & 0377;
- if((nb=bap[i]) == 0 && (nbp = alloc(d)) != NULL) {
- nb = nbp->b_blkno;
- bap[i] = nb;
- bdwrite(nbp);
- bdwrite(bp);
- } else
- brelse(bp);
- rablock = 0;
- if(i < 255)
- rablock = bap[i+1];
- return(nb);
- }
-
- /*
- * Pass back c to the user at his location u_base;
- * update u_base, u_count, and u_offset. Return -1
- * on the last character of the user's read.
- * u_base is in the user address space unless u_segflg is set.
- */
- passc(c)
- char c;
- {
-
- if(u.u_segflg)
- *u.u_base = c; else
- if(subyte(u.u_base, c) < 0) {
- u.u_error = EFAULT;
- return(-1);
- }
- u.u_count--;
- if(++u.u_offset[1] == 0)
- u.u_offset[0]++;
- u.u_base++;
- return(u.u_count == 0? -1: 0);
- }
-
- /*
- * Pick up and return the next character from the user's
- * write call at location u_base;
- * update u_base, u_count, and u_offset. Return -1
- * when u_count is exhausted. u_base is in the user's
- * address space unless u_segflg is set.
- */
- cpass()
- {
- register c;
-
- if(u.u_count == 0)
- return(-1);
- if(u.u_segflg)
- c = *u.u_base; else
- if((c=fubyte(u.u_base)) < 0) {
- u.u_error = EFAULT;
- return(-1);
- }
- u.u_count--;
- if(++u.u_offset[1] == 0)
- u.u_offset[0]++;
- u.u_base++;
- return(c&0377);
- }
-
- /*
- * Routine which sets a user error; placed in
- * illegal entries in the bdevsw and cdevsw tables.
- */
- nodev()
- {
-
- u.u_error = ENODEV;
- }
-
- /*
- * Null routine; placed in insignificant entries
- * in the bdevsw and cdevsw tables.
- */
- nulldev()
- {
- }
-
- /*
- * copy count words from from to to.
- */
- bcopy(from, to, count)
- int *from, *to;
- {
- register *a, *b, c;
-
- a = from;
- b = to;
- c = count;
- do
- *b++ = *a++;
- while(--c);
- }
-