Blame


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"
4 7a4ee46d 2003-11-23 devnull
5 333c1dcc 2004-03-13 devnull #define trace 1
6 9ffbb5ad 2004-03-12 devnull
7 7a4ee46d 2003-11-23 devnull u32int maxblocksize;
8 7a4ee46d 2003-11-23 devnull int readonly;
9 7a4ee46d 2003-11-23 devnull
10 7a4ee46d 2003-11-23 devnull Part*
11 7a4ee46d 2003-11-23 devnull initpart(char *name, int writable)
12 7a4ee46d 2003-11-23 devnull {
13 7a4ee46d 2003-11-23 devnull Part *part;
14 7a4ee46d 2003-11-23 devnull Dir *dir;
15 7a4ee46d 2003-11-23 devnull int how;
16 7a4ee46d 2003-11-23 devnull
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;
21 7a4ee46d 2003-11-23 devnull else
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;
31 7a4ee46d 2003-11-23 devnull }
32 7a4ee46d 2003-11-23 devnull fprint(2, "warning: %s opened for reading only\n", name);
33 7a4ee46d 2003-11-23 devnull }
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;
39 7a4ee46d 2003-11-23 devnull }
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;
44 7a4ee46d 2003-11-23 devnull }
45 7a4ee46d 2003-11-23 devnull
46 7a4ee46d 2003-11-23 devnull void
47 7a4ee46d 2003-11-23 devnull freepart(Part *part)
48 7a4ee46d 2003-11-23 devnull {
49 7a4ee46d 2003-11-23 devnull if(part == nil)
50 7a4ee46d 2003-11-23 devnull return;
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);
54 7a4ee46d 2003-11-23 devnull }
55 7a4ee46d 2003-11-23 devnull
56 7a4ee46d 2003-11-23 devnull void
57 7a4ee46d 2003-11-23 devnull partblocksize(Part *part, u32int blocksize)
58 7a4ee46d 2003-11-23 devnull {
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;
64 7a4ee46d 2003-11-23 devnull }
65 7a4ee46d 2003-11-23 devnull
66 7a4ee46d 2003-11-23 devnull int
67 7a4ee46d 2003-11-23 devnull writepart(Part *part, u64int addr, u8int *buf, u32int n)
68 7a4ee46d 2003-11-23 devnull {
69 7a4ee46d 2003-11-23 devnull long m, mm, nn;
70 7a4ee46d 2003-11-23 devnull
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);
75 7a4ee46d 2003-11-23 devnull
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;
79 7a4ee46d 2003-11-23 devnull }
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;
90 7a4ee46d 2003-11-23 devnull }
91 7a4ee46d 2003-11-23 devnull logerr(EOk, "truncated write to partition='%s' n=%ld wrote=%ld", part->name, mm, m);
92 7a4ee46d 2003-11-23 devnull }
93 7a4ee46d 2003-11-23 devnull }
94 7a4ee46d 2003-11-23 devnull return 0;
95 7a4ee46d 2003-11-23 devnull }
96 7a4ee46d 2003-11-23 devnull
97 7a4ee46d 2003-11-23 devnull int
98 7a4ee46d 2003-11-23 devnull readpart(Part *part, u64int addr, u8int *buf, u32int n)
99 7a4ee46d 2003-11-23 devnull {
100 7a4ee46d 2003-11-23 devnull long m, mm, nn;
101 7a4ee46d 2003-11-23 devnull int i;
102 7a4ee46d 2003-11-23 devnull
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);
107 7a4ee46d 2003-11-23 devnull
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;
111 7a4ee46d 2003-11-23 devnull }
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;
117 7a4ee46d 2003-11-23 devnull m = -1;
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)
121 7a4ee46d 2003-11-23 devnull break;
122 7a4ee46d 2003-11-23 devnull }
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;
127 7a4ee46d 2003-11-23 devnull }
128 7a4ee46d 2003-11-23 devnull logerr(EOk, "warning: truncated read from partition='%s' n=%ld read=%ld", part->name, mm, m);
129 7a4ee46d 2003-11-23 devnull }
130 7a4ee46d 2003-11-23 devnull }
131 7a4ee46d 2003-11-23 devnull return 0;
132 7a4ee46d 2003-11-23 devnull }