4c639475ce
the malloc pool allocator is limited in its allocation size. as almost all data structures in cwfs are never freed, use brk() in ialloc() instead of mallocalign(). this means memory returned by ialloc() cannot be freed! to make sure we do not call free by accident, remove the #define malloc(n) ialloc(n, 0) macro and use ialloc() directly as in the original code to show the intend of permanent allocations.
123 lines
2.6 KiB
C
123 lines
2.6 KiB
C
/*
|
|
* drive disks
|
|
* used to be just scsi disks, and issued scsi commands directly to the host
|
|
* adapter, but now it just does normal i/o.
|
|
*/
|
|
#include "all.h"
|
|
|
|
enum { Sectorsz = 512, }; /* usual disk sector size */
|
|
|
|
typedef struct Wren Wren;
|
|
struct Wren
|
|
{
|
|
long block; /* size of a block -- from config */
|
|
Devsize nblock; /* number of blocks -- from config */
|
|
long mult; /* multiplier to get physical blocks */
|
|
Devsize max; /* number of logical blocks */
|
|
};
|
|
|
|
char *
|
|
dataof(char *file)
|
|
{
|
|
char *datanm;
|
|
Dir *dir;
|
|
|
|
dir = dirstat(file);
|
|
if (dir != nil && dir->mode & DMDIR)
|
|
datanm = smprint("%s/data", file);
|
|
else
|
|
datanm = strdup(file);
|
|
free(dir);
|
|
return datanm;
|
|
}
|
|
|
|
void
|
|
wreninit(Device *d)
|
|
{
|
|
Wren *dr;
|
|
Dir *dir;
|
|
|
|
if(d->private)
|
|
return;
|
|
d->private = dr = ialloc(sizeof(Wren), 0);
|
|
|
|
if (d->wren.file)
|
|
d->wren.sddata = dataof(d->wren.file);
|
|
else {
|
|
d->wren.sddir = sdof(d);
|
|
d->wren.sddata = smprint("%s/data", d->wren.sddir);
|
|
}
|
|
|
|
assert(d->wren.fd <= 0);
|
|
d->wren.fd = open(d->wren.sddata, ORDWR);
|
|
if (d->wren.fd < 0)
|
|
panic("wreninit: can't open %s for %Z: %r", d->wren.sddata, d);
|
|
|
|
dr->block = inqsize(d->wren.sddata);
|
|
if(dr->block <= 0 || dr->block >= 16*1024) {
|
|
if(chatty)
|
|
print("\twreninit %Z block size %ld, setting to %d\n",
|
|
d, dr->block, Sectorsz);
|
|
dr->block = Sectorsz;
|
|
}
|
|
|
|
dir = dirfstat(d->wren.fd);
|
|
dr->nblock = dir->length / dr->block;
|
|
free(dir);
|
|
|
|
dr->mult = (RBUFSIZE + dr->block - 1) / dr->block;
|
|
dr->max = (dr->nblock + 1) / dr->mult;
|
|
if(chatty){
|
|
print("\tdisk drive %Z: %,lld %ld-byte sectors, ",
|
|
d, (Wideoff)dr->nblock, dr->block);
|
|
print("%,lld %d-byte blocks\n", (Wideoff)dr->max, RBUFSIZE);
|
|
print("\t\t%ld multiplier\n", dr->mult);
|
|
}
|
|
}
|
|
|
|
Devsize
|
|
wrensize(Device *d)
|
|
{
|
|
return ((Wren *)d->private)->max;
|
|
}
|
|
|
|
int
|
|
wrenread(Device *d, Off b, void *c)
|
|
{
|
|
int r = 0;
|
|
Wren *dr = d->private;
|
|
|
|
if (dr == nil)
|
|
panic("wrenread: no drive (%Z) block %lld", d, (Wideoff)b);
|
|
if(b >= dr->max) {
|
|
fprint(2, "wrenread: block out of range %Z(%lld)\n", d, (Wideoff)b);
|
|
r = 0x040;
|
|
} else if (pread(d->wren.fd, c, RBUFSIZE, (vlong)b*RBUFSIZE) != RBUFSIZE) {
|
|
fprint(2, "wrenread: error on %Z(%lld): %r\n", d, (Wideoff)b);
|
|
cons.nwrenre++;
|
|
r = 1;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
int
|
|
wrenwrite(Device *d, Off b, void *c)
|
|
{
|
|
int r = 0;
|
|
Wren *dr = d->private;
|
|
|
|
if (dr == nil)
|
|
panic("wrenwrite: no drive (%Z) block %lld", d, (Wideoff)b);
|
|
if(b >= dr->max) {
|
|
fprint(2, "wrenwrite: block out of range %Z(%lld)\n",
|
|
d, (Wideoff)b);
|
|
r = 0x040;
|
|
} else if (pwrite(d->wren.fd, c, RBUFSIZE, (vlong)b*RBUFSIZE) != RBUFSIZE) {
|
|
fprint(2, "wrenwrite: error on %Z(%lld): %r\n", d, (Wideoff)b);
|
|
cons.nwrenwe++;
|
|
r = 1;
|
|
}
|
|
|
|
return r;
|
|
}
|