9pfuse: always return . and ..

This commit is contained in:
Russ Cox 2008-07-04 12:16:53 -04:00
parent 869875b48b
commit 9ec57f8b9e

View file

@ -855,6 +855,7 @@ fusereadlink(FuseMsg *m)
* are stored in m->d,nd,d0. * are stored in m->d,nd,d0.
*/ */
int canpack(Dir*, uvlong, uchar**, uchar*); int canpack(Dir*, uvlong, uchar**, uchar*);
Dir *dotdirs(CFid*);
void void
fusereaddir(FuseMsg *m) fusereaddir(FuseMsg *m)
{ {
@ -871,9 +872,8 @@ fusereaddir(FuseMsg *m)
if(in->offset == 0){ if(in->offset == 0){
fsseek(ff->fid, 0, 0); fsseek(ff->fid, 0, 0);
free(ff->d0); free(ff->d0);
ff->d0 = nil; ff->d0 = ff->d = dotdirs(ff->fid);
ff->d = nil; ff->nd = 2;
ff->nd = 0;
} }
n = in->size; n = in->size;
if(n > fusemaxwrite) if(n > fusemaxwrite)
@ -906,6 +906,31 @@ out:
free(buf); free(buf);
} }
/*
* Fuse assumes that it can always read two directory entries.
* If it gets just one, it will double it in the dirread results.
* Thus if a directory contains just "a", you see "a" twice.
* Adding . as the first directory entry works around this.
* We could add .. too, but it isn't necessary.
*/
Dir*
dotdirs(CFid *f)
{
Dir *d;
CFid *f1;
d = emalloc(2*sizeof *d);
d[0].name = ".";
d[0].qid = fsqid(f);
d[1].name = "..";
f1 = fswalk(f, "..");
if(f1){
d[1].qid = fsqid(f1);
fsclose(f1);
}
return d;
}
int int
canpack(Dir *d, uvlong off, uchar **pp, uchar *ep) canpack(Dir *d, uvlong off, uchar **pp, uchar *ep)
{ {