URI:
       tdisk.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tdisk.c (2124B)
       ---
            1 #include "sam.h"
            2 
            3 static        Block        *blist;
            4 
            5 #if 0
            6 static int
            7 tempdisk(void)
            8 {
            9         char buf[128];
           10         int i, fd;
           11 
           12         snprint(buf, sizeof buf, "/tmp/X%d.%.4ssam", getpid(), getuser());
           13         for(i='A'; i<='Z'; i++){
           14                 buf[5] = i;
           15                 if(access(buf, AEXIST) == 0)
           16                         continue;
           17                 fd = create(buf, ORDWR|ORCLOSE|OCEXEC, 0600);
           18                 if(fd >= 0)
           19                         return fd;
           20         }
           21         return -1;
           22 }
           23 #else
           24 extern int tempdisk(void);
           25 #endif
           26 
           27 Disk*
           28 diskinit(void)
           29 {
           30         Disk *d;
           31 
           32         d = emalloc(sizeof(Disk));
           33         d->fd = tempdisk();
           34         if(d->fd < 0){
           35                 fprint(2, "sam: can't create temp file: %r\n");
           36                 exits("diskinit");
           37         }
           38         return d;
           39 }
           40 
           41 static
           42 uint
           43 ntosize(uint n, uint *ip)
           44 {
           45         uint size;
           46 
           47         if(n > Maxblock)
           48                 panic("internal error: ntosize");
           49         size = n;
           50         if(size & (Blockincr-1))
           51                 size += Blockincr - (size & (Blockincr-1));
           52         /* last bucket holds blocks of exactly Maxblock */
           53         if(ip)
           54                 *ip = size/Blockincr;
           55         return size * sizeof(Rune);
           56 }
           57 
           58 Block*
           59 disknewblock(Disk *d, uint n)
           60 {
           61         uint i, j, size;
           62         Block *b;
           63 
           64         size = ntosize(n, &i);
           65         b = d->free[i];
           66         if(b)
           67                 d->free[i] = b->u.next;
           68         else{
           69                 /* allocate in chunks to reduce malloc overhead */
           70                 if(blist == nil){
           71                         blist = emalloc(100*sizeof(Block));
           72                         for(j=0; j<100-1; j++)
           73                                 blist[j].u.next = &blist[j+1];
           74                 }
           75                 b = blist;
           76                 blist = b->u.next;
           77                 b->addr = d->addr;
           78                 if(d->addr+size < d->addr){
           79                         panic("temp file overflow");
           80                 }
           81                 d->addr += size;
           82         }
           83         b->u.n = n;
           84         return b;
           85 }
           86 
           87 void
           88 diskrelease(Disk *d, Block *b)
           89 {
           90         uint i;
           91 
           92         ntosize(b->u.n, &i);
           93         b->u.next = d->free[i];
           94         d->free[i] = b;
           95 }
           96 
           97 void
           98 diskwrite(Disk *d, Block **bp, Rune *r, uint n)
           99 {
          100         int size, nsize;
          101         Block *b;
          102 
          103         b = *bp;
          104         size = ntosize(b->u.n, nil);
          105         nsize = ntosize(n, nil);
          106         if(size != nsize){
          107                 diskrelease(d, b);
          108                 b = disknewblock(d, n);
          109                 *bp = b;
          110         }
          111         if(pwrite(d->fd, r, n*sizeof(Rune), b->addr) != n*sizeof(Rune))
          112                 panic("write error to temp file");
          113         b->u.n = n;
          114 }
          115 
          116 void
          117 diskread(Disk *d, Block *b, Rune *r, uint n)
          118 {
          119         if(n > b->u.n)
          120                 panic("internal error: diskread");
          121 
          122         ntosize(b->u.n, nil);        /* called only for sanity check on Maxblock */
          123         if(pread(d->fd, r, n*sizeof(Rune), b->addr) != n*sizeof(Rune))
          124                 panic("read error from temp file");
          125 }