Same story as before.

This commit is contained in:
Kris Maglione 2006-06-15 15:30:03 -04:00
parent a4cf1b6fde
commit c8bff01914
2 changed files with 100 additions and 91 deletions

View File

@ -12,7 +12,8 @@ P9Srv p9srv = {
.write= fs_write, .write= fs_write,
.attach=fs_attach, .attach=fs_attach,
.create=fs_create, .create=fs_create,
.remove=fs_remove .remove=fs_remove,
.freefid=fs_freefid
}; };
#define QID(t, i) (((long long)((t)&0xFF)<<32)|((i)&0xFFFFFFFF)) #define QID(t, i) (((long long)((t)&0xFF)<<32)|((i)&0xFFFFFFFF))
@ -133,6 +134,16 @@ get_file() {
return temp; return temp;
} }
/* Convenience func: */
/* ugly, though... */
FileId *
push_file(FileId ***last) {
FileId *ret = get_file();
**last = ret;
*last = &ret->next;
return ret;
}
static void static void
free_file(FileId *f) { free_file(FileId *f) {
if(--f->nref) if(--f->nref)
@ -161,117 +172,101 @@ lookup_file(FileId *parent, char *name)
if(!(parent->tab.perm & DMDIR)) if(!(parent->tab.perm & DMDIR))
return nil; return nil;
Dirtab *dir = dirtab[parent->tab.type]; Dirtab *dir = dirtab[parent->tab.type];
FileId *ret = nil, *temp, **last = &ret; FileId *ret = nil, *file, **last = &ret;
for(; dir->name; dir++) { for(; dir->name; dir++) {
/* Dynamic dirs */
if(!*dir->name) { /* strlen(dir->name) == 0 */ if(!*dir->name) { /* strlen(dir->name) == 0 */
switch(parent->tab.type) { switch(parent->tab.type) {
case FsDClients: case FsDClients:
if(!name || !strncmp(name, "sel", 4)) { if(!name || !strncmp(name, "sel", 4)) {
if((c = sel_client())) { if((c = sel_client())) {
temp = get_file(); file = push_file(&last);
*last = temp; file->ref = c;
last = &temp->next; file->id = c->id;
temp->ref = c; file->index = idx_of_client(c);
temp->id = c->id; file->tab = *dirtab[FsDSClient];
temp->index = idx_of_client(c); file->tab.name = strdup("sel");
temp->tab = *dirtab[FsDSClient]; }if(name) goto LastItem;
temp->tab.name = strdup("sel");
}
if(name)
goto LastItem;
} }
if(name) { if(name) {
id = (unsigned int)strtol(name, &name, 10); id = (unsigned int)strtol(name, &name, 10);
if(*name) if(*name) goto NextItem;
continue;
} }
i=0; i=0;
for(c=client; c; c=c->next, i++) { for(c=client; c; c=c->next, i++) {
if(name && i != id) if(!name || i == id) {
continue; file = push_file(&last);
temp = get_file(); file->ref = c;
*last = temp; file->id = c->id;
last = &temp->next; file->tab = *dir;
temp->ref = c; asprintf(&file->tab.name, "%d", i);
temp->id = c->id; if(name) goto LastItem;
temp->tab = *dir; }
asprintf(&temp->tab.name, "%d", i);
if(name)
goto LastItem;
} }
break; break;
case FsDTags: case FsDTags:
if(!name || !strncmp(name, "sel", 4)) { if(!name || !strncmp(name, "sel", 4)) {
if(sel) { if(sel) {
temp = get_file(); file = push_file(&last);
*last = temp; file->ref = sel;
last = &temp->next; file->id = sel->id;
temp->ref = sel; file->tab = *dir;
temp->id = sel->id; file->tab.name = strdup("sel");
temp->tab = *dir; }if(name) goto LastItem;
temp->tab.name = strdup("sel");
}
if(name)
goto LastItem;
} }
for(v=view; v; v=v->next) { for(v=view; v; v=v->next) {
if(name && strcmp(name, v->name)) if(!name || !strcmp(name, v->name)) {
continue; file = push_file(&last);
temp = get_file(); file->ref = v;
*last = temp; file->id = v->id;
last = &temp->next; file->tab = *dir;
temp->ref = v; file->tab.name = strdup(v->name);
temp->id = v->id; if(name) goto LastItem;
temp->tab = *dir; }
temp->tab.name = strdup(v->name);
if(name)
goto LastItem;
} }
break; break;
case FsDRBar: case FsDRBar:
case FsDLBar: case FsDLBar:
for(b=parent->ref; b; b=b->next) { for(b=parent->ref; b; b=b->next) {
if(!name || strcmp(name, b->name)) { if(!name || !strcmp(name, b->name)) {
temp = get_file(); file = push_file(&last);
*last = temp; file->ref = b;
last = &temp->next; file->id = b->id;
temp->ref = b; file->tab = *dir;
temp->id = b->id; file->tab.name = strdup(b->name);
temp->tab = *dir; if(name) goto LastItem;
temp->tab.name = strdup(b->name);
if(name)
goto LastItem;
} }
} }
break;
} }
}else }else /* Static dirs */
if(!name || !strcmp(name, dir->name)) { if(!name || !strcmp(name, dir->name)) {
temp = get_file(); file = push_file(&last);
*last = temp; file->id = 0;
last = &temp->next; file->ref = nil;
temp->id = 0; file->tab = *dir;
temp->ref = nil;
temp->tab = *dir;
switch(temp->tab.type) { /* Special considerations: */
switch(file->tab.type) {
case FsDLBar: case FsDLBar:
temp->ref = lbar; file->ref = lbar;
break; break;
case FsDRBar: case FsDRBar:
temp->ref = rbar; file->ref = rbar;
break; break;
case FsFColRules: case FsFColRules:
temp->ref = vrule; file->ref = vrule;
break; break;
case FsFTagRules: case FsFTagRules:
temp->ref = trule; file->ref = trule;
break; break;
} }
if(name) if(name) goto LastItem;
break;
} }
NextItem:
continue;
} }
LastItem: LastItem:
*last = nil; *last = nil;
@ -301,27 +296,28 @@ fs_walk(Req *r) {
r->ofcall.wqid[i].type = f->tab.qtype; r->ofcall.wqid[i].type = f->tab.qtype;
r->ofcall.wqid[i].path = QID(f->tab.type, f->id); r->ofcall.wqid[i].path = QID(f->tab.type, f->id);
} }
/* XXX: This will not be necessary once a free_fid
* function is implemented */
if(i < r->ifcall.nwname) { if(i < r->ifcall.nwname) {
while((nf = f)) { while((nf = f)) {
f=f->next; f=f->next;
free_file(nf); free_file(nf);
} }
return respond(r, Enofile); return respond(r, Enofile);
}else }
/* Remove refs for r->fid if no new fid */
/* If Fids were ref counted, this could be
* done in their decref function */
if(r->ifcall.fid == r->ifcall.newfid) { if(r->ifcall.fid == r->ifcall.newfid) {
nf=r->fid->aux; nf=r->fid->aux;
r->fid->aux = f; r->fid->aux = f;
for(; nf; nf=f) { for(; nf; nf=f) {
f = nf->next; f = nf->next;
free(nf); free_file(nf);
} }
} }
if(r->ifcall.nwname == 0)
r->newfid->qid = r->fid->qid;
else
r->newfid->qid = r->ofcall.wqid[i-1];
r->newfid->aux = f; r->newfid->aux = f;
r->ofcall.nwqid = i; r->ofcall.nwqid = i;
respond(r, nil); respond(r, nil);
@ -361,7 +357,7 @@ fs_read(Req *r) {
buf = cext_emallocz(size); buf = cext_emallocz(size);
r->ofcall.data = buf; r->ofcall.data = buf;
f = lookup_file(f, nil); tf = f = lookup_file(f, nil);
/* Note: f->tab.name == "."; goto next */ /* Note: f->tab.name == "."; goto next */
for(f=f->next; f; f=f->next) { for(f=f->next; f; f=f->next) {
dostat(&s, 0, f); dostat(&s, 0, f);
@ -374,9 +370,9 @@ fs_read(Req *r) {
offset += n; offset += n;
} }
while((tf = f)) { while((f = tf)) {
f = f->next; tf = tf->next;
free_file(tf); free_file(f);
} }
r->ofcall.count = r->ifcall.count - size; r->ofcall.count = r->ifcall.count - size;
@ -408,6 +404,15 @@ fs_open(Req *r) {
respond(r, nil); respond(r, nil);
} }
void
fs_freefid(Fid *f) {
FileId *id = f->aux, *tid;
while((tid = id)) {
id = id->next;
free_file(tid);
}
}
void void
fs_remove(Req *r) { fs_remove(Req *r) {
respond(r, "not implemented"); respond(r, "not implemented");

View File

@ -31,7 +31,7 @@ static char
Edupfid[] = "fid in use", Edupfid[] = "fid in use",
Enofunc[] = "function not implemented", Enofunc[] = "function not implemented",
Ebotch[] = "9P protocol botch", Ebotch[] = "9P protocol botch",
Enofile[] = "the requested file does not exist", Enofile[] = "file does not exist",
Enofid[] = "fid does not exist", Enofid[] = "fid does not exist",
Enotdir[] = "not a directory", Enotdir[] = "not a directory",
Eisdir[] = "cannot perform operation on a directory"; Eisdir[] = "cannot perform operation on a directory";
@ -82,6 +82,7 @@ ixp_handle_req(Req *r)
{ {
P9Conn *pc = r->conn->aux; P9Conn *pc = r->conn->aux;
P9Srv *srv = pc->srv; P9Srv *srv = pc->srv;
Fid *f;
switch(r->ifcall.type) { switch(r->ifcall.type) {
default: default:
@ -106,8 +107,11 @@ ixp_handle_req(Req *r)
srv->attach(r); srv->attach(r);
break; break;
case TCLUNK: case TCLUNK:
if(!destroyfid(&pc->fidmap, r->ifcall.fid)) if(!(f=deletekey(&pc->fidmap, r->ifcall.fid)))
return respond(r, Enofid); return respond(r, Enofid);
if(pc->srv->freefid)
pc->srv->freefid(f);
free(f);
respond(r, nil); respond(r, nil);
break; break;
case TCREATE: case TCREATE:
@ -193,6 +197,7 @@ respond(Req *r, char *error) {
break; break;
case TVERSION: case TVERSION:
cext_assert(!error); cext_assert(!error);
free(r->ifcall.version);
pc->msize = (r->ofcall.msize < IXP_MAX_MSG) ? r->ofcall.msize : IXP_MAX_MSG; pc->msize = (r->ofcall.msize < IXP_MAX_MSG) ? r->ofcall.msize : IXP_MAX_MSG;
free(pc->buf); free(pc->buf);
pc->buf = cext_emallocz(r->ofcall.msize); pc->buf = cext_emallocz(r->ofcall.msize);
@ -200,6 +205,8 @@ respond(Req *r, char *error) {
case TATTACH: case TATTACH:
if(error) if(error)
destroyfid(r->fid->map, r->fid->fid); destroyfid(r->fid->map, r->fid->fid);
free(r->ifcall.uname);
free(r->ifcall.aname);
break; break;
case TOPEN: case TOPEN:
case TCREATE: case TCREATE:
@ -207,6 +214,7 @@ respond(Req *r, char *error) {
r->fid->omode = r->ofcall.mode; r->fid->omode = r->ofcall.mode;
r->fid->qid = r->ofcall.qid; r->fid->qid = r->ofcall.qid;
} }
free(r->ifcall.name);
r->ofcall.iounit = pc->msize - sizeof(unsigned long); r->ofcall.iounit = pc->msize - sizeof(unsigned long);
break; break;
case TWALK: case TWALK:
@ -221,12 +229,15 @@ respond(Req *r, char *error) {
else else
r->newfid->qid = r->ofcall.wqid[r->ofcall.nwqid-1]; r->newfid->qid = r->ofcall.wqid[r->ofcall.nwqid-1];
} }
free(*r->ifcall.wname);
break;
case TWRITE:
free(r->ifcall.data);
break; break;
case TCLUNK: case TCLUNK:
case TREAD: case TREAD:
case TREMOVE: case TREMOVE:
case TSTAT: case TSTAT:
case TWRITE:
break; break;
/* Still to be implemented: flush, wstat, auth */ /* Still to be implemented: flush, wstat, auth */
} }
@ -250,13 +261,6 @@ respond(Req *r, char *error) {
free(r->ofcall.data); free(r->ofcall.data);
break; break;
} }
switch(r->ifcall.type) {
case TWALK:
free(*r->ifcall.wname);
break;
case TWRITE:
free(r->ifcall.data);
}
deletekey(&pc->tagmap, r->ifcall.tag);; deletekey(&pc->tagmap, r->ifcall.tag);;
free(r); free(r);