diff options
| author | rsc <devnull@localhost> | 2003-12-11 17:50:28 +0000 |
|---|---|---|
| committer | rsc <devnull@localhost> | 2003-12-11 17:50:28 +0000 |
| commit | b3994ec5c78e6c18885079b58abb7fb997899c3f (patch) | |
| tree | d4ead391f5ebd1554cc5ecfba69130e750de67bb /src/cmd/acme/disk.c | |
| parent | 32f69c36e0eec1227934bbd34854bfebd88686f2 (diff) | |
| download | plan9port-b3994ec5c78e6c18885079b58abb7fb997899c3f.tar.gz plan9port-b3994ec5c78e6c18885079b58abb7fb997899c3f.zip | |
More files related to user-level file servers.
Also add acme!
Diffstat (limited to 'src/cmd/acme/disk.c')
| -rw-r--r-- | src/cmd/acme/disk.c | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/src/cmd/acme/disk.c b/src/cmd/acme/disk.c new file mode 100644 index 00000000..857d9329 --- /dev/null +++ b/src/cmd/acme/disk.c @@ -0,0 +1,129 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <thread.h> +#include <cursor.h> +#include <mouse.h> +#include <keyboard.h> +#include <frame.h> +#include <fcall.h> +#include <plumb.h> +#include "dat.h" +#include "fns.h" + +static Block *blist; + +int +tempfile(void) +{ + char buf[128]; + int i, fd; + + snprint(buf, sizeof buf, "/tmp/X%d.%.4sacme", getpid(), getuser()); + for(i='A'; i<='Z'; i++){ + buf[5] = i; + if(access(buf, AEXIST) == 0) + continue; + fd = create(buf, ORDWR|ORCLOSE|OCEXEC, 0600); + if(fd >= 0) + return fd; + } + return -1; +} + +Disk* +diskinit() +{ + Disk *d; + + d = emalloc(sizeof(Disk)); + d->fd = tempfile(); + if(d->fd < 0){ + fprint(2, "acme: can't create temp file: %r\n"); + threadexitsall("diskinit"); + } + return d; +} + +static +uint +ntosize(uint n, uint *ip) +{ + uint size; + + if(n > Maxblock) + error("internal error: ntosize"); + size = n; + if(size & (Blockincr-1)) + size += Blockincr - (size & (Blockincr-1)); + /* last bucket holds blocks of exactly Maxblock */ + if(ip) + *ip = size/Blockincr; + return size * sizeof(Rune); +} + +Block* +disknewblock(Disk *d, uint n) +{ + uint i, j, size; + Block *b; + + size = ntosize(n, &i); + b = d->free[i]; + if(b) + d->free[i] = b->u.next; + else{ + /* allocate in chunks to reduce malloc overhead */ + if(blist == nil){ + blist = emalloc(100*sizeof(Block)); + for(j=0; j<100-1; j++) + blist[j].u.next = &blist[j+1]; + } + b = blist; + blist = b->u.next; + b->addr = d->addr; + d->addr += size; + } + b->u.n = n; + return b; +} + +void +diskrelease(Disk *d, Block *b) +{ + uint i; + + ntosize(b->u.n, &i); + b->u.next = d->free[i]; + d->free[i] = b; +} + +void +diskwrite(Disk *d, Block **bp, Rune *r, uint n) +{ + int size, nsize; + Block *b; + + b = *bp; + size = ntosize(b->u.n, nil); + nsize = ntosize(n, nil); + if(size != nsize){ + diskrelease(d, b); + b = disknewblock(d, n); + *bp = b; + } + if(pwrite(d->fd, r, n*sizeof(Rune), b->addr) != n*sizeof(Rune)) + error("write error to temp file"); + b->u.n = n; +} + +void +diskread(Disk *d, Block *b, Rune *r, uint n) +{ + if(n > b->u.n) + error("internal error: diskread"); + + ntosize(b->u.n, nil); + if(pread(d->fd, r, n*sizeof(Rune), b->addr) != n*sizeof(Rune)) + error("read error from temp file"); +} |
