~ubuntu-branches/ubuntu/utopic/9base/utopic

« back to all changes in this revision

Viewing changes to sam/disk.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2010-06-04 17:22:03 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20100604172203-ei85j0da495sr8ut
Tags: 1:6-1
* Adding Kai as co-maintainer.
* Merging upstream version 6.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
                d->addr += size;
 
79
        }
 
80
        b->u.n = n;
 
81
        return b;
 
82
}
 
83
 
 
84
void
 
85
diskrelease(Disk *d, Block *b)
 
86
{
 
87
        uint i;
 
88
 
 
89
        ntosize(b->u.n, &i);
 
90
        b->u.next = d->free[i];
 
91
        d->free[i] = b;
 
92
}
 
93
 
 
94
void
 
95
diskwrite(Disk *d, Block **bp, Rune *r, uint n)
 
96
{
 
97
        int size, nsize;
 
98
        Block *b;
 
99
 
 
100
        b = *bp;
 
101
        size = ntosize(b->u.n, nil);
 
102
        nsize = ntosize(n, nil);
 
103
        if(size != nsize){
 
104
                diskrelease(d, b);
 
105
                b = disknewblock(d, n);
 
106
                *bp = b;
 
107
        }
 
108
        if(pwrite(d->fd, r, n*sizeof(Rune), b->addr) != n*sizeof(Rune))
 
109
                panic("write error to temp file");
 
110
        b->u.n = n;
 
111
}
 
112
 
 
113
void
 
114
diskread(Disk *d, Block *b, Rune *r, uint n)
 
115
{
 
116
        if(n > b->u.n)
 
117
                panic("internal error: diskread");
 
118
 
 
119
        ntosize(b->u.n, nil);   /* called only for sanity check on Maxblock */
 
120
        if(pread(d->fd, r, n*sizeof(Rune), b->addr) != n*sizeof(Rune))
 
121
                panic("read error from temp file");
 
122
}