#include <u.h>
#include <libc.h>
#include <thread.h>
#include <sunrpc.h>
#include <nfs3.h>
#include <diskfs.h>
#include "ffs.h"

#define BADBNO	((u64int)~0ULL)

#define checkcg 0
#define debug 0

static int checkfsblk(Fsblk*);
static int checkcgblk(Cgblk*);
static Block *ffsblockread(Fsys*, u64int);
static int ffssync(Fsys*);
static void ffsclose(Fsys*);

static u64int ffsxfileblock(Fsys *fs, Nfs3Handle *h, u64int offset);
static Nfs3Status ffsroot(Fsys*, Nfs3Handle*);
static Nfs3Status ffsgetattr(Fsys*, SunAuthUnix *au, Nfs3Handle*, Nfs3Attr*);
static Nfs3Status ffslookup(Fsys*, SunAuthUnix *au, Nfs3Handle*, char*, Nfs3Handle*);
static Nfs3Status ffsreadfile(Fsys*, SunAuthUnix *au, Nfs3Handle*, u32int, u64int, uchar**, u32int*, u1int*);
static Nfs3Status ffsreadlink(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char **link);
static Nfs3Status ffsreaddir(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int, u64int, uchar**, u32int*, u1int*);
static Nfs3Status ffsaccess(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int want, u32int *got, Nfs3Attr *attr);

Fsys*
fsysopenffs(Disk *disk)
{
	Ffs *fs;
	Fsys *fsys;

	fsys = emalloc(sizeof(Fsys));
	fs = emalloc(sizeof(Ffs));
	fs->disk = disk;
	fsys->priv = fs;
	fsys->type = "ffs";
	fsys->_readblock = ffsblockread;
	fsys->_sync = ffssync;
	fsys->_root = ffsroot;
	fsys->_getattr = ffsgetattr;
	fsys->_access = ffsaccess;
	fsys->_lookup = ffslookup;
	fsys->_readfile = ffsreadfile;
	fsys->_readlink = ffsreadlink;
	fsys->_readdir = ffsreaddir;
	fsys->_close = ffsclose;
	fsys->fileblock = ffsxfileblock;

	if(ffssync(fsys) < 0)
		goto error;

	return fsys;

error:
	ffsclose(fsys);
	return nil;
}

static Cgblk*
ffscylgrp(Ffs *fs, u32int i, Block **pb)
{
	Block *b;
	Cgblk *cg;

	if(i >= fs->ncg)
		return nil;

	b = diskread(fs->disk, fs->blocksize, (u64int)fs->cg[i].cgblkno*fs->blocksize);
	if(b == nil)
		return nil;
	cg = (Cgblk*)b->data;
	if(checkcgblk(cg) < 0){
fprint(2, "checkcgblk %d %lud: %r\n", i, (ulong)fs->cg[i].cgblkno);
		blockput(b);
		return nil;
	}
	*pb = b;
	return cg;
}

