better ext2 block read (sigh)

This commit is contained in:
rsc 2006-06-15 05:52:24 +00:00
parent dbf91a04cc
commit fa5af68711

View file

@ -655,7 +655,7 @@ ext2readfile(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count,
uchar *data; uchar *data;
Block *b; Block *b;
Ext2 *fs; Ext2 *fs;
int off, want, fragcount; int skip1, tot, want, fragcount;
Inode ino; Inode ino;
Nfs3Status ok; Nfs3Status ok;
@ -674,34 +674,36 @@ ext2readfile(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count,
} }
if(offset+count > ino.size) if(offset+count > ino.size)
count = ino.size-offset; count = ino.size-offset;
if(offset/fs->blocksize != (offset+count-1)/fs->blocksize)
count = fs->blocksize - offset%fs->blocksize;
data = malloc(count); data = malloc(count);
if(data == nil) if(data == nil)
return Nfs3ErrNoMem; return Nfs3ErrNoMem;
want = offset%fs->blocksize+count;
if(want%fs->blocksize)
want += fs->blocksize - want%fs->blocksize;
b = ext2fileblock(fs, &ino, offset/fs->blocksize, want);
if(b == nil){
/* BUG: distinguish sparse file from I/O error */
memset(data, 0, count); memset(data, 0, count);
}else{
off = offset%fs->blocksize; skip1 = offset%fs->blocksize;
fragcount = count; /* need signed variable */ offset -= skip1;
if(off+fragcount > b->len){ want = skip1+count;
fragcount = b->len - off;
if(fragcount < 0) /*
fragcount = 0; * have to read multiple blocks if we get asked for a big read.
} * Linux NFS client assumes that if you ask for 8k and only get 4k
if(fragcount > 0) * back, the remaining 4k is zeros.
memmove(data, b->data+off, fragcount); */
count = fragcount; for(tot=0; tot<want; tot+=fragcount){
b = ext2fileblock(fs, &ino, (offset+tot)/fs->blocksize, fs->blocksize);
fragcount = fs->blocksize;
if(b == nil)
continue;
if(tot+fragcount > want)
fragcount = want - tot;
if(tot == 0)
memmove(data, b->data+skip1, fragcount-skip1);
else
memmove(data+tot-skip1, b->data, fragcount);
blockput(b); blockput(b);
} }
count = tot - skip1;
*peof = (offset+count == ino.size); *peof = (offset+count == ino.size);
*pcount = count; *pcount = count;
*pdata = data; *pdata = data;