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 7a4ee46d 2003-11-23 devnull u32int maxblocksize;
6 7a4ee46d 2003-11-23 devnull int readonly;
7 7a4ee46d 2003-11-23 devnull
8 7a4ee46d 2003-11-23 devnull Part*
9 7a4ee46d 2003-11-23 devnull initpart(char *name, int writable)
10 7a4ee46d 2003-11-23 devnull {
11 7a4ee46d 2003-11-23 devnull Part *part;
12 7a4ee46d 2003-11-23 devnull Dir *dir;
13 7a4ee46d 2003-11-23 devnull int how;
14 7a4ee46d 2003-11-23 devnull
15 7a4ee46d 2003-11-23 devnull part = MK(Part);
16 7a4ee46d 2003-11-23 devnull part->name = estrdup(name);
17 7a4ee46d 2003-11-23 devnull if(!writable && readonly)
18 7a4ee46d 2003-11-23 devnull how = OREAD;
19 7a4ee46d 2003-11-23 devnull else
20 7a4ee46d 2003-11-23 devnull how = ORDWR;
21 7a4ee46d 2003-11-23 devnull part->fd = open(name, how);
22 7a4ee46d 2003-11-23 devnull if(part->fd < 0){
23 7a4ee46d 2003-11-23 devnull if(how == ORDWR)
24 7a4ee46d 2003-11-23 devnull part->fd = open(name, OREAD);
25 7a4ee46d 2003-11-23 devnull if(part->fd < 0){
26 7a4ee46d 2003-11-23 devnull freepart(part);
27 7a4ee46d 2003-11-23 devnull seterr(EOk, "can't open partition='%s': %r", name);
28 7a4ee46d 2003-11-23 devnull return nil;
29 7a4ee46d 2003-11-23 devnull }
30 7a4ee46d 2003-11-23 devnull fprint(2, "warning: %s opened for reading only\n", name);
31 7a4ee46d 2003-11-23 devnull }
32 7a4ee46d 2003-11-23 devnull dir = dirfstat(part->fd);
33 7a4ee46d 2003-11-23 devnull if(dir == nil){
34 7a4ee46d 2003-11-23 devnull freepart(part);
35 7a4ee46d 2003-11-23 devnull seterr(EOk, "can't stat partition='%s': %r", name);
36 7a4ee46d 2003-11-23 devnull return nil;
37 7a4ee46d 2003-11-23 devnull }
38 7a4ee46d 2003-11-23 devnull part->size = dir->length;
39 7a4ee46d 2003-11-23 devnull part->blocksize = 0;
40 7a4ee46d 2003-11-23 devnull free(dir);
41 7a4ee46d 2003-11-23 devnull return part;
42 7a4ee46d 2003-11-23 devnull }
43 7a4ee46d 2003-11-23 devnull
44 7a4ee46d 2003-11-23 devnull void
45 7a4ee46d 2003-11-23 devnull freepart(Part *part)
46 7a4ee46d 2003-11-23 devnull {
47 7a4ee46d 2003-11-23 devnull if(part == nil)
48 7a4ee46d 2003-11-23 devnull return;
49 7a4ee46d 2003-11-23 devnull close(part->fd);
50 7a4ee46d 2003-11-23 devnull free(part->name);
51 7a4ee46d 2003-11-23 devnull free(part);
52 7a4ee46d 2003-11-23 devnull }
53 7a4ee46d 2003-11-23 devnull
54 7a4ee46d 2003-11-23 devnull void
55 7a4ee46d 2003-11-23 devnull partblocksize(Part *part, u32int blocksize)
56 7a4ee46d 2003-11-23 devnull {
57 7a4ee46d 2003-11-23 devnull if(part->blocksize)
58 7a4ee46d 2003-11-23 devnull sysfatal("resetting partition=%s's block size", part->name);
59 7a4ee46d 2003-11-23 devnull part->blocksize = blocksize;
60 7a4ee46d 2003-11-23 devnull if(blocksize > maxblocksize)
61 7a4ee46d 2003-11-23 devnull maxblocksize = blocksize;
62 7a4ee46d 2003-11-23 devnull }
63 7a4ee46d 2003-11-23 devnull
64 7a4ee46d 2003-11-23 devnull int
65 7a4ee46d 2003-11-23 devnull writepart(Part *part, u64int addr, u8int *buf, u32int n)
66 7a4ee46d 2003-11-23 devnull {
67 7a4ee46d 2003-11-23 devnull long m, mm, nn;
68 7a4ee46d 2003-11-23 devnull
69 7a4ee46d 2003-11-23 devnull qlock(&stats.lock);
70 7a4ee46d 2003-11-23 devnull stats.diskwrites++;
71 7a4ee46d 2003-11-23 devnull stats.diskbwrites += n;
72 7a4ee46d 2003-11-23 devnull qunlock(&stats.lock);
73 7a4ee46d 2003-11-23 devnull
74 7a4ee46d 2003-11-23 devnull if(addr > part->size || addr + n > part->size){
75 7a4ee46d 2003-11-23 devnull seterr(ECorrupt, "out of bounds write to partition='%s'", part->name);
76 7a4ee46d 2003-11-23 devnull return -1;
77 7a4ee46d 2003-11-23 devnull }
78 7a4ee46d 2003-11-23 devnull print("write %s %lud at %llud\n", part->name, n, addr);
79 7a4ee46d 2003-11-23 devnull for(nn = 0; nn < n; nn += m){
80 7a4ee46d 2003-11-23 devnull mm = n - nn;
81 7a4ee46d 2003-11-23 devnull if(mm > MaxIo)
82 7a4ee46d 2003-11-23 devnull mm = MaxIo;
83 7a4ee46d 2003-11-23 devnull m = pwrite(part->fd, &buf[nn], mm, addr + nn);
84 7a4ee46d 2003-11-23 devnull if(m != mm){
85 7a4ee46d 2003-11-23 devnull if(m < 0){
86 7a4ee46d 2003-11-23 devnull seterr(EOk, "can't write partition='%s': %r", part->name);
87 7a4ee46d 2003-11-23 devnull return -1;
88 7a4ee46d 2003-11-23 devnull }
89 7a4ee46d 2003-11-23 devnull logerr(EOk, "truncated write to partition='%s' n=%ld wrote=%ld", part->name, mm, m);
90 7a4ee46d 2003-11-23 devnull }
91 7a4ee46d 2003-11-23 devnull }
92 7a4ee46d 2003-11-23 devnull return 0;
93 7a4ee46d 2003-11-23 devnull }
94 7a4ee46d 2003-11-23 devnull
95 7a4ee46d 2003-11-23 devnull int
96 7a4ee46d 2003-11-23 devnull readpart(Part *part, u64int addr, u8int *buf, u32int n)
97 7a4ee46d 2003-11-23 devnull {
98 7a4ee46d 2003-11-23 devnull long m, mm, nn;
99 7a4ee46d 2003-11-23 devnull int i;
100 7a4ee46d 2003-11-23 devnull
101 7a4ee46d 2003-11-23 devnull qlock(&stats.lock);
102 7a4ee46d 2003-11-23 devnull stats.diskreads++;
103 7a4ee46d 2003-11-23 devnull stats.diskbreads += n;
104 7a4ee46d 2003-11-23 devnull qunlock(&stats.lock);
105 7a4ee46d 2003-11-23 devnull
106 7a4ee46d 2003-11-23 devnull if(addr > part->size || addr + n > part->size){
107 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);
108 7a4ee46d 2003-11-23 devnull return -1;
109 7a4ee46d 2003-11-23 devnull }
110 7a4ee46d 2003-11-23 devnull print("read %s %lud at %llud\n", part->name, n, addr);
111 7a4ee46d 2003-11-23 devnull for(nn = 0; nn < n; nn += m){
112 7a4ee46d 2003-11-23 devnull mm = n - nn;
113 7a4ee46d 2003-11-23 devnull if(mm > MaxIo)
114 7a4ee46d 2003-11-23 devnull mm = MaxIo;
115 7a4ee46d 2003-11-23 devnull m = -1;
116 7a4ee46d 2003-11-23 devnull for(i=0; i<4; i++) {
117 7a4ee46d 2003-11-23 devnull m = pread(part->fd, &buf[nn], mm, addr + nn);
118 7a4ee46d 2003-11-23 devnull if(m == mm)
119 7a4ee46d 2003-11-23 devnull break;
120 7a4ee46d 2003-11-23 devnull }
121 7a4ee46d 2003-11-23 devnull if(m != mm){
122 7a4ee46d 2003-11-23 devnull if(m < 0){
123 7a4ee46d 2003-11-23 devnull seterr(EOk, "can't read partition='%s': %r", part->name);
124 7a4ee46d 2003-11-23 devnull return -1;
125 7a4ee46d 2003-11-23 devnull }
126 7a4ee46d 2003-11-23 devnull logerr(EOk, "warning: truncated read from partition='%s' n=%ld read=%ld", part->name, mm, m);
127 7a4ee46d 2003-11-23 devnull }
128 7a4ee46d 2003-11-23 devnull }
129 7a4ee46d 2003-11-23 devnull return 0;
130 7a4ee46d 2003-11-23 devnull }