123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- #include "stdinc.h"
- #include "dat.h"
- #include "fns.h"
- u32int maxBlockSize;
- int readonly;
- Part*
- initPart(char *name, int writable)
- {
- Part *part;
- Dir *dir;
- int how;
- part = MK(Part);
- part->name = estrdup(name);
- if(!writable && readonly)
- how = OREAD;
- else
- how = ORDWR;
- part->fd = open(name, how);
- if(part->fd < 0){
- if(how == ORDWR)
- part->fd = open(name, OREAD);
- if(part->fd < 0){
- freePart(part);
- setErr(EOk, "can't open partition='%s': %r", name);
- return nil;
- }
- fprint(2, "warning: %s opened for reading only\n", name);
- }
- dir = dirfstat(part->fd);
- if(dir == nil){
- freePart(part);
- setErr(EOk, "can't stat partition='%s': %r", name);
- return nil;
- }
- part->size = dir->length;
- part->blockSize = 0;
- free(dir);
- return part;
- }
- void
- freePart(Part *part)
- {
- if(part == nil)
- return;
- close(part->fd);
- free(part->name);
- free(part);
- }
- void
- partBlockSize(Part *part, u32int blockSize)
- {
- if(part->blockSize)
- fatal("resetting partition=%s's block size", part->name);
- part->blockSize = blockSize;
- if(blockSize > maxBlockSize)
- maxBlockSize = blockSize;
- }
- int
- writePart(Part *part, u64int addr, u8int *buf, u32int n)
- {
- long m, mm, nn;
- vtLock(stats.lock);
- stats.diskWrites++;
- stats.diskBWrites += n;
- vtUnlock(stats.lock);
- if(addr > part->size || addr + n > part->size){
- setErr(ECorrupt, "out of bounds write to partition='%s'", part->name);
- return 0;
- }
- for(nn = 0; nn < n; nn += m){
- mm = n - nn;
- if(mm > MaxIo)
- mm = MaxIo;
- m = pwrite(part->fd, &buf[nn], mm, addr + nn);
- if(m != mm){
- if(m < 0){
- setErr(EOk, "can't write partition='%s': %r", part->name);
- return 0;
- }
- logErr(EOk, "truncated write to partition='%s' n=%ld wrote=%ld", part->name, mm, m);
- }
- }
- return 1;
- }
- int
- readPart(Part *part, u64int addr, u8int *buf, u32int n)
- {
- long m, mm, nn;
- int i;
- vtLock(stats.lock);
- stats.diskReads++;
- stats.diskBReads += n;
- vtUnlock(stats.lock);
- if(addr > part->size || addr + n > part->size){
- setErr(ECorrupt, "out of bounds read from partition='%s': addr=%lld n=%d size=%lld", part->name, addr, n, part->size);
- return 0;
- }
- for(nn = 0; nn < n; nn += m){
- mm = n - nn;
- if(mm > MaxIo)
- mm = MaxIo;
- m = -1;
- for(i=0; i<4; i++) {
- m = pread(part->fd, &buf[nn], mm, addr + nn);
- if(m == mm)
- break;
- }
- if(m != mm){
- if(m < 0){
- setErr(EOk, "can't read partition='%s': %r", part->name);
- return 0;
- }
- logErr(EOk, "warning: truncated read from partition='%s' n=%ld read=%ld", part->name, mm, m);
- }
- }
- return 1;
- }
|