static int
ffssync(Fsys *fsys)
{
	int i;
	int off[] = { SBOFF, SBOFF2, SBOFFPIGGY };
	Block *b, *cgb;
	Cgblk *cgblk;
	Cylgrp *cg;
	Disk *disk;
	Ffs *fs;
	Fsblk *fsblk;

	fs = fsys->priv;
	disk = fs->disk;

	/*
	 * Read super block.
	 */
	b = nil;
	for(i=0; i<nelem(off); i++){
		if((b = diskread(disk, SBSIZE, off[i])) == nil)
			goto error;
		fsblk = (Fsblk*)b->data;
	//	fprint(2, "offset of magic: %ld\n", offsetof(Fsblk, magic));
		if((fs->ufs = checkfsblk(fsblk)) > 0)
			goto okay;
		blockput(b);
		b = nil;
	}
	goto error;

okay:
	fs->blocksize = fsblk->blocksize;
	fs->nblock = (fsblk->nfrag+fsblk->fragsperblock-1) / fsblk->fragsperblock;
	fs->fragsize = fsblk->fragsize;
	fs->fragspergroup = fsblk->fragspergroup;
	fs->fragsperblock = fsblk->fragsperblock;
	fs->inosperblock = fsblk->inosperblock;
	fs->inospergroup = fsblk->inospergroup;

	fs->nfrag = fsblk->nfrag;
	fs->ndfrag = fsblk->ndfrag;
	/*
	 * used to use 
	 *	fs->blockspergroup = (u64int)fsblk->_cylspergroup * 
	 *		fsblk->secspercyl * BYTESPERSEC / fsblk->blocksize;
	 * for UFS1, but this should work for both UFS1 and UFS2
	 */
	fs->blockspergroup = (u64int)fsblk->fragspergroup / fsblk->fragsperblock;
	fs->ncg = fsblk->ncg;

	fsys->blocksize = fs->blocksize;
	fsys->nblock = fs->nblock;

	if(debug) fprint(2, "ffs %lld %d-byte blocks, %d cylinder groups\n",
		fs->nblock, fs->blocksize, fs->ncg);
	if(debug) fprint(2, "\tinospergroup %d perblock %d blockspergroup %lld\n",
		fs->inospergroup, fs->inosperblock, fs->blockspergroup);

	if(fs->cg == nil)
		fs->cg = emalloc(fs->ncg*sizeof(Cylgrp));
	for(i=0; i<fs->ncg; i++){
		cg = &fs->cg[i];
		if(fs->ufs == 2)
			cg->bno = (u64int)fs->blockspergroup*i;
		else
			cg->bno = fs->blockspergroup*i + fsblk->_cgoffset * (i & ~fsblk->_cgmask);
		cg->cgblkno = cg->bno + fsblk->cfragno/fs->fragsperblock;
		cg->ibno = cg->bno + fsblk->ifragno/fs->fragsperblock;
		cg->dbno = cg->bno + fsblk->dfragno/fs->fragsperblock;

		if(checkcg){
			if((cgb = diskread(disk, fs->blocksize, (u64int)cg->cgblkno*fs->blocksize)) == nil)
				goto error;

			cgblk = (Cgblk*)cgb->data;
			if(checkcgblk(cgblk) < 0){
				blockput(cgb);
				goto error;
			}
			if(cgblk->nfrag % fs->fragsperblock && i != fs->ncg-1){
				werrstr("fractional number of blocks in non-last cylinder group %d", cgblk->nfrag);
				blockput(cgb);
				goto error;
			}
			/* cg->nfrag = cgblk->nfrag; */
			/* cg->nblock = (cgblk->nfrag+fs->fragsperblock-1) / fs->fragsperblock; */
			/* fprint(2, "cg #%d: cgblk %lud, %d blocks, %d inodes\n", cgblk->num, (ulong)cg->cgblkno, cg->nblock, cg->nino); */
		}
	}
	blockput(b);
	return 0;

error:
	blockput(b);
	return -1;
}

static void
ffsclose(Fsys *fsys)
{
	Ffs *fs;

	fs = fsys->priv;
	if(fs->cg)
		free(fs->cg);
	free(fs);
	free(fsys);
}
	
static int
checkfsblk(Fsblk *super)
{
// fprint(2, "ffs magic 0x%ux\n", super->magic);
	if(super->magic == FSMAGIC){
		super->time = super->_time;
		super->nfrag = super->_nfrag;
		super->ndfrag = super->_ndfrag;
		super->flags = super->_flags;
		return 1;
	}
	if(super->magic == FSMAGIC2){
		return 2;
	}

	werrstr("bad super block");
	return -1;
}

static int
checkcgblk(Cgblk *cg)
{
	if(cg->magic != CGMAGIC){
		werrstr("bad cylinder group block");
		return -1;
	}
	return 0;
}

/*
 * Read block #bno from the disk, zeroing unused data.
 * If there is no data whatsoever, it's okay to return nil.
 */
