#include <u.h> | |
#include <libc.h> | |
#include <diskfs.h> | |
typedef struct DiskFile DiskFile; | |
struct DiskFile | |
{ | |
Disk disk; | |
int fd; | |
}; | |
int nfilereads; | |
static long | |
preadn(int fd, void *vdata, u32int ulen, u64int offset) | |
{ | |
long n; | |
uchar *data; | |
long len; | |
nfilereads++; | |
len = ulen; | |
data = vdata; | |
// fprint(2, "readn 0x%llux 0x%ux\n", offset, ulen); | |
while(len > 0){ | |
n = pread(fd, data, len, offset); | |
if(n <= 0) | |
break; | |
data += n; | |
offset += n; | |
len -= n; | |
} | |
return data-(uchar*)vdata; | |
} | |
static void | |
diskfileblockput(Block *b) | |
{ | |
free(b); | |
} | |
uvlong nreadx; | |
static Block* | |
diskfileread(Disk *dd, u32int len, u64int offset) | |
{ | |
int n; | |
Block *b; | |
DiskFile *d = (DiskFile*)dd; | |
b = mallocz(sizeof(Block)+len, 1); | |
if(b == nil) | |
return nil; | |
b->data = (uchar*)&b[1]; | |
nreadx += len; | |
n = preadn(d->fd, b->data, len, offset); | |
if(n <= 0){ | |
free(b); | |
return nil; | |
} | |
b->_close = diskfileblockput; | |
b->len = n; | |
return b; | |
} | |
static int | |
diskfilesync(Disk *dd) | |
{ | |
USED(dd); | |
return 0; | |
} | |
static void | |
diskfileclose(Disk *dd) | |
{ | |
DiskFile *d = (DiskFile*)dd; | |
close(d->fd); | |
free(d); | |
} | |
Disk* | |
diskopenfile(char *file) | |
{ | |
int fd; | |
DiskFile *d; | |
if((fd = open(file, OREAD)) < 0) | |
return nil; | |
d = mallocz(sizeof(DiskFile), 1); | |
if(d == nil){ | |
close(fd); | |
return nil; | |
} | |
d->disk._read = diskfileread; | |
d->disk._sync = diskfilesync; | |
d->disk._close = diskfileclose; | |
d->fd = fd; | |
return &d->disk; | |
} |