tdisk.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
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 … | |
123 if(pread(d->fd, r, n*sizeof(Rune), b->addr) != n*sizeof(Rune)) | |
124 panic("read error from temp file"); | |
125 } |