int nskipx;
static Block*
ffsblockread(Fsys *fsys, u64int bno)
{
	int i, o;
	u8int *fmap;
	int frag, fsize, avail;
	Block *b;
	Cgblk *cgblk;
	Ffs *fs;

	fs = fsys->priv;
	i = bno / fs->blockspergroup;
	o = bno % fs->blockspergroup;
	if(i >= fs->ncg)
		return nil;

	if((cgblk = ffscylgrp(fs, i, &b)) == nil)
		return nil;

	fmap = (u8int*)cgblk+cgblk->fmapoff;
	frag = fs->fragsperblock;
	switch(frag){
	default:
		sysfatal("bad frag");
	case 8:
		avail = fmap[o];
		break;
	case 4:
		avail = (fmap[o>>1] >> ((o&1)*4)) & 0xF;
		break;
	case 2:
		avail = (fmap[o>>2] >> ((o&3)*2)) & 0x3;
		break;
	case 1:
		avail = (fmap[o>>3] >> (o&7)) & 0x1;
		break;
	}
	blockput(b);

	if(avail == ((1<<frag)-1))
{
nskipx++;
		return nil;
}
	if((b = diskread(fs->disk, fs->blocksize, bno*fs->blocksize)) == nil){
		fprint(2, "diskread failed!!!\n");
		return nil;
	}

	fsize = fs->fragsize;
	for(i=0; i<frag; i++)
		if(avail & (1<<i))
			memset(b->data + fsize*i, 0, fsize);
	return b;
}

static Block*
ffsdatablock(Ffs *fs, u64int bno, int size)
{
	int fsize;
	u64int diskaddr;
	Block *b;

	if(bno == 0)
		return nil;

	fsize = size;
	if(fsize < fs->fragsize)
		fsize = fs->fragsize;

	if(bno >= fs->nfrag){
		fprint(2, "ffs: request for block %#lux; nfrag %#llux\n", (ulong)bno, fs->nfrag);
		return nil;
	}
	diskaddr = (u64int)bno*fs->fragsize;
	b = diskread(fs->disk, fsize, diskaddr);
	if(b == nil){
		fprint(2, "ffs: disk i/o at %#llux for %#ux: %r\n", diskaddr, fsize);
		return nil;
	}
	if(b->len < fsize){
		fprint(2, "ffs: disk i/o at %#llux for %#ux got %#ux\n", diskaddr, fsize,
			b->len);
		blockput(b);
		return nil;
	}
	
	return b;
}

static u64int
ifetch(Ffs *fs, u64int bno, u32int off)
{
	Block *b;
	
	if(bno == BADBNO)
		return BADBNO;
	b = ffsdatablock(fs, bno, fs->blocksize);
	if(b == nil)
		return BADBNO;
	if(fs->ufs == 2)
		bno = ((u64int*)b->data)[off];
	else
		bno = ((u32int*)b->data)[off];
	blockput(b);
	return bno;
}

static u64int
ffsfileblockno(Ffs *fs, Inode *ino, u64int bno)
{
	int ppb;

	if(bno < NDADDR){
		if(debug) fprint(2, "ffsfileblock %lud: direct %#lux\n", (ulong)bno, (ulong)ino->db[bno]);
		return ino->db[bno];
	}
	bno -= NDADDR;
	ppb = fs->blocksize/4;

	if(bno < ppb)	/* single indirect */
		return ifetch(fs, ino->ib[0], bno);
	bno -= ppb;

	if(bno < ppb*ppb)
		return ifetch(fs, ifetch(fs, ino->ib[1], bno/ppb), bno%ppb);
	bno -= ppb*ppb;
	
	if(bno/ppb/ppb/ppb == 0)	/* bno < ppb*ppb*ppb w/o overflow */
		return ifetch(fs, ifetch(fs, ifetch(fs, ino->ib[2], bno/ppb/ppb), (bno/ppb)%ppb), bno%ppb);
	
	fprint(2, "ffsfileblock %llud: way too big\n", bno+NDADDR+ppb+ppb*ppb);
	return BADBNO;
}

