From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <955d5a290dab26febdf399145b6c5471@quanstro.net> From: erik quanstrom Date: Mon, 10 Aug 2009 10:41:28 -0400 To: 9fans@9fans.net MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Subject: [9fans] bind vs. 9660srv Topicbox-Message-UUID: 409d36a4-ead5-11e9-9d60-3106f5b1d025 i mentioned a few days ago that bind and 9660srv were not agreeing. i tracked this down a bit further and am now quite confused. here's the initial symptom ; 9660srv ; mount /srv/9660 /n/cd0 /n/other/ftp/plan9.iso ; du -s /n/cd0/386/bin 80143 /n/cd1/386/bin but then through if i bind over an entry served by 9660srv, i see this error. ; bind /386/bin/awk /n/cd0/386/bin/awk ; du -s /n/cd0/386/bin du: /n/cd1/386/bin: seek in directory 55724 /n/cd1/386/bin a quick look shows that /sys/src/cmd/9660srv/9660srv.c:346 is the source of the error and read(5) indicates that this really is an error. the bug must be induced by whoever is getting the offset wrong, since directory offsets must either continue at the previous offset or 0; seek is not allowed (note: ramfs does not exhibit this behavior.) if i add a little debugging to 9660srv, i get du: /n/cd1/386/bin: seek in directory offset 8198 != dp->doffset 8190 and if i add a little more, i find that the closest doffset set is at the entry "page" [PAGE] ip->doffset = offset 0 + rcnt 8190 = 8190 i'm quite puzzled by why binding in an entry (which 9660srv should not know about) would cause the offset to be wrong. this seems like a bug in the kernel. i'm fighting that conclusion, though. one would think that this problem would have reared its head before. on a bit further inspection of sysfile:/^mountfix, i think the problem might be that the winning bind spans buffers. - erik ps. this workaround, similar to the code in ramfs does "work" but it contradicts read(5), so it must be wrong. static long ireaddir(Xfile *f, uchar *buf, long offset, long count) { Isofile *ip = f->ptr; Dir d; char names[4*Maxname]; uchar dbuf[256]; Drec *drec = (Drec *)dbuf; int n, rcnt; if(offset==0 || offset != ip->doffset){ ip->offset = 0; ip->doffset = offset; }else offset = 0; rcnt = 0; setnames(&d, names); while(rcnt < count && getdrec(f, drec) >= 0){ if(drec->namelen == 1){ if(drec->name[0] == 0) continue; if(drec->name[0] == 1) continue; } rzdir(f->xf, &d, ip->fmt, drec); d.qid.vers = f->qid.vers; if((n = convD2M(&d, buf+rcnt, count-rcnt)) <= BIT16SZ){ ungetdrec(f); break; } if(offset > 0) offset -= n; if(offset <= 0) rcnt += n; } ip->doffset += rcnt; return rcnt; }