-/* subr_xxx.c 4.7 81/03/11 */
+/* subr_xxx.c 4.21 82/12/17 */
+
+#include "../machine/pte.h"
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/user.h"
#include "../h/buf.h"
#include "../h/proc.h"
+#include "../h/fs.h"
+#include "../h/vm.h"
+#include "../h/cmap.h"
+#include "../h/uio.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.
+ * Routine placed in illegal entries in the bdevsw and cdevsw tables.
*/
-daddr_t
-bmap(ip, bn, rwflg)
-register struct inode *ip;
-daddr_t bn;
+nodev()
{
- register i;
- struct buf *bp, *nbp;
- int j, sh;
- daddr_t nb, *bap;
- dev_t dev;
-
- if(bn < 0) {
- u.u_error = EFBIG;
- return((daddr_t)0);
- }
- dev = ip->i_dev;
- rablock = 0;
-
- /*
- * blocks 0..NADDR-4 are direct blocks
- */
- if(bn < NADDR-3) {
- i = bn;
- nb = ip->i_un.i_addr[i];
- if(nb == 0) {
- if(rwflg==B_READ || (bp = alloc(dev))==NULL)
- return((daddr_t)-1);
- nb = dbtofsb(bp->b_blkno);
- if ((ip->i_mode&IFMT) == IFDIR)
- /*
- * Write directory blocks synchronously
- * so they never appear with garbage in
- * them on the disk.
- */
- bwrite(bp);
- else
- bdwrite(bp);
- ip->i_un.i_addr[i] = nb;
- ip->i_flag |= IUPD|ICHG;
- }
- if(i < NADDR-4)
- rablock = ip->i_un.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);
- }
+ return (ENODEV);
+}
- /*
- * fetch the first indirect block
- */
- nb = ip->i_un.i_addr[NADDR-j];
- if(nb == 0) {
- if(rwflg==B_READ || (bp = alloc(dev))==NULL)
- return((daddr_t)-1);
- nb = dbtofsb(bp->b_blkno);
- /*
- * Write synchronously so that indirect blocks
- * never point at garbage.
- */
- bwrite(bp);
- ip->i_un.i_addr[NADDR-j] = nb;
- ip->i_flag |= IUPD|ICHG;
- }
+/*
+ * Null routine; placed in insignificant entries
+ * in the bdevsw and cdevsw tables.
+ */
+nulldev()
+{
- /*
- * 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 = dbtofsb(nbp->b_blkno);
- if (j < 3 || (ip->i_mode&IFMT) == IFDIR)
- /*
- * Write synchronously so indirect blocks
- * never point at garbage and blocks
- * in directories never contain garbage.
- */
- bwrite(nbp);
- else
- bdwrite(nbp);
- bap[i] = nb;
- bdwrite(bp);
- } else
- brelse(bp);
- }
+ return (0);
+}
- /*
- * calculate read-ahead.
- */
- if(i < NINDIR-1)
- rablock = bap[i+1];
- return(nb);
+imin(a, b)
+{
+
+ return (a < b ? a : b);
}
-/*
- * 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;
+imax(a, b)
{
- 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);
+
+ return (a > b ? a : b);
}
-#include "ct.h"
-#if NCT > 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()
+unsigned
+min(a, b)
+ u_int a, b;
{
- 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);
+
+ return (a < b ? a : b);
}
-#endif
-/*
- * Routine which sets a user error; placed in
- * illegal entries in the bdevsw and cdevsw tables.
- */
-nodev()
+unsigned
+max(a, b)
+ u_int a, b;
{
- u.u_error = ENODEV;
+ return (a > b ? a : b);
}
+extern cabase, calimit;
+extern struct pte camap[];
+
+caddr_t cacur = (caddr_t)&cabase;
+caddr_t camax = (caddr_t)&cabase;
+int cax = 0;
/*
- * Null routine; placed in insignificant entries
- * in the bdevsw and cdevsw tables.
+ * This is a kernel-mode storage allocator.
+ * It is very primitive, currently, in that
+ * there is no way to give space back.
+ * It serves, for the time being, the needs of
+ * auto-configuration code and the like which
+ * need to allocate some stuff at boot time.
*/
-nulldev()
+caddr_t
+calloc(size)
+ int size;
+{
+ register caddr_t res;
+ register int i;
+
+ if (cacur+size >= (caddr_t)&calimit)
+ panic("calloc");
+ while (cacur+size > camax) {
+ (void) vmemall(&camap[cax], CLSIZE, &proc[0], CSYS);
+ vmaccess(&camap[cax], camax, CLSIZE);
+ for (i = 0; i < CLSIZE; i++)
+ clearseg(camap[cax++].pg_pfnum);
+ camax += NBPG * CLSIZE;
+ }
+ res = cacur;
+ cacur += size;
+ return (res);
+}
+
+#ifndef vax
+ffs(mask)
+ register long mask;
{
+ register int i;
+ for(i=1; i<NSIG; i++) {
+ if (mask & 1)
+ return (i);
+ mask >>= 1;
+ }
+ return (0);
}
-imin(a, b)
+bcmp(s1, s2, len)
+ register char *s1, *s2;
+ register int len;
{
- return (a < b ? a : b);
+ while (len--)
+ if (*s1++ != *s2++)
+ return (1);
+ return (0);
}
-imax(a, b)
+strlen(s1)
+ register char *s1;
{
+ register int len;
- return (a > b ? a : b);
+ for (len = 0; *s1++ != '\0'; len++)
+ /* void */;
+ return (len);
}
+#endif
-struct proc *
-pfind(pid)
- int pid;
+/*
+ * Pass back c to the user.
+ */
+passuc(c, uio)
+ register c;
+ struct uio *uio;
{
- register struct proc *p;
+ register struct iovec *iov = uio->uio_iov;
+
+ switch (uio->uio_segflg) {
+
+ case 0:
+ if (subyte(iov->iov_base, c) < 0)
+ goto fault;
+ break;
- for (p = &proc[pidhash[PIDHASH(pid)]]; p != &proc[0]; p = &proc[p->p_idhash])
- if (p->p_pid == pid)
- return (p);
- return ((struct proc *)0);
+ case 1:
+ *iov->iov_base = c;
+ break;
+
+ case 2:
+ if (suibyte(iov->iov_base, c) < 0)
+ goto fault;
+ break;
+ }
+ iov->iov_base++;
+ iov->iov_len--;
+ uio->uio_resid--;
+ uio->uio_offset++;
+ if (iov->iov_len <= 0) {
+ uio->uio_iov++;
+ uio->uio_iovcnt--;
+ }
+ return (0);
+fault:
+ return (EFAULT);
}