📄 cfs.c
字号:
}voidrclunk(Mfile *mf){ if(!mf->busy){ sendreply(0); return; } mf->busy = 0; delegate();}voidrremove(Mfile *mf){ if(statson && ctltest(mf)){ sendreply("not removed"); return; } mf->busy = 0; delegate();}voidrread(Mfile *mf){ int cnt; long off, first; char *cp; Ibuf *b; long n; char data[MAXFDATA]; int done; first = off = c.thdr.offset; cnt = c.thdr.count; if(statson && ctltest(mf)){ if(cnt > statlen-off) c.rhdr.count = statlen-off; else c.rhdr.count = cnt; if((int)c.rhdr.count < 0){ sendreply("eof"); return; } c.rhdr.data = statbuf + off; sendreply(0); return; } if(mf->qid.type & (QTDIR|QTAUTH)){ delegate(); if (statson) { cfsstat.ndirread++; if(c.rhdr.count > 0){ cfsstat.bytesread += c.rhdr.count; cfsstat.bytesfromdirs += c.rhdr.count; } } return; } b = iget(&ic, mf->qid); if(b == 0){ DPRINT(2, "delegating read\n"); delegate(); if (statson){ cfsstat.ndelegateread++; if(c.rhdr.count > 0){ cfsstat.bytesread += c.rhdr.count; cfsstat.bytesfromserver += c.rhdr.count; } } return; } cp = data; done = 0; while(cnt>0 && !done){ if(off >= b->inode.length){ DPRINT(2, "offset %ld greater than length %lld\n", off, b->inode.length); break; } n = fread(&ic, b, cp, off, cnt); if(n <= 0){ n = -n; if(n==0 || n>cnt) n = cnt; DPRINT(2, "fetch %ld bytes of data from server at offset %ld\n", n, off); s.thdr.type = c.thdr.type; s.thdr.fid = c.thdr.fid; s.thdr.tag = c.thdr.tag; s.thdr.offset = off; s.thdr.count = n; if(statson){ cfsstat.ndelegateread++; } if(askserver() < 0){ sendreply(s.rhdr.ename); return; } if(s.rhdr.count != n) done = 1; n = s.rhdr.count; if(n == 0){ /* end of file */ if(b->inode.length > off){ DPRINT(2, "file %llud.%ld, length %ld\n", b->inode.qid.path, b->inode.qid.vers, off); b->inode.length = off; } break; } memmove(cp, s.rhdr.data, n); fwrite(&ic, b, cp, off, n); if (statson){ cfsstat.bytestocache += n; cfsstat.bytesfromserver += n; } }else{ DPRINT(2, "fetched %ld bytes from cache\n", n); if(statson){ cfsstat.bytesfromcache += n; } } cnt -= n; off += n; cp += n; } c.rhdr.data = data; c.rhdr.count = off - first; if(statson){ cfsstat.bytesread += c.rhdr.count; } sendreply(0);}voidrwrite(Mfile *mf){ Ibuf *b; char buf[MAXFDATA]; if(statson && ctltest(mf)){ sendreply("read only"); return; } if(mf->qid.type & (QTDIR|QTAUTH)){ delegate(); if(statson && c.rhdr.count > 0) cfsstat.byteswritten += c.rhdr.count; return; } memmove(buf, c.thdr.data, c.thdr.count); if(delegate() < 0) return; if(s.rhdr.count > 0) cfsstat.byteswritten += s.rhdr.count; if(mf->qid.type & QTAPPEND) /* don't modify our cache for append-only data; always read from server*/ return; b = iget(&ic, mf->qid); if(b == 0) return; if (b->inode.length < c.thdr.offset + s.rhdr.count) b->inode.length = c.thdr.offset + s.rhdr.count; mf->qid.vers++; if (s.rhdr.count != c.thdr.count) syslog(0, "cfslog", "rhdr.count %ud, thdr.count %ud\n", s.rhdr.count, c.thdr.count); if(fwrite(&ic, b, buf, c.thdr.offset, s.rhdr.count) == s.rhdr.count){ iinc(&ic, b); if(statson) cfsstat.bytestocache += s.rhdr.count; }}voidrstat(Mfile *mf){ Dir d; if(statson && ctltest(mf)){ genstats(); d.qid = ctlqid; d.mode = 0444; d.length = statlen; /* would be nice to do better */ d.name = "cfsctl"; d.uid = "none"; d.gid = "none"; d.muid = "none"; d.atime = time(nil); d.mtime = d.atime; c.rhdr.nstat = convD2M(&d, c.rhdr.stat, sizeof(c.rhdr) - (c.rhdr.stat - (uchar*)&c.rhdr)); sendreply(0); return; } if(delegate() == 0){ Ibuf *b; convM2D(s.rhdr.stat, s.rhdr.nstat , &d, nil); mf->qid = d.qid; b = iget(&ic, mf->qid); if(b) b->inode.length = d.length; }}voidrwstat(Mfile *mf){ Ibuf *b; if(statson && ctltest(mf)){ sendreply("read only"); return; } delegate(); if(b = iget(&ic, mf->qid)) b->inode.length = MAXLEN;}voiderror(char *fmt, ...) { va_list arg; static char buf[2048]; va_start(arg, fmt); vseprint(buf, buf+sizeof(buf), fmt, arg); va_end(arg); fprint(2, "%s: %s\n", argv0, buf); exits("error");}voidwarning(char *s){ fprint(2, "cfs: %s: %r\n", s);}/* * send a reply to the client */voidsendreply(char *err){ if(err){ c.rhdr.type = Rerror; c.rhdr.ename = err; }else{ c.rhdr.type = c.thdr.type+1; c.rhdr.fid = c.thdr.fid; } c.rhdr.tag = c.thdr.tag; sendmsg(&c, &c.rhdr);}/* * send a request to the server, get the reply, and send that to * the client */intdelegate(void){ int type; type = c.thdr.type; if(statson){ cfsstat.sm[type].n++; cfsstat.sm[type].s = nsec(); } sendmsg(&s, &c.thdr); rcvmsg(&s, &s.rhdr); if(statson){ cfsstat.sm[type].t += nsec() - cfsstat.sm[type].s; } sendmsg(&c, &s.rhdr); return c.thdr.type+1 == s.rhdr.type ? 0 : -1;}/* * send a request to the server and get a reply */intaskserver(void){ int type; s.thdr.tag = c.thdr.tag; type = s.thdr.type; if(statson){ cfsstat.sm[type].n++; cfsstat.sm[type].s = nsec(); } sendmsg(&s, &s.thdr); rcvmsg(&s, &s.rhdr); if(statson){ cfsstat.sm[type].t += nsec() - cfsstat.sm[type].s; } return s.thdr.type+1 == s.rhdr.type ? 0 : -1;}/* * send/receive messages with logging */voidsendmsg(P9fs *p, Fcall *f){ DPRINT(2, "->%s: %F\n", p->name, f); p->len = convS2M(f, datasnd, messagesize); if(p->len <= 0) error("convS2M"); if(write(p->fd[1], datasnd, p->len)!=p->len) error("sendmsg");}voiddump(uchar *p, int len){ fprint(2, "%d bytes", len); while(len > 0){ fprint(2, " %.2ux", *p++); len--; } fprint(2, "\n");}voidrcvmsg(P9fs *p, Fcall *f){ int olen, rlen; char buf[128]; olen = p->len; p->len = read9pmsg(p->fd[0], datarcv, sizeof(datarcv)); if(p->len <= 0){ sprint(buf, "read9pmsg(%d)->%ld: %r", p->fd[0], p->len); error(buf); } if((rlen = convM2S(datarcv, p->len, f)) != p->len) error("rcvmsg format error, expected length %d, got %d", rlen, p->len); if(f->fid >= Nfid){ fprint(2, "<-%s: %d %s on %d\n", p->name, f->type, mname[f->type]? mname[f->type] : "mystery", f->fid); dump((uchar*)datasnd, olen); dump((uchar*)datarcv, p->len); error("rcvmsg fid out of range"); } DPRINT(2, "<-%s: %F\n", p->name, f);}intctltest(Mfile *mf){ return mf->busy && mf->qid.type == ctlqid.type && mf->qid.path == ctlqid.path;}voidgenstats(void){ int i; char *p; p = statbuf; p += snprint(p, sizeof(statbuf)+statbuf-p, " Client Server\n"); p += snprint(p, sizeof(statbuf)+statbuf-p, " #calls Δ ms/call Δ #calls Δ ms/call Δ\n"); for (i = 0; i < nelem(cfsstat.cm); i++) if(cfsstat.cm[i].n || cfsstat.sm[i].n) { p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ", cfsstat.cm[i].n, cfsstat.cm[i].n - cfsprev.cm[i].n); if (cfsstat.cm[i].n) p += snprint(p, sizeof(statbuf)+statbuf-p, "%7.3f ", 0.000001*cfsstat.cm[i].t/cfsstat.cm[i].n); else p += snprint(p, sizeof(statbuf)+statbuf-p, " "); if(cfsstat.cm[i].n - cfsprev.cm[i].n) p += snprint(p, sizeof(statbuf)+statbuf-p, "%7.3f ", 0.000001*(cfsstat.cm[i].t - cfsprev.cm[i].t)/(cfsstat.cm[i].n - cfsprev.cm[i].n)); else p += snprint(p, sizeof(statbuf)+statbuf-p, " "); p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ", cfsstat.sm[i].n, cfsstat.sm[i].n - cfsprev.sm[i].n); if (cfsstat.sm[i].n) p += snprint(p, sizeof(statbuf)+statbuf-p, "%7.3f ", 0.000001*cfsstat.sm[i].t/cfsstat.sm[i].n); else p += snprint(p, sizeof(statbuf)+statbuf-p, " "); if(cfsstat.sm[i].n - cfsprev.sm[i].n) p += snprint(p, sizeof(statbuf)+statbuf-p, "%7.3f ", 0.000001*(cfsstat.sm[i].t - cfsprev.sm[i].t)/(cfsstat.sm[i].n - cfsprev.sm[i].n)); else p += snprint(p, sizeof(statbuf)+statbuf-p, " "); p += snprint(p, sizeof(statbuf)+statbuf-p, "%s\n", mname[i]); } p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ndirread\n", cfsstat.ndirread, cfsstat.ndirread - cfsprev.ndirread); p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ndelegateread\n", cfsstat.ndelegateread, cfsstat.ndelegateread - cfsprev.ndelegateread); p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ninsert\n", cfsstat.ninsert, cfsstat.ninsert - cfsprev.ninsert); p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ndelete\n", cfsstat.ndelete, cfsstat.ndelete - cfsprev.ndelete); p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud nupdate\n", cfsstat.nupdate, cfsstat.nupdate - cfsprev.nupdate); p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud bytesread\n", cfsstat.bytesread, cfsstat.bytesread - cfsprev.bytesread); p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud byteswritten\n", cfsstat.byteswritten, cfsstat.byteswritten - cfsprev.byteswritten); p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud bytesfromserver\n", cfsstat.bytesfromserver, cfsstat.bytesfromserver - cfsprev.bytesfromserver); p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud bytesfromdirs\n", cfsstat.bytesfromdirs, cfsstat.bytesfromdirs - cfsprev.bytesfromdirs); p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud bytesfromcache\n", cfsstat.bytesfromcache, cfsstat.bytesfromcache - cfsprev.bytesfromcache); p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud bytestocache\n", cfsstat.bytestocache, cfsstat.bytestocache - cfsprev.bytestocache); statlen = p - statbuf; cfsprev = cfsstat;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -