disk.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
disk.c (2058B) | |
--- | |
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 … | |
120 if(pread(d->fd, r, n*sizeof(Rune), b->addr) != n*sizeof(Rune)) | |
121 panic("read error from temp file"); | |
122 } |