10 strtoullsuf(char *p, char **pp, int rad, u64int *u)
14 if(!isdigit((uchar)*p))
16 v = strtoull(p, &p, rad);
46 parsepart(char *name, char **file, u64int *lo, u64int *hi)
50 *file = estrdup(name);
51 if((p = strrchr(*file, ':')) == nil){
60 if(strtoullsuf(p, &p, 0, lo) < 0){
71 if(strtoullsuf(p, &p, 0, hi) < 0 || *p != 0){
79 initpart(char *name, int mode)
86 if(parsepart(name, &file, &lo, &hi) < 0)
88 trace(TraceDisk, "initpart %s file %s lo 0x%llx hi 0x%llx", name, file, lo, hi);
90 part->name = estrdup(name);
91 part->filename = estrdup(file);
93 mode &= ~(OREAD|OWRITE|ORDWR);
96 part->fd = open(file, mode);
98 if((mode&(OREAD|OWRITE|ORDWR)) == ORDWR)
99 part->fd = open(file, (mode&~ORDWR)|OREAD);
102 fprint(2, "can't open partition='%s': %r\n", file);
103 seterr(EOk, "can't open partition='%s': %r", file);
108 fprint(2, "warning: %s opened for reading only\n", name);
111 dir = dirfstat(part->fd);
114 seterr(EOk, "can't stat partition='%s': %r", file);
118 if(dir->length == 0){
121 seterr(EOk, "can't determine size of partition %s", file);
125 if(dir->length < hi || dir->length < lo){
127 seterr(EOk, "partition '%s': bounds out of range (max %lld)", name, dir->length);
134 part->size = hi - part->offset;
140 flushpart(Part *part)
158 partblocksize(Part *part, u32int blocksize)
161 sysfatal("resetting partition=%s's block size", part->name);
162 part->blocksize = blocksize;
163 if(blocksize > maxblocksize)
164 maxblocksize = blocksize;
168 Maxxfer = 64*1024, /* for NCR SCSI controllers; was 128K */
171 static int reopen(Part*);
174 rwpart(Part *part, int isread, u64int offset0, u8int *buf0, u32int count0)
176 u32int count, opsize;
181 trace(TraceDisk, "%s %s %ud at 0x%llx",
182 isread ? "read" : "write", part->name, count0, offset0);
183 if(offset0 >= part->size || offset0+count0 > part->size){
184 seterr(EStrange, "out of bounds %s offset 0x%llux count %ud to partition %s size 0x%llux",
185 isread ? "read" : "write", offset0, count0, part->name,
198 n = pread(part->fd, buf, opsize, offset);
200 n = pwrite(part->fd, buf, opsize, offset);
202 seterr(EAdmin, "%s %s offset 0x%llux count %ud buf %p returned %d: %r",
203 isread ? "read" : "write", part->filename, offset, opsize, buf, n);
215 readpart(Part *part, u64int offset, u8int *buf, u32int count)
217 return rwpart(part, 1, offset, buf, count);
221 writepart(Part *part, u64int offset, u8int *buf, u32int count)
223 return rwpart(part, 0, offset, buf, count);
232 p = initpart(name, OREAD);
235 b = alloczblock(p->size, 0, p->blocksize);
237 seterr(EOk, "can't alloc %s: %r", name);
241 if(readpart(p, 0, b->data, p->size) < 0){
242 seterr(EOk, "can't read %s: %r", name);