diff --git a/WEGA/src/uts/sys/subr.c b/WEGA/src/uts/sys/subr.c new file mode 100644 index 0000000..b796fce --- /dev/null +++ b/WEGA/src/uts/sys/subr.c @@ -0,0 +1,250 @@ +/****************************************************************************** +******************************************************************************* + + W E G A - Quelle + + KERN 3.2 Modul: sysent.c + + + Bearbeiter: O. Lehmann + Datum: 09.05.08 + Version: 1.0 + +******************************************************************************* +******************************************************************************/ + +char subrwstr[] = "@[$]subr.c Rev : 4.1 08/27/83 11:58:09"; + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * 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. + */ +daddr_t +bmap(ip, bn, rwflg) +register struct inode *ip; +daddr_t bn; +{ + register int i; + register struct buf *bp; + struct buf *nbp; + register int j; + int sh; + daddr_t nb, *bap; + dev_t dev; + + dev = ip->i_dev; + rablock = 0; + + /* + * blocks 0..NADDR-4 are direct blocks + */ + + if(bn < NADDR-3) { + i = bn; + nb = ip->i_addr[i]; + if(nb == 0) { + if(rwflg==B_READ || (bp = alloc(dev))==NULL) + return((daddr_t)-1); + nb = bp->b_blkno; + bdwrite(bp); + ip->i_addr[i] = nb; + ip->i_flag |= IUPD|ICHG; + } + if(i < NADDR-4) + rablock = ip->i_addr[i+1]; + return(nb); + } + + /* + * addresses NADDR-3, NADDR-2, and NADDR-1 + * have single, double, triple indirect blocks. + * the first step is to determine + * how many levels of indirection. + */ + sh = 0; + nb = 1; + bn -= NADDR-3; + for(j=3; j>0; j--) { + sh += NSHIFT; + nb <<= NSHIFT; + if(bn < nb) + break; + bn -= nb; + } + if(j == 0) { + u.u_error = EFBIG; + return((daddr_t)0); + } + + /* + * fetch the address from the inode + */ + nb = ip->i_addr[NADDR-j]; + if(nb == 0) { + if(rwflg==B_READ || (bp = alloc(dev))==NULL) + return((daddr_t)-1); + nb = bp->b_blkno; + bdwrite(bp); + ip->i_addr[NADDR-j] = nb; + ip->i_flag |= IUPD|ICHG; + } + + /* + * fetch through the indirect blocks + */ + for(; j<=3; j++) { + bp = bread(dev, nb); + if(bp->b_flags & B_ERROR) { + brelse(bp); + return((daddr_t)0); + } + bap = bp->b_un.b_daddr; + sh -= NSHIFT; + i = (bn>>sh) & NMASK; + nb = bap[i]; + if(nb == 0) { + if(rwflg==B_READ || (nbp = alloc(dev))==NULL) { + brelse(bp); + return((daddr_t)-1); + } + nb = nbp->b_blkno; + bdwrite(nbp); + bap[i] = nb; + bdwrite(bp); + } else + brelse(bp); + } + + /* + * calculate read-ahead. + */ + if(i < NINDIR-1) + rablock = bap[i+1]; + return(nb); +} + +/* + * 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, id; + + if(u.u_count == 0) + return(-1); + if((id = u.u_segflg) == 1) + c = *u.u_base; + else + if((c = id==0?fubyte(u.u_base):fuibyte(u.u_base)) < 0) { + u.u_error = EFAULT; + return(-1); + } + u.u_count--; + u.u_offset++; + 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() +{ +} + +/* + * 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) +register c; +{ + register id; + + if((id = u.u_segflg) == 1) + *u.u_base = c; + else + if(id?suibyte(u.u_base, c):subyte(u.u_base, c) < 0) { + u.u_error = EFAULT; + return(-1); + } + u.u_count--; + u.u_offset++; + u.u_base++; + return(u.u_count == 0? -1: 0); +} + +/* + * timeout is called to arrange that fun(arg) is called in tim/HZ seconds. + * An entry is sorted into the callout structure. + * The time in each structure entry is the number of HZ's more + * than the previous entry. In this way, decrementing the + * first entry has the effect of updating all entries. + * + * The panic is there because there is nothing + * intelligent to be done if an entry won't fit. + */ +timeout(fun, arg, tim) +int (*fun)(); +caddr_t arg; +{ + register struct callo *p1, *p2; + register int t; + int s; + + t = tim; + p1 = &callout[0]; + s = dvi(); + while(p1->c_func != 0 && p1->c_time <= t) { + t -= p1->c_time; + p1++; + } + if (p1 >= &callout[NCALL-1]) + panic("Timeout table overflow"); + p1->c_time -= t; + p2 = p1; + while(p2->c_func != 0) + p2++; + while(p2 >= p1) { + (p2+1)->c_time = p2->c_time; + (p2+1)->c_func = p2->c_func; + (p2+1)->c_arg = p2->c_arg; + p2--; + } + p1->c_time = t; + p1->c_func = fun; + p1->c_arg = arg; + rvi(s); +}