diff options
author | cinap_lenrek <cinap_lenrek@localhost> | 2011-04-18 06:35:33 +0000 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@localhost> | 2011-04-18 06:35:33 +0000 |
commit | ad5522be0fbfcad7b47bb9baca9a44dadb4b6461 (patch) | |
tree | 4e5622e0b5d1d0037406ac345d2a91e2c11e1bfc /sys/src/cmd/fossil/disk.c | |
parent | a455c61024cab80bfc50c898d8686068cd8ea06a (diff) |
remove fossil
Diffstat (limited to 'sys/src/cmd/fossil/disk.c')
-rw-r--r-- | sys/src/cmd/fossil/disk.c | 406 |
1 files changed, 0 insertions, 406 deletions
diff --git a/sys/src/cmd/fossil/disk.c b/sys/src/cmd/fossil/disk.c deleted file mode 100644 index 3ae43fb6d..000000000 --- a/sys/src/cmd/fossil/disk.c +++ /dev/null @@ -1,406 +0,0 @@ -#include "stdinc.h" -#include "dat.h" -#include "fns.h" -#include "error.h" - -static void diskThread(void *a); - -enum { - /* - * disable measurement since it gets alignment faults on BG - * and the guts used to be commented out. - */ - Timing = 0, /* flag */ - QueueSize = 100, /* maximum block to queue */ -}; - -struct Disk { - VtLock *lk; - int ref; - - int fd; - Header h; - - VtRendez *flow; - VtRendez *starve; - VtRendez *flush; - VtRendez *die; - - int nqueue; - - Block *cur; /* block to do on current scan */ - Block *next; /* blocks to do next scan */ -}; - -/* keep in sync with Part* enum in dat.h */ -static char *partname[] = { - [PartError] "error", - [PartSuper] "super", - [PartLabel] "label", - [PartData] "data", - [PartVenti] "venti", -}; - -Disk * -diskAlloc(int fd) -{ - u8int buf[HeaderSize]; - Header h; - Disk *disk; - - if(pread(fd, buf, HeaderSize, HeaderOffset) < HeaderSize){ - vtSetError("short read: %r"); - vtOSError(); - return nil; - } - - if(!headerUnpack(&h, buf)){ - vtSetError("bad disk header"); - return nil; - } - disk = vtMemAllocZ(sizeof(Disk)); - disk->lk = vtLockAlloc(); - disk->starve = vtRendezAlloc(disk->lk); - disk->flow = vtRendezAlloc(disk->lk); - disk->flush = vtRendezAlloc(disk->lk); - disk->fd = fd; - disk->h = h; - - disk->ref = 2; - vtThread(diskThread, disk); - - return disk; -} - -void -diskFree(Disk *disk) -{ - diskFlush(disk); - - /* kill slave */ - vtLock(disk->lk); - disk->die = vtRendezAlloc(disk->lk); - vtWakeup(disk->starve); - while(disk->ref > 1) - vtSleep(disk->die); - vtUnlock(disk->lk); - vtRendezFree(disk->flow); - vtRendezFree(disk->starve); - vtRendezFree(disk->die); - vtLockFree(disk->lk); - close(disk->fd); - vtMemFree(disk); -} - -static u32int -partStart(Disk *disk, int part) -{ - switch(part){ - default: - assert(0); - case PartSuper: - return disk->h.super; - case PartLabel: - return disk->h.label; - case PartData: - return disk->h.data; - } -} - - -static u32int -partEnd(Disk *disk, int part) -{ - switch(part){ - default: - assert(0); - case PartSuper: - return disk->h.super+1; - case PartLabel: - return disk->h.data; - case PartData: - return disk->h.end; - } -} - -int -diskReadRaw(Disk *disk, int part, u32int addr, uchar *buf) -{ - ulong start, end; - u64int offset; - int n, nn; - - start = partStart(disk, part); - end = partEnd(disk, part); - - if(addr >= end-start){ - vtSetError(EBadAddr); - return 0; - } - - offset = ((u64int)(addr + start))*disk->h.blockSize; - n = disk->h.blockSize; - while(n > 0){ - nn = pread(disk->fd, buf, n, offset); - if(nn < 0){ - vtOSError(); - return 0; - } - if(nn == 0){ - vtSetError("eof reading disk"); - return 0; - } - n -= nn; - offset += nn; - buf += nn; - } - return 1; -} - -int -diskWriteRaw(Disk *disk, int part, u32int addr, uchar *buf) -{ - ulong start, end; - u64int offset; - int n; - - start = partStart(disk, part); - end = partEnd(disk, part); - - if(addr >= end - start){ - vtSetError(EBadAddr); - return 0; - } - - offset = ((u64int)(addr + start))*disk->h.blockSize; - n = pwrite(disk->fd, buf, disk->h.blockSize, offset); - if(n < 0){ - vtOSError(); - return 0; - } - if(n < disk->h.blockSize) { - vtSetError("short write"); - return 0; - } - - return 1; -} - -static void -diskQueue(Disk *disk, Block *b) -{ - Block **bp, *bb; - - vtLock(disk->lk); - while(disk->nqueue >= QueueSize) - vtSleep(disk->flow); - if(disk->cur == nil || b->addr > disk->cur->addr) - bp = &disk->cur; - else - bp = &disk->next; - - for(bb=*bp; bb; bb=*bp){ - if(b->addr < bb->addr) - break; - bp = &bb->ionext; - } - b->ionext = bb; - *bp = b; - if(disk->nqueue == 0) - vtWakeup(disk->starve); - disk->nqueue++; - vtUnlock(disk->lk); -} - - -void -diskRead(Disk *disk, Block *b) -{ - assert(b->iostate == BioEmpty || b->iostate == BioLabel); - blockSetIOState(b, BioReading); - diskQueue(disk, b); -} - -void -diskWrite(Disk *disk, Block *b) -{ - assert(b->nlock == 1); - assert(b->iostate == BioDirty); - blockSetIOState(b, BioWriting); - diskQueue(disk, b); -} - -void -diskWriteAndWait(Disk *disk, Block *b) -{ - int nlock; - - /* - * If b->nlock > 1, the block is aliased within - * a single thread. That thread is us. - * DiskWrite does some funny stuff with VtLock - * and blockPut that basically assumes b->nlock==1. - * We humor diskWrite by temporarily setting - * nlock to 1. This needs to be revisited. - */ - nlock = b->nlock; - if(nlock > 1) - b->nlock = 1; - diskWrite(disk, b); - while(b->iostate != BioClean) - vtSleep(b->ioready); - b->nlock = nlock; -} - -int -diskBlockSize(Disk *disk) -{ - return disk->h.blockSize; /* immuttable */ -} - -int -diskFlush(Disk *disk) -{ - Dir dir; - - vtLock(disk->lk); - while(disk->nqueue > 0) - vtSleep(disk->flush); - vtUnlock(disk->lk); - - /* there really should be a cleaner interface to flush an fd */ - nulldir(&dir); - if(dirfwstat(disk->fd, &dir) < 0){ - vtOSError(); - return 0; - } - return 1; -} - -u32int -diskSize(Disk *disk, int part) -{ - return partEnd(disk, part) - partStart(disk, part); -} - -static uintptr -mypc(int x) -{ - return getcallerpc(&x); -} - -static char * -disk2file(Disk *disk) -{ - static char buf[256]; - - if (fd2path(disk->fd, buf, sizeof buf) < 0) - strncpy(buf, "GOK", sizeof buf); - return buf; -} - -static void -diskThread(void *a) -{ - Disk *disk = a; - Block *b; - uchar *buf, *p; - double t; - int nio; - - vtThreadSetName("disk"); - -//fprint(2, "diskThread %d\n", getpid()); - - buf = vtMemAlloc(disk->h.blockSize); - - vtLock(disk->lk); - if (Timing) { - nio = 0; - t = -nsec(); - } - for(;;){ - while(disk->nqueue == 0){ - if (Timing) { - t += nsec(); - if(nio >= 10000){ - fprint(2, "disk: io=%d at %.3fms\n", - nio, t*1e-6/nio); - nio = 0; - t = 0; - } - } - if(disk->die != nil) - goto Done; - vtSleep(disk->starve); - if (Timing) - t -= nsec(); - } - assert(disk->cur != nil || disk->next != nil); - - if(disk->cur == nil){ - disk->cur = disk->next; - disk->next = nil; - } - b = disk->cur; - disk->cur = b->ionext; - vtUnlock(disk->lk); - - /* - * no one should hold onto blocking in the - * reading or writing state, so this lock should - * not cause deadlock. - */ -if(0)fprint(2, "fossil: diskThread: %d:%d %x\n", getpid(), b->part, b->addr); - bwatchLock(b); - vtLock(b->lk); - b->pc = mypc(0); - assert(b->nlock == 1); - switch(b->iostate){ - default: - abort(); - case BioReading: - if(!diskReadRaw(disk, b->part, b->addr, b->data)){ - fprint(2, "fossil: diskReadRaw failed: %s: " - "score %V: part=%s block %ud: %r\n", - disk2file(disk), b->score, - partname[b->part], b->addr); - blockSetIOState(b, BioReadError); - }else - blockSetIOState(b, BioClean); - break; - case BioWriting: - p = blockRollback(b, buf); - /* NB: ctime result ends with a newline */ - if(!diskWriteRaw(disk, b->part, b->addr, p)){ - fprint(2, "fossil: diskWriteRaw failed: %s: " - "score %V: date %s part=%s block %ud: %r\n", - disk2file(disk), b->score, - ctime(time(0)), - partname[b->part], b->addr); - break; - } - if(p != buf) - blockSetIOState(b, BioClean); - else - blockSetIOState(b, BioDirty); - break; - } - - blockPut(b); /* remove extra reference, unlock */ - vtLock(disk->lk); - disk->nqueue--; - if(disk->nqueue == QueueSize-1) - vtWakeup(disk->flow); - if(disk->nqueue == 0) - vtWakeup(disk->flush); - if(Timing) - nio++; - } -Done: -//fprint(2, "diskThread done\n"); - disk->ref--; - vtWakeup(disk->die); - vtUnlock(disk->lk); - vtMemFree(buf); -} |