fix indirect block reading
This commit is contained in:
parent
725d9fd795
commit
9f4a65a0d8
1 changed files with 79 additions and 19 deletions
|
|
@ -15,6 +15,7 @@ static Block *ffsblockread(Fsys*, u64int);
|
||||||
static int ffssync(Fsys*);
|
static int ffssync(Fsys*);
|
||||||
static void ffsclose(Fsys*);
|
static void ffsclose(Fsys*);
|
||||||
|
|
||||||
|
static u64int ffsxfileblock(Fsys *fs, Nfs3Handle *h, u64int offset);
|
||||||
static Nfs3Status ffsroot(Fsys*, Nfs3Handle*);
|
static Nfs3Status ffsroot(Fsys*, Nfs3Handle*);
|
||||||
static Nfs3Status ffsgetattr(Fsys*, SunAuthUnix *au, Nfs3Handle*, Nfs3Attr*);
|
static Nfs3Status ffsgetattr(Fsys*, SunAuthUnix *au, Nfs3Handle*, Nfs3Attr*);
|
||||||
static Nfs3Status ffslookup(Fsys*, SunAuthUnix *au, Nfs3Handle*, char*, Nfs3Handle*);
|
static Nfs3Status ffslookup(Fsys*, SunAuthUnix *au, Nfs3Handle*, char*, Nfs3Handle*);
|
||||||
|
|
@ -43,6 +44,7 @@ fsysopenffs(Disk *disk)
|
||||||
fsys->_readfile = ffsreadfile;
|
fsys->_readfile = ffsreadfile;
|
||||||
fsys->_readlink = ffsreadlink;
|
fsys->_readlink = ffsreadlink;
|
||||||
fsys->_readdir = ffsreaddir;
|
fsys->_readdir = ffsreaddir;
|
||||||
|
fsys->fileblock = ffsxfileblock;
|
||||||
|
|
||||||
if(ffssync(fsys) < 0)
|
if(ffssync(fsys) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
@ -288,35 +290,60 @@ ffsdatablock(Ffs *fs, u32int bno, int size)
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Block*
|
static u32int
|
||||||
ffsfileblock(Ffs *fs, Inode *ino, u32int bno, int size)
|
ifetch(Ffs *fs, u32int bno, u32int off)
|
||||||
|
{
|
||||||
|
u32int *a;
|
||||||
|
Block *b;
|
||||||
|
|
||||||
|
if(bno == ~0)
|
||||||
|
return ~0;
|
||||||
|
b = ffsdatablock(fs, bno, fs->blocksize);
|
||||||
|
if(b == nil)
|
||||||
|
return ~0;
|
||||||
|
a = (u32int*)b->data;
|
||||||
|
bno = a[off];
|
||||||
|
blockput(b);
|
||||||
|
return bno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32int
|
||||||
|
ffsfileblockno(Ffs *fs, Inode *ino, u32int bno)
|
||||||
{
|
{
|
||||||
int ppb;
|
int ppb;
|
||||||
Block *b;
|
|
||||||
u32int *a;
|
|
||||||
|
|
||||||
if(bno < NDADDR){
|
if(bno < NDADDR){
|
||||||
if(debug) fprint(2, "ffsfileblock %lud: direct %#lux\n", (ulong)bno, (ulong)ino->db[bno]);
|
if(debug) fprint(2, "ffsfileblock %lud: direct %#lux\n", (ulong)bno, (ulong)ino->db[bno]);
|
||||||
return ffsdatablock(fs, ino->db[bno], size);
|
return ino->db[bno];
|
||||||
}
|
}
|
||||||
bno -= NDADDR;
|
bno -= NDADDR;
|
||||||
ppb = fs->blocksize/4;
|
ppb = fs->blocksize/4;
|
||||||
|
|
||||||
if(bno/ppb < NIADDR){
|
if(bno < ppb) /* single indirect */
|
||||||
if(debug) fprint(2, "ffsfileblock %lud: indirect %#lux\n", (ulong)(bno+NDADDR),
|
return ifetch(fs, ino->ib[0], bno);
|
||||||
(ulong)ino->ib[bno/ppb]);
|
bno -= ppb;
|
||||||
b = ffsdatablock(fs, ino->ib[bno/ppb], fs->blocksize);
|
|
||||||
if(b == nil)
|
if(bno < ppb*ppb)
|
||||||
return nil;
|
return ifetch(fs, ifetch(fs, ino->ib[1], bno/ppb), bno%ppb);
|
||||||
a = (u32int*)b->data;
|
bno -= ppb*ppb;
|
||||||
bno = a[bno%ppb];
|
|
||||||
if(debug) fprint(2, "ffsfileblock: indirect fetch %#lux size %d\n", (ulong)bno, size);
|
if(bno/ppb/ppb/ppb == 0) /* bno < ppb*ppb*ppb w/o overflow */
|
||||||
blockput(b);
|
return ifetch(fs, ifetch(fs, ifetch(fs, ino->ib[2], bno/ppb/ppb), (bno/ppb)%ppb), bno%ppb);
|
||||||
return ffsdatablock(fs, bno, size);
|
bno -= ppb*ppb*ppb;
|
||||||
|
|
||||||
|
fprint(2, "ffsfileblock %lud: way too big\n", (ulong)bno+NDADDR);
|
||||||
|
return ~0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprint(2, "ffsfileblock %lud: too big\n", (ulong)bno+NDADDR);
|
static Block*
|
||||||
|
ffsfileblock(Ffs *fs, Inode *ino, u32int bno, int size)
|
||||||
|
{
|
||||||
|
u32int b;
|
||||||
|
|
||||||
|
b = ffsfileblockno(fs, ino, bno);
|
||||||
|
if(b == ~0)
|
||||||
return nil;
|
return nil;
|
||||||
|
return ffsdatablock(fs, b, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -338,6 +365,8 @@ byte2u32(uchar *p)
|
||||||
return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
|
return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u64int iaddr;
|
||||||
|
|
||||||
static Nfs3Status
|
static Nfs3Status
|
||||||
handle2ino(Ffs *fs, Nfs3Handle *h, u32int *pinum, Inode *ino)
|
handle2ino(Ffs *fs, Nfs3Handle *h, u32int *pinum, Inode *ino)
|
||||||
{
|
{
|
||||||
|
|
@ -370,6 +399,8 @@ handle2ino(Ffs *fs, Nfs3Handle *h, u32int *pinum, Inode *ino)
|
||||||
if((b = diskread(fs->disk, fs->blocksize,
|
if((b = diskread(fs->disk, fs->blocksize,
|
||||||
(cg->ibno+ioff/fs->inosperblock)*(vlong)fs->blocksize)) == nil)
|
(cg->ibno+ioff/fs->inosperblock)*(vlong)fs->blocksize)) == nil)
|
||||||
return Nfs3ErrIo;
|
return Nfs3ErrIo;
|
||||||
|
iaddr = (cg->ibno+ioff/fs->inosperblock)*(vlong)fs->blocksize
|
||||||
|
+ (ioff%fs->inosperblock)*sizeof(Inode);
|
||||||
*ino = ((Inode*)b->data)[ioff%fs->inosperblock];
|
*ino = ((Inode*)b->data)[ioff%fs->inosperblock];
|
||||||
blockput(b);
|
blockput(b);
|
||||||
|
|
||||||
|
|
@ -458,6 +489,9 @@ inoperm(Inode *ino, SunAuthUnix *au, int need)
|
||||||
{
|
{
|
||||||
int have;
|
int have;
|
||||||
|
|
||||||
|
if(au == nil)
|
||||||
|
return Nfs3Ok;
|
||||||
|
|
||||||
have = ino->mode&0777;
|
have = ino->mode&0777;
|
||||||
if(ino->uid == au->uid)
|
if(ino->uid == au->uid)
|
||||||
have >>= 6;
|
have >>= 6;
|
||||||
|
|
@ -680,6 +714,32 @@ ffsreaddir(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count, u64int cook
|
||||||
return Nfs3Ok;
|
return Nfs3Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u64int
|
||||||
|
ffsxfileblock(Fsys *fsys, Nfs3Handle *h, u64int offset)
|
||||||
|
{
|
||||||
|
u32int bno;
|
||||||
|
Inode ino;
|
||||||
|
Nfs3Status ok;
|
||||||
|
Ffs *fs;
|
||||||
|
|
||||||
|
fs = fsys->priv;
|
||||||
|
if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok){
|
||||||
|
nfs3errstr(ok);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(offset == 1)
|
||||||
|
return iaddr;
|
||||||
|
if(offset >= ino.size){
|
||||||
|
werrstr("beyond end of file");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bno = offset/fs->blocksize;
|
||||||
|
bno = ffsfileblockno(fs, &ino, bno);
|
||||||
|
if(bno == ~0)
|
||||||
|
return 0;
|
||||||
|
return bno*(u64int)fs->fragsize;
|
||||||
|
}
|
||||||
|
|
||||||
static Nfs3Status
|
static Nfs3Status
|
||||||
ffsreadfile(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count,
|
ffsreadfile(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count,
|
||||||
u64int offset, uchar **pdata, u32int *pcount, u1int *peof)
|
u64int offset, uchar **pdata, u32int *pcount, u1int *peof)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue