1 7a4ee46d 2003-11-23 devnull #include "stdinc.h"
2 7a4ee46d 2003-11-23 devnull #include "dat.h"
3 7a4ee46d 2003-11-23 devnull #include "fns.h"
5 333c1dcc 2004-03-13 devnull #define trace 1
7 7a4ee46d 2003-11-23 devnull u32int maxblocksize;
8 7a4ee46d 2003-11-23 devnull int readonly;
11 7a4ee46d 2003-11-23 devnull initpart(char *name, int writable)
13 7a4ee46d 2003-11-23 devnull Part *part;
14 7a4ee46d 2003-11-23 devnull Dir *dir;
17 24998851 2004-03-11 devnull part = MKZ(Part);
18 7a4ee46d 2003-11-23 devnull part->name = estrdup(name);
19 7a4ee46d 2003-11-23 devnull if(!writable && readonly)
20 7a4ee46d 2003-11-23 devnull how = OREAD;
22 7a4ee46d 2003-11-23 devnull how = ORDWR;
23 7a4ee46d 2003-11-23 devnull part->fd = open(name, how);
24 7a4ee46d 2003-11-23 devnull if(part->fd < 0){
25 7a4ee46d 2003-11-23 devnull if(how == ORDWR)
26 7a4ee46d 2003-11-23 devnull part->fd = open(name, OREAD);
27 7a4ee46d 2003-11-23 devnull if(part->fd < 0){
28 7a4ee46d 2003-11-23 devnull freepart(part);
29 7a4ee46d 2003-11-23 devnull seterr(EOk, "can't open partition='%s': %r", name);
30 7a4ee46d 2003-11-23 devnull return nil;
32 7a4ee46d 2003-11-23 devnull fprint(2, "warning: %s opened for reading only\n", name);
34 7a4ee46d 2003-11-23 devnull dir = dirfstat(part->fd);
35 7a4ee46d 2003-11-23 devnull if(dir == nil){
36 7a4ee46d 2003-11-23 devnull freepart(part);
37 7a4ee46d 2003-11-23 devnull seterr(EOk, "can't stat partition='%s': %r", name);
38 7a4ee46d 2003-11-23 devnull return nil;
40 7a4ee46d 2003-11-23 devnull part->size = dir->length;
41 7a4ee46d 2003-11-23 devnull part->blocksize = 0;
42 7a4ee46d 2003-11-23 devnull free(dir);
43 7a4ee46d 2003-11-23 devnull return part;
47 7a4ee46d 2003-11-23 devnull freepart(Part *part)
49 7a4ee46d 2003-11-23 devnull if(part == nil)
51 7a4ee46d 2003-11-23 devnull close(part->fd);
52 7a4ee46d 2003-11-23 devnull free(part->name);
53 7a4ee46d 2003-11-23 devnull free(part);
57 7a4ee46d 2003-11-23 devnull partblocksize(Part *part, u32int blocksize)
59 7a4ee46d 2003-11-23 devnull if(part->blocksize)
60 7a4ee46d 2003-11-23 devnull sysfatal("resetting partition=%s's block size", part->name);
61 7a4ee46d 2003-11-23 devnull part->blocksize = blocksize;
62 7a4ee46d 2003-11-23 devnull if(blocksize > maxblocksize)
63 7a4ee46d 2003-11-23 devnull maxblocksize = blocksize;
67 7a4ee46d 2003-11-23 devnull writepart(Part *part, u64int addr, u8int *buf, u32int n)
69 7a4ee46d 2003-11-23 devnull long m, mm, nn;
71 7a4ee46d 2003-11-23 devnull qlock(&stats.lock);
72 7a4ee46d 2003-11-23 devnull stats.diskwrites++;
73 7a4ee46d 2003-11-23 devnull stats.diskbwrites += n;
74 7a4ee46d 2003-11-23 devnull qunlock(&stats.lock);
76 7a4ee46d 2003-11-23 devnull if(addr > part->size || addr + n > part->size){
77 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "out of bounds write to partition='%s'", part->name);
78 7a4ee46d 2003-11-23 devnull return -1;
80 9ffbb5ad 2004-03-12 devnull if(trace) print("write %s %lud at %llud\n", part->name, n, addr);
81 7a4ee46d 2003-11-23 devnull for(nn = 0; nn < n; nn += m){
82 7a4ee46d 2003-11-23 devnull mm = n - nn;
83 7a4ee46d 2003-11-23 devnull if(mm > MaxIo)
84 7a4ee46d 2003-11-23 devnull mm = MaxIo;
85 7a4ee46d 2003-11-23 devnull m = pwrite(part->fd, &buf[nn], mm, addr + nn);
86 7a4ee46d 2003-11-23 devnull if(m != mm){
87 7a4ee46d 2003-11-23 devnull if(m < 0){
88 7a4ee46d 2003-11-23 devnull seterr(EOk, "can't write partition='%s': %r", part->name);
89 7a4ee46d 2003-11-23 devnull return -1;
91 7a4ee46d 2003-11-23 devnull logerr(EOk, "truncated write to partition='%s' n=%ld wrote=%ld", part->name, mm, m);
94 7a4ee46d 2003-11-23 devnull return 0;
98 7a4ee46d 2003-11-23 devnull readpart(Part *part, u64int addr, u8int *buf, u32int n)
100 7a4ee46d 2003-11-23 devnull long m, mm, nn;
103 7a4ee46d 2003-11-23 devnull qlock(&stats.lock);
104 7a4ee46d 2003-11-23 devnull stats.diskreads++;
105 7a4ee46d 2003-11-23 devnull stats.diskbreads += n;
106 7a4ee46d 2003-11-23 devnull qunlock(&stats.lock);
108 7a4ee46d 2003-11-23 devnull if(addr > part->size || addr + n > part->size){
109 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "out of bounds read from partition='%s': addr=%lld n=%d size=%lld", part->name, addr, n, part->size);
110 7a4ee46d 2003-11-23 devnull return -1;
112 9ffbb5ad 2004-03-12 devnull if(trace) print("read %s %lud at %llud\n", part->name, n, addr);
113 7a4ee46d 2003-11-23 devnull for(nn = 0; nn < n; nn += m){
114 7a4ee46d 2003-11-23 devnull mm = n - nn;
115 7a4ee46d 2003-11-23 devnull if(mm > MaxIo)
116 7a4ee46d 2003-11-23 devnull mm = MaxIo;
118 7a4ee46d 2003-11-23 devnull for(i=0; i<4; i++) {
119 7a4ee46d 2003-11-23 devnull m = pread(part->fd, &buf[nn], mm, addr + nn);
120 7a4ee46d 2003-11-23 devnull if(m == mm)
123 7a4ee46d 2003-11-23 devnull if(m != mm){
124 7a4ee46d 2003-11-23 devnull if(m < 0){
125 7a4ee46d 2003-11-23 devnull seterr(EOk, "can't read partition='%s': %r", part->name);
126 7a4ee46d 2003-11-23 devnull return -1;
128 7a4ee46d 2003-11-23 devnull logerr(EOk, "warning: truncated read from partition='%s' n=%ld read=%ld", part->name, mm, m);
131 7a4ee46d 2003-11-23 devnull return 0;