static Block*
ffsfileblock(Ffs *fs, Inode *ino, u64int bno, int size)
{
	u64int b;
	
	b = ffsfileblockno(fs, ino, bno);
	if(b == ~0)
		return nil;
	return ffsdatablock(fs, b, size);
}

/*
 * NFS handles are 4-byte inode number.
 */
static void
mkhandle(Nfs3Handle *h, u64int ino)
{
	h->h[0] = ino >> 24;
	h->h[1] = ino >> 16;
	h->h[2] = ino >> 8;
	h->h[3] = ino;
	h->len = 4;
}

static u32int
byte2u32(uchar *p)
{
	return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
}

static u64int lastiaddr;	/* debugging */

static void
inode1to2(Inode1 *i1, Inode *i2)
{
	int i;
	
	memset(i2, 0, sizeof *i2);
	i2->mode = i1->mode;
	i2->nlink = i1->nlink;
	i2->size = i1->size;
	i2->atime = i1->atime;
	i2->atimensec = i1->atimensec;
	i2->mtime = i1->mtime;
	i2->mtimensec = i1->mtimensec;
	i2->ctime = i1->ctime;
	i2->ctimensec = i1->ctimensec;
	for(i=0; i<NDADDR; i++)
		i2->db[i] = i1->db[i];
	for(i=0; i<NIADDR; i++)
		i2->ib[i] = i1->ib[i];
	i2->flags = i1->flags;
	i2->nblock = i1->nblock;
	i2->gen = i1->gen;
	i2->uid = i1->uid;
	i2->gid = i1->gid;
}

static Nfs3Status
handle2ino(Ffs *fs, Nfs3Handle *h, u32int *pinum, Inode *ino)
{
	int i;
	u32int ioff;
	u32int inum;
	u64int iaddr;
	Block *b;
	Cylgrp *cg;
	Inode1 ino1;

	if(h->len != 4)
		return Nfs3ErrBadHandle;
	inum = byte2u32(h->h);
	if(pinum)
		*pinum = inum;
	if(debug) print("inum %d...", (int)inum);

	/* fetch inode from disk */
	i = inum / fs->inospergroup;
	ioff = inum % fs->inospergroup;
	if(debug)print("cg %d off %d...", i, (int)ioff);
	if(i >= fs->ncg)
		return Nfs3ErrBadHandle;
	cg = &fs->cg[i];

	if(debug) print("cg->ibno %lld ufs %d...", cg->ibno, fs->ufs);
	iaddr = (cg->ibno+ioff/fs->inosperblock)*(vlong)fs->blocksize;
	ioff = ioff%fs->inosperblock;
	if((b = diskread(fs->disk, fs->blocksize, iaddr)) == nil)
		return Nfs3ErrIo;
	if(fs->ufs == 2){
		*ino = ((Inode*)b->data)[ioff];
		lastiaddr = iaddr+ioff*sizeof(Inode);
	}else{
		ino1 = ((Inode1*)b->data)[ioff];
		inode1to2(&ino1, ino);
		lastiaddr = iaddr+ioff*sizeof(Inode1);
	}
	blockput(b);
	return Nfs3Ok;
}

static Nfs3Status
ffsroot(Fsys *fsys, Nfs3Handle *h)
{
	USED(fsys);
	mkhandle(h, 2);
	return Nfs3Ok;
}

