BSD 4_3_Tahoe development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Tue, 8 Jun 1982 13:12:23 +0000 (05:12 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Tue, 8 Jun 1982 13:12:23 +0000 (05:12 -0800)
Work on file usr/src/undoc/brktest.c
Work on file usr/src/undoc/copyout.c

Synthesized-from: CSRG/cd2/4.3tahoe

usr/src/undoc/brktest.c [new file with mode: 0644]
usr/src/undoc/copyout.c [new file with mode: 0644]

diff --git a/usr/src/undoc/brktest.c b/usr/src/undoc/brktest.c
new file mode 100644 (file)
index 0000000..649984a
--- /dev/null
@@ -0,0 +1,27 @@
+       int     a[1000];
+
+main()
+{
+       int     asize = 1000,i,inc = 0,new;
+
+       srand(1);
+       for (i = 0 ; i < asize ; i++)
+               a[i] = i;
+       while (1)  {
+               new = rand() % 4000;
+               if (((rand() % 1000) > 750) && ((asize - new) > 1000))
+                       new = -new;
+               for (i = 0 ;  i < asize ; i++ )
+                       if (a[i] != i)
+                               printf("bad a %x\n",i);
+                       if (sbrk(4 * new) != -1)  {
+                               if (new > 0)  {
+                                       for (i = 0 ; i < new ; i++)
+                                               a[asize + i] = asize + i;  }
+                               asize += new;  }
+                       else  {
+                               new = 1000 - asize;
+                               sbrk(4 * new);
+                               asize += new;  }
+               sleep((rand() % 4) + 1);  }
+}
diff --git a/usr/src/undoc/copyout.c b/usr/src/undoc/copyout.c
new file mode 100644 (file)
index 0000000..d58ecc3
--- /dev/null
@@ -0,0 +1,229 @@
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+#include <sys/vm.h>
+#include <sys/proc.h>
+#include <sys/pte.h>
+#include <sys/cmap.h>
+#include <sys/inode.h>
+#include <sys/buf.h>
+#include <sys/text.h>
+#include <sys/ino.h>
+
+struct buf *bread();
+struct buf b;
+char   bc[BSIZE];
+int    bflag;
+
+main(argc, argv)
+       char *argv[];
+{
+       struct dinode di;
+       struct inode i;
+       struct proc p;
+       struct user u;
+       struct text x;
+       struct pte *pte;
+       int j,k,l;
+
+       if (argc > 1 && !strcmp(argv[1], "-b"))
+               argc--, argv++, bflag++;
+       if (argc != 3) {
+               fprintf(stderr, "usage: copyout [ -b ] inum disk\n");
+               exit(1);
+       }
+       close(0);
+       if (open(argv[2], 0) != 0) {
+               perror(argv[2]);
+               exit(1);
+       }
+       lseek(0, itod(atoi(argv[1])) * BSIZE + itoo(atoi(argv[1])) * sizeof (di), 0);
+       if (read(0, &di, sizeof (di)) != sizeof (di)) {
+               fprintf(stderr, "error reading inode ");
+               perror(argv[1]);
+               exit(1);
+       }
+       i.i_dev = 0;
+       i.i_number = atoi(argv[1]);
+       i.i_flag = ILOCK;
+       i.i_count = 1;
+       i.i_un.i_lastr = 0;
+       i.i_mode = di.di_mode;
+       i.i_nlink = di.di_nlink;
+       i.i_uid = di.di_uid;
+       i.i_size = di.di_size;
+       l3tol(i.i_un.i_addr, di.di_addr, NADDR);
+       p.p_textp = &x;
+       x.x_iptr = &i;
+       b.b_un.b_addr = bc;
+       pte = (struct pte *)calloc(btoc(i.i_size), sizeof (struct pte));
+       if (pte == NULL) {
+               fprintf(stderr, "Not enough core for block pointers\n");
+               exit(1);
+       }
+       vinizfod(&p, pte, 0, (btoc(i.i_size)+(CLSIZE-1)) / CLSIZE);
+       l = i.i_size;
+       for (j = 0; j < (btoc(i.i_size)+(CLSIZE-1)) / CLSIZE; j++)
+               if (bflag)
+                       printf("#%d: block %d\n", j, pte[j].pg_pfnum);
+               else {
+                       k = imin(l, BSIZE);
+                       write(1, bread(0, pte[j].pg_pfnum)->b_un.b_words, k);
+                       brelse(&b);
+                       l -= BSIZE;
+               }
+       exit(0);
+}
+
+int    bused;
+
+struct buf *
+bread(dev, blk)
+{
+
+       if (bused)
+               abort();
+       bused = 1;
+       printf("getblk %x\n", blk);
+       lseek(0, blk * BSIZE, 0);
+       if (read(0, b.b_un.b_addr, BSIZE) != BSIZE) {
+               printf("block %d: ", blk);
+               perror("bread");
+       }
+       return (&b);
+}
+
+brelse(bp)
+struct buf *bp;
+{
+
+       if (bp != &b)
+               abort();
+       bused = 0;
+}
+
+struct buf *vbmap();
+/*
+ * Initialize the page tables for paging from an inode,
+ * by scouring up the indirect blocks in order.
+ */
+vinizfod(p, pte, bstart, count)
+       struct proc *p;
+       register struct pte *pte;
+       daddr_t bstart;
+       int count;
+{
+       register struct inode *ip = p->p_textp->x_iptr;
+       register int i;
+       struct buf *bp;
+       int indx;
+       register daddr_t *pp;
+
+       while (count > 0) {
+               if (bstart < NADDR - 3) {
+                       pte++->pg_pfnum = ip->i_un.i_addr[bstart];
+                       bstart++;
+                       count--;
+               } else {
+                       bp = vbmap(ip, bstart);
+                       indx = (bstart - (NADDR - 3)) % NINDIR;
+                       i = imin(NINDIR - indx, count);
+                       bstart += i;
+                       count -= i;
+                       if (bp) {
+                               pp = &bp->b_un.b_daddr[indx];
+                               do
+                                       pte++->pg_pfnum = *pp++;
+                               while (--i > 0);
+                               brelse(bp);
+                       } else
+                               pte += i;
+               }
+       }
+}
+
+/*
+ * Vbmap returns a block full of indirect pointers for a given block offset
+ * in a file.  It returns 0 if a missing address block was encountered,
+ * in which case the pages can be normal zfod pages.
+ */
+struct buf *
+vbmap(ip, bn)
+register struct inode *ip;
+daddr_t bn;
+{
+       register i;
+       struct buf *bp;
+       int j, sh;
+       daddr_t nb;
+       dev_t dev = ip->i_dev;
+
+       if (bn < NADDR-3)
+               panic("vbmap");
+
+       /*
+        * 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)
+               goto noblk;
+
+       /*
+        * fetch the address from the inode
+        */
+       nb = ip->i_un.i_addr[NADDR-j];
+
+       /*
+        * fetch through the indirect blocks
+        */
+       for (;;) {
+               if (nb == 0)
+                       return ((daddr_t)0);
+               bp = bread(dev, nb);
+               if (bp->b_flags & B_ERROR) {
+                       brelse(bp);
+                       goto noblk;
+               }
+               if (j == 3)
+                       break;
+               j++;
+               sh -= NSHIFT;
+               i = (bn>>sh) & NMASK;
+               nb = bp->b_un.b_daddr[i];
+               brelse(bp);
+               if (nb == 0)
+                       goto noblk;
+       }
+       return (bp);
+
+noblk:
+       return ((struct buf *)0);
+}
+
+imin(a,b)
+{
+       return (a<b?a:b);
+}
+
+panic(cp)
+{
+       printf(cp);
+       abort();
+}
+
+char vmmap[1];
+char version[1];