static Nfs3Status
ino2attr(Ffs *fs, Inode *ino, u32int inum, Nfs3Attr *attr)
{
	u32int rdev;

	attr->type = -1;
	switch(ino->mode&IFMT){
	case IFIFO:
		attr->type = Nfs3FileFifo;
		break;
	case IFCHR:
		attr->type = Nfs3FileChar;
		break;
	case IFDIR:
		attr->type = Nfs3FileDir;
		break;
	case IFBLK:
		attr->type = Nfs3FileBlock;
		break;
	case IFREG:
		attr->type = Nfs3FileReg;
		break;
	case IFLNK:
		attr->type = Nfs3FileSymlink;
		break;
	case IFSOCK:
		attr->type = Nfs3FileSocket;
		break;
	case IFWHT:
	default:
		return Nfs3ErrBadHandle;
	}

	attr->mode = ino->mode&07777;
	attr->nlink = ino->nlink;
	attr->uid = ino->uid;
	attr->gid = ino->gid;
	attr->size = ino->size;
	attr->used = ino->nblock*fs->blocksize;
	if(attr->type==Nfs3FileBlock || attr->type==Nfs3FileChar){
		rdev = ino->db[0];
		attr->major = (rdev>>8)&0xFF;
		attr->minor = rdev & 0xFFFF00FF;
	}else{
		attr->major = 0;
		attr->minor = 0;
	}
	attr->fsid = 0;
	attr->fileid = inum;
	attr->atime.sec = ino->atime;
	attr->atime.nsec = ino->atimensec;
	attr->mtime.sec = ino->mtime;
	attr->mtime.nsec = ino->mtimensec;
	attr->ctime.sec = ino->ctime;
	attr->ctime.nsec = ino->ctimensec;
	return Nfs3Ok;
}

static int
ingroup(SunAuthUnix *au, uint gid)
{
	int i;

	for(i=0; i<au->ng; i++)
		if(au->g[i] == gid)
			return 1;
	return 0;
}

static Nfs3Status
inoperm(Inode *ino, SunAuthUnix *au, int need)
{
	int have;

	if(au == nil)
		return Nfs3Ok;

	have = ino->mode&0777;
	if(ino->uid == au->uid)
		have >>= 6;
	else if(ino->gid == au->gid || ingroup(au, ino->gid))
		have >>= 3;

	if((have&need) != need)
		return Nfs3ErrNotOwner;	/* really EPERM */
	return Nfs3Ok;
}

static Nfs3Status
ffsgetattr(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, Nfs3Attr *attr)
{
	Inode ino;
	u32int inum;
	Ffs *fs;
	Nfs3Status ok;

	fs = fsys->priv;
	if((ok = handle2ino(fs, h, &inum, &ino)) != Nfs3Ok)
		return ok;

	USED(au);	/* anyone can getattr */

	return ino2attr(fs, &ino, inum, attr);
}

static Nfs3Status
ffsaccess(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int want, u32int *got, Nfs3Attr *attr)
{
	int have;
	Inode ino;
	u32int inum;
	Ffs *fs;
	Nfs3Status ok;

	fs = fsys->priv;
	if((ok = handle2ino(fs, h, &inum, &ino)) != Nfs3Ok)
		return ok;

	have = ino.mode&0777;
	if(ino.uid == au->uid)
		have >>= 6;
	else if(ino.gid == au->gid || ingroup(au, ino.gid))
		have >>= 3;

	*got = 0;
	if((want&Nfs3AccessRead) && (have&AREAD))
		*got |= Nfs3AccessRead;
	if((want&Nfs3AccessLookup) && (ino.mode&IFMT)==IFDIR && (have&AEXEC))
		*got |= Nfs3AccessLookup;
	if((want&Nfs3AccessExecute) && (ino.mode&IFMT)!=IFDIR && (have&AEXEC))
		*got |= Nfs3AccessExecute;

	return ino2attr(fs, &ino, inum, attr);
}

static Nfs3Status
ffslookup(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char *name, Nfs3Handle *nh)
{
	u32int nblock;
	u32int i;
	uchar *p, *ep;
	Dirent *de;
	Inode ino;
	Block *b;
	Ffs *fs;
	Nfs3Status ok;
	int len, want;

	fs = fsys->priv;
	if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok)
		return ok;

	if((ino.mode&IFMT) != IFDIR)
		return Nfs3ErrNotDir;

	if((ok = inoperm(&ino, au, AEXEC)) != Nfs3Ok)
		return ok;

	len = strlen(name);
	nblock = (ino.size+fs->blocksize-1) / fs->blocksize;
	for(i=0; i<nblock; i++){
		if(i==nblock-1)
			want = ino.size % fs->blocksize;
		else
			want = fs->blocksize;
		b = ffsfileblock(fs, &ino, i, want);
		if(b == nil)
			continue;
		p = b->data;
		ep = p+b->len;
		while(p < ep){
			de = (Dirent*)p;
			if(de->reclen == 0){
				if(debug)
					fprint(2, "reclen 0 at offset %d of %d\n", (int)(p-b->data), b->len);
				break;
			}
			p += de->reclen;
			if(p > ep){
				if(debug)
					fprint(2, "bad len %d at offset %d of %d\n", de->reclen, (int)(p-b->data), b->len);
				break;
			}
			if(de->ino == 0)
				continue;
			if(4+2+2+de->namlen > de->reclen){
				if(debug)
					fprint(2, "bad namelen %d at offset %d of %d\n", de->namlen, (int)(p-b->data), b->len);
				break;
			}
			if(de->namlen == len && memcmp(de->name, name, len) == 0){
				mkhandle(nh, de->ino);
				blockput(b);
				return Nfs3Ok;
			}
		}
		blockput(b);
	}
	return Nfs3ErrNoEnt;
}

static Nfs3Status
ffsreaddir(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count, u64int cookie, uchar **pdata, u32int *pcount, u1int *peof)
{
	u32int nblock;
	u32int i;
	int off, done;
	uchar *data, *dp, *dep, *p, *ep, *ndp;
	Dirent *de;
	Inode ino;
	Block *b;
	Ffs *fs;
	Nfs3Status ok;
	Nfs3Entry e;
	int want;

	fs = fsys->priv;
	if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok)
		return ok;

	if((ino.mode&IFMT) != IFDIR)
		return Nfs3ErrNotDir;

	if((ok = inoperm(&ino, au, AREAD)) != Nfs3Ok)
		return ok;

	if(cookie >= ino.size){
		*peof = 1;
		*pcount = 0;
		*pdata = 0;
		return Nfs3Ok;
	}

	dp = malloc(count);
	data = dp;
	if(dp == nil)
		return Nfs3ErrNoMem;
	dep = dp+count;
	*peof = 0;
	nblock = (ino.size+fs->blocksize-1) / fs->blocksize;
	i = cookie/fs->blocksize;
	off = cookie%fs->blocksize;
	done = 0;
	for(; i<nblock && !done; i++){
		if(i==nblock-1)
			want = ino.size % fs->blocksize;
		else
			want = fs->blocksize;
		b = ffsfileblock(fs, &ino, i, want);
		if(b == nil)
			continue;
		p = b->data;
		ep = p+b->len;
		memset(&e, 0, sizeof e);
		while(p < ep){
			de = (Dirent*)p;
			if(de->reclen == 0){
				if(debug) fprint(2, "reclen 0 at offset %d of %d\n", (int)(p-b->data), b->len);
				break;
			}
			p += de->reclen;
			if(p > ep){
				if(debug) fprint(2, "reclen %d at offset %d of %d\n", de->reclen, (int)(p-b->data), b->len);
				break;
			}
			if(de->ino == 0){
				if(debug) fprint(2, "zero inode\n");
				continue;
			}
			if(4+2+2+de->namlen > de->reclen){
				if(debug) fprint(2, "bad namlen %d reclen %d at offset %d of %d\n", de->namlen, de->reclen, (int)(p-b->data), b->len);
				break;
			}
			if(de->name[de->namlen] != 0){
				if(debug) fprint(2, "bad name %d %.*s\n", de->namlen, de->namlen, de->name);
				continue;
			}
			if(debug) print("%s/%d ", de->name, (int)de->ino);
			if((uchar*)de - b->data < off)
				continue;
			e.fileid = de->ino;
			e.name = de->name;
			e.namelen = de->namlen;
			e.cookie = (u64int)i*fs->blocksize + (p - b->data);
			if(nfs3entrypack(dp, dep, &ndp, &e) < 0){
				done = 1;
				break;
			}
			dp = ndp;
		}
		off = 0;
		blockput(b);
	}
	if(i==nblock)
		*peof = 1;

	*pcount = dp - data;
	*pdata = data;
	return Nfs3Ok;
}

static u64int
ffsxfileblock(Fsys *fsys, Nfs3Handle *h, u64int offset)
{
	u64int 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)	/* clumsy hack for debugging */
		return lastiaddr;
	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
ffsreadfile(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count,
	u64int offset, uchar **pdata, u32int *pcount, u1int *peof)
{
	uchar *data;
	Block *b;
	Ffs *fs;
	int off, want, fragcount;
	Inode ino;
	Nfs3Status ok;

	fs = fsys->priv;
	if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok)
		return ok;

	if((ok = inoperm(&ino, au, AREAD)) != Nfs3Ok)
		return ok;

	if(offset >= ino.size){
		*pdata = 0;
		*pcount = 0;
		*peof = 1;
		return Nfs3Ok;
	}
	if(offset+count > ino.size)
		count = ino.size-offset;
	if(offset/fs->blocksize != (offset+count-1)/fs->blocksize)
		count = fs->blocksize - offset%fs->blocksize;

	data = malloc(count);
	if(data == nil)
		return Nfs3ErrNoMem;

	want = offset%fs->blocksize+count;
	if(want%fs->fragsize)
		want += fs->fragsize - want%fs->fragsize;

	b = ffsfileblock(fs, &ino, offset/fs->blocksize, want);
	if(b == nil){
		/* BUG: distinguish sparse file from I/O error */
		memset(data, 0, count);
	}else{
		off = offset%fs->blocksize;
		fragcount = count;	/* need signed variable */
		if(off+fragcount > b->len){
			fragcount = b->len - off;
			if(fragcount < 0)
				fragcount = 0;
		}
		if(fragcount > 0)
			memmove(data, b->data+off, fragcount);
		count = fragcount;
		blockput(b);
	}
	*peof = (offset+count == ino.size);
	*pcount = count;
	*pdata = data;
	return Nfs3Ok;
}

static Nfs3Status
ffsreadlink(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char **link)
{
	Ffs *fs;
	Nfs3Status ok;
	int len;
	Inode ino;
	Block *b;

	fs = fsys->priv;
	if((ok = handle2ino(fs, h, nil, &ino)) != Nfs3Ok)
		return ok;
	if((ok = inoperm(&ino, au, AREAD)) != Nfs3Ok)
		return ok;

	if(ino.size > 1024)
		return Nfs3ErrIo;
	len = ino.size;

	if(ino.nblock != 0){
		/* assumes symlink fits in one block */
		b = ffsfileblock(fs, &ino, 0, len);
		if(b == nil)
			return Nfs3ErrIo;
		if(memchr(b->data, 0, len) != nil){
			blockput(b);
			return Nfs3ErrIo;
		}
		*link = malloc(len+1);
		if(*link == 0){
			blockput(b);
			return Nfs3ErrNoMem;
		}
		memmove(*link, b->data, len);
		(*link)[len] = 0;
		blockput(b);
		return Nfs3Ok;
	}

	if(len > sizeof ino.db + sizeof ino.ib)
		return Nfs3ErrIo;

	*link = malloc(len+1);
	if(*link == 0)
		return Nfs3ErrNoMem;
	memmove(*link, ino.db, ino.size);
	(*link)[len] = 0;
	return Nfs3Ok;
}
