13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
3219b2ee8SDavid du Colombier #include <auth.h>
43e12c5d1SDavid du Colombier #include <fcall.h>
53e12c5d1SDavid du Colombier
63e12c5d1SDavid du Colombier #include "cformat.h"
73e12c5d1SDavid du Colombier #include "lru.h"
83e12c5d1SDavid du Colombier #include "bcache.h"
93e12c5d1SDavid du Colombier #include "disk.h"
103e12c5d1SDavid du Colombier #include "inode.h"
113e12c5d1SDavid du Colombier #include "file.h"
129a747e4fSDavid du Colombier #include "stats.h"
133e12c5d1SDavid du Colombier
143e12c5d1SDavid du Colombier enum
153e12c5d1SDavid du Colombier {
167dd7cddfSDavid du Colombier Nfid= 10240,
173e12c5d1SDavid du Colombier };
183e12c5d1SDavid du Colombier
199a747e4fSDavid du Colombier /* maximum length of a file */
20*2bef681aSDavid du Colombier enum { MAXLEN = ~0ULL >> 1 };
213e12c5d1SDavid du Colombier
223e12c5d1SDavid du Colombier typedef struct Mfile Mfile;
233e12c5d1SDavid du Colombier typedef struct Ram Ram;
243e12c5d1SDavid du Colombier typedef struct P9fs P9fs;
253e12c5d1SDavid du Colombier
263e12c5d1SDavid du Colombier struct Mfile
273e12c5d1SDavid du Colombier {
283e12c5d1SDavid du Colombier Qid qid;
293e12c5d1SDavid du Colombier char busy;
303e12c5d1SDavid du Colombier };
313e12c5d1SDavid du Colombier
323e12c5d1SDavid du Colombier Mfile mfile[Nfid];
333e12c5d1SDavid du Colombier Icache ic;
34*2bef681aSDavid du Colombier int debug, statson, noauth, openserver;
353e12c5d1SDavid du Colombier
363e12c5d1SDavid du Colombier struct P9fs
373e12c5d1SDavid du Colombier {
383e12c5d1SDavid du Colombier int fd[2];
393e12c5d1SDavid du Colombier Fcall rhdr;
403e12c5d1SDavid du Colombier Fcall thdr;
413e12c5d1SDavid du Colombier long len;
423e12c5d1SDavid du Colombier char *name;
433e12c5d1SDavid du Colombier };
443e12c5d1SDavid du Colombier
453e12c5d1SDavid du Colombier P9fs c; /* client conversation */
463e12c5d1SDavid du Colombier P9fs s; /* server conversation */
473e12c5d1SDavid du Colombier
489a747e4fSDavid du Colombier struct Cfsstat cfsstat, cfsprev;
499a747e4fSDavid du Colombier char statbuf[2048];
509a747e4fSDavid du Colombier int statlen;
513e12c5d1SDavid du Colombier
529a747e4fSDavid du Colombier #define MAXFDATA 8192 /* i/o size for read/write */
539a747e4fSDavid du Colombier
549a747e4fSDavid du Colombier int messagesize = MAXFDATA+IOHDRSZ;
559a747e4fSDavid du Colombier
569a747e4fSDavid du Colombier uchar datasnd[MAXFDATA + IOHDRSZ];
579a747e4fSDavid du Colombier uchar datarcv[MAXFDATA + IOHDRSZ];
589a747e4fSDavid du Colombier
599a747e4fSDavid du Colombier Qid rootqid;
609a747e4fSDavid du Colombier Qid ctlqid = {0x5555555555555555LL, 0, 0};
619a747e4fSDavid du Colombier
629a747e4fSDavid du Colombier void rversion(void);
639a747e4fSDavid du Colombier void rauth(Mfile*);
643e12c5d1SDavid du Colombier void rflush(void);
653e12c5d1SDavid du Colombier void rattach(Mfile*);
663e12c5d1SDavid du Colombier void rwalk(Mfile*);
673e12c5d1SDavid du Colombier void ropen(Mfile*);
683e12c5d1SDavid du Colombier void rcreate(Mfile*);
693e12c5d1SDavid du Colombier void rread(Mfile*);
703e12c5d1SDavid du Colombier void rwrite(Mfile*);
713e12c5d1SDavid du Colombier void rclunk(Mfile*);
723e12c5d1SDavid du Colombier void rremove(Mfile*);
733e12c5d1SDavid du Colombier void rstat(Mfile*);
743e12c5d1SDavid du Colombier void rwstat(Mfile*);
759a747e4fSDavid du Colombier void error(char*, ...);
763e12c5d1SDavid du Colombier void warning(char*);
773e12c5d1SDavid du Colombier void mountinit(char*, char*);
783e12c5d1SDavid du Colombier void io(void);
793e12c5d1SDavid du Colombier void sendreply(char*);
803e12c5d1SDavid du Colombier void sendmsg(P9fs*, Fcall*);
813e12c5d1SDavid du Colombier void rcvmsg(P9fs*, Fcall*);
823e12c5d1SDavid du Colombier int delegate(void);
833e12c5d1SDavid du Colombier int askserver(void);
847c70c028SDavid du Colombier void cachesetup(int, char*, char*);
859a747e4fSDavid du Colombier int ctltest(Mfile*);
869a747e4fSDavid du Colombier void genstats(void);
873e12c5d1SDavid du Colombier
883e12c5d1SDavid du Colombier char *mname[]={
899a747e4fSDavid du Colombier [Tversion] "Tversion",
909a747e4fSDavid du Colombier [Tauth] "Tauth",
913e12c5d1SDavid du Colombier [Tflush] "Tflush",
923e12c5d1SDavid du Colombier [Tattach] "Tattach",
933e12c5d1SDavid du Colombier [Twalk] "Twalk",
943e12c5d1SDavid du Colombier [Topen] "Topen",
953e12c5d1SDavid du Colombier [Tcreate] "Tcreate",
963e12c5d1SDavid du Colombier [Tclunk] "Tclunk",
973e12c5d1SDavid du Colombier [Tread] "Tread",
983e12c5d1SDavid du Colombier [Twrite] "Twrite",
993e12c5d1SDavid du Colombier [Tremove] "Tremove",
1003e12c5d1SDavid du Colombier [Tstat] "Tstat",
1013e12c5d1SDavid du Colombier [Twstat] "Twstat",
1029a747e4fSDavid du Colombier [Rversion] "Rversion",
1039a747e4fSDavid du Colombier [Rauth] "Rauth",
1043e12c5d1SDavid du Colombier [Rerror] "Rerror",
1053e12c5d1SDavid du Colombier [Rflush] "Rflush",
1063e12c5d1SDavid du Colombier [Rattach] "Rattach",
1073e12c5d1SDavid du Colombier [Rwalk] "Rwalk",
1083e12c5d1SDavid du Colombier [Ropen] "Ropen",
1093e12c5d1SDavid du Colombier [Rcreate] "Rcreate",
1103e12c5d1SDavid du Colombier [Rclunk] "Rclunk",
1113e12c5d1SDavid du Colombier [Rread] "Rread",
1123e12c5d1SDavid du Colombier [Rwrite] "Rwrite",
1133e12c5d1SDavid du Colombier [Rremove] "Rremove",
1143e12c5d1SDavid du Colombier [Rstat] "Rstat",
1153e12c5d1SDavid du Colombier [Rwstat] "Rwstat",
1163e12c5d1SDavid du Colombier 0,
1173e12c5d1SDavid du Colombier };
1183e12c5d1SDavid du Colombier
1193e12c5d1SDavid du Colombier void
usage(void)1203e12c5d1SDavid du Colombier usage(void)
1213e12c5d1SDavid du Colombier {
122*2bef681aSDavid du Colombier fprint(2, "usage:\tcfs -s [-dknrS] [-f partition]\n");
123*2bef681aSDavid du Colombier fprint(2, "\tcfs [-a netaddr | -F srv] [-dknrS] [-f partition] [mntpt]\n");
1249a747e4fSDavid du Colombier exits("usage");
1253e12c5d1SDavid du Colombier }
1263e12c5d1SDavid du Colombier
1273e12c5d1SDavid du Colombier void
main(int argc,char * argv[])1283e12c5d1SDavid du Colombier main(int argc, char *argv[])
1293e12c5d1SDavid du Colombier {
130*2bef681aSDavid du Colombier int std, format, chkid;
131*2bef681aSDavid du Colombier char *part, *server, *mtpt;
1327c70c028SDavid du Colombier NetConnInfo *snci;
1337c70c028SDavid du Colombier
1343e12c5d1SDavid du Colombier std = 0;
1353e12c5d1SDavid du Colombier format = 0;
1367c70c028SDavid du Colombier chkid = 1;
1377dd7cddfSDavid du Colombier part = "/dev/sdC0/cache";
1387c70c028SDavid du Colombier server = "tcp!fs";
1393e12c5d1SDavid du Colombier mtpt = "/tmp";
1403e12c5d1SDavid du Colombier
1413e12c5d1SDavid du Colombier ARGBEGIN{
1423e12c5d1SDavid du Colombier case 'a':
14307b9f4d0SDavid du Colombier server = EARGF(usage());
1443e12c5d1SDavid du Colombier break;
145*2bef681aSDavid du Colombier case 'd':
146*2bef681aSDavid du Colombier debug = 1;
147*2bef681aSDavid du Colombier break;
148*2bef681aSDavid du Colombier case 'f':
149*2bef681aSDavid du Colombier part = EARGF(usage());
150*2bef681aSDavid du Colombier break;
151*2bef681aSDavid du Colombier case 'F':
152*2bef681aSDavid du Colombier server = EARGF(usage());
153*2bef681aSDavid du Colombier openserver = 1;
154*2bef681aSDavid du Colombier break;
155*2bef681aSDavid du Colombier case 'k':
156*2bef681aSDavid du Colombier chkid = 0;
157*2bef681aSDavid du Colombier break;
158*2bef681aSDavid du Colombier case 'n':
159*2bef681aSDavid du Colombier noauth = 1;
160*2bef681aSDavid du Colombier break;
161*2bef681aSDavid du Colombier case 'r':
162*2bef681aSDavid du Colombier format = 1;
163*2bef681aSDavid du Colombier break;
1649a747e4fSDavid du Colombier case 'S':
1659a747e4fSDavid du Colombier statson = 1;
1669a747e4fSDavid du Colombier break;
1673e12c5d1SDavid du Colombier case 's':
1683e12c5d1SDavid du Colombier std = 1;
1693e12c5d1SDavid du Colombier break;
1703e12c5d1SDavid du Colombier default:
1713e12c5d1SDavid du Colombier usage();
1723e12c5d1SDavid du Colombier }ARGEND
1733e12c5d1SDavid du Colombier if(argc && *argv)
1743e12c5d1SDavid du Colombier mtpt = *argv;
1753e12c5d1SDavid du Colombier
1767dd7cddfSDavid du Colombier if(debug)
1779a747e4fSDavid du Colombier fmtinstall('F', fcallfmt);
1787dd7cddfSDavid du Colombier
1793e12c5d1SDavid du Colombier c.name = "client";
1803e12c5d1SDavid du Colombier s.name = "server";
1813e12c5d1SDavid du Colombier if(std){
1823e12c5d1SDavid du Colombier c.fd[0] = c.fd[1] = 1;
1833e12c5d1SDavid du Colombier s.fd[0] = s.fd[1] = 0;
1843e12c5d1SDavid du Colombier }else
1853e12c5d1SDavid du Colombier mountinit(server, mtpt);
1863e12c5d1SDavid du Colombier
1877c70c028SDavid du Colombier if(chkid){
1887c70c028SDavid du Colombier if((snci = getnetconninfo(nil, s.fd[0])) == nil)
1897c70c028SDavid du Colombier /* Failed to lookup information; format */
1907c70c028SDavid du Colombier cachesetup(1, nil, part);
1917c70c028SDavid du Colombier else
1927c70c028SDavid du Colombier /* Do partition check */
1937c70c028SDavid du Colombier cachesetup(0, snci->raddr, part);
1947c70c028SDavid du Colombier }else
1957c70c028SDavid du Colombier /* Obey -f w/o regard to cache vs. remote server */
1967c70c028SDavid du Colombier cachesetup(format, nil, part);
1977c70c028SDavid du Colombier
1983e12c5d1SDavid du Colombier switch(fork()){
1993e12c5d1SDavid du Colombier case 0:
2003e12c5d1SDavid du Colombier io();
2013e12c5d1SDavid du Colombier exits("");
2023e12c5d1SDavid du Colombier case -1:
2033e12c5d1SDavid du Colombier error("fork");
2043e12c5d1SDavid du Colombier default:
2053e12c5d1SDavid du Colombier exits("");
2063e12c5d1SDavid du Colombier }
2073e12c5d1SDavid du Colombier }
2083e12c5d1SDavid du Colombier
2093e12c5d1SDavid du Colombier void
cachesetup(int format,char * name,char * partition)2107c70c028SDavid du Colombier cachesetup(int format, char *name, char *partition)
2113e12c5d1SDavid du Colombier {
2123e12c5d1SDavid du Colombier int f;
2133e12c5d1SDavid du Colombier int secsize;
2143e12c5d1SDavid du Colombier int inodes;
2153e12c5d1SDavid du Colombier int blocksize;
2163e12c5d1SDavid du Colombier
2173e12c5d1SDavid du Colombier secsize = 512;
2183e12c5d1SDavid du Colombier inodes = 1024;
2193e12c5d1SDavid du Colombier blocksize = 4*1024;
2203e12c5d1SDavid du Colombier
2213e12c5d1SDavid du Colombier f = open(partition, ORDWR);
2223e12c5d1SDavid du Colombier if(f < 0)
2233e12c5d1SDavid du Colombier error("opening partition");
2243e12c5d1SDavid du Colombier
2257c70c028SDavid du Colombier if(format || iinit(&ic, f, secsize, name) < 0){
2267c70c028SDavid du Colombier /*
2277c70c028SDavid du Colombier * If we need to format and don't have a name, fall
2287c70c028SDavid du Colombier * back to our old behavior of using "bootes"
2297c70c028SDavid du Colombier */
2307c70c028SDavid du Colombier name = (name == nil? "bootes": name);
2317c70c028SDavid du Colombier if(iformat(&ic, f, inodes, name, blocksize, secsize) < 0)
2323e12c5d1SDavid du Colombier error("formatting failed");
2333e12c5d1SDavid du Colombier }
2343e12c5d1SDavid du Colombier }
2353e12c5d1SDavid du Colombier
2363e12c5d1SDavid du Colombier void
mountinit(char * server,char * mountpoint)2373e12c5d1SDavid du Colombier mountinit(char *server, char *mountpoint)
2383e12c5d1SDavid du Colombier {
239*2bef681aSDavid du Colombier int err;
2403e12c5d1SDavid du Colombier int p[2];
2413e12c5d1SDavid du Colombier
2423e12c5d1SDavid du Colombier /*
2433e12c5d1SDavid du Colombier * grab a channel and call up the file server
2443e12c5d1SDavid du Colombier */
245*2bef681aSDavid du Colombier if (openserver)
246*2bef681aSDavid du Colombier s.fd[0] = open(server, ORDWR);
247*2bef681aSDavid du Colombier else
248*2bef681aSDavid du Colombier s.fd[0] = dial(netmkaddr(server, 0, "9fs"), 0, 0, 0);
2493e12c5d1SDavid du Colombier if(s.fd[0] < 0)
250*2bef681aSDavid du Colombier error("opening data: %r");
251*2bef681aSDavid du Colombier s.fd[1] = s.fd[0];
2523e12c5d1SDavid du Colombier
2533e12c5d1SDavid du Colombier /*
2543e12c5d1SDavid du Colombier * mount onto name space
2553e12c5d1SDavid du Colombier */
2563e12c5d1SDavid du Colombier if(pipe(p) < 0)
2573e12c5d1SDavid du Colombier error("pipe failed");
2583e12c5d1SDavid du Colombier switch(fork()){
2593e12c5d1SDavid du Colombier case 0:
260219b2ee8SDavid du Colombier break;
261219b2ee8SDavid du Colombier default:
262*2bef681aSDavid du Colombier if (noauth)
263*2bef681aSDavid du Colombier err = mount(p[1], -1, mountpoint, MREPL|MCREATE, "");
264*2bef681aSDavid du Colombier else
265*2bef681aSDavid du Colombier err = amount(p[1], mountpoint, MREPL|MCREATE, "");
266*2bef681aSDavid du Colombier if (err < 0)
267*2bef681aSDavid du Colombier error("mount failed: %r");
2683e12c5d1SDavid du Colombier exits(0);
2693e12c5d1SDavid du Colombier case -1:
2703e12c5d1SDavid du Colombier error("fork failed\n");
2713e12c5d1SDavid du Colombier /*BUG: no wait!*/
2723e12c5d1SDavid du Colombier }
2733e12c5d1SDavid du Colombier c.fd[0] = c.fd[1] = p[0];
2743e12c5d1SDavid du Colombier }
2753e12c5d1SDavid du Colombier
2763e12c5d1SDavid du Colombier void
io(void)2773e12c5d1SDavid du Colombier io(void)
2783e12c5d1SDavid du Colombier {
2799a747e4fSDavid du Colombier int type;
2803e12c5d1SDavid du Colombier Mfile *mf;
2813e12c5d1SDavid du Colombier loop:
2823e12c5d1SDavid du Colombier rcvmsg(&c, &c.thdr);
2839a747e4fSDavid du Colombier
2849a747e4fSDavid du Colombier type = c.thdr.type;
2859a747e4fSDavid du Colombier
2869a747e4fSDavid du Colombier if(statson){
2879a747e4fSDavid du Colombier cfsstat.cm[type].n++;
2889a747e4fSDavid du Colombier cfsstat.cm[type].s = nsec();
2899a747e4fSDavid du Colombier }
2903e12c5d1SDavid du Colombier mf = &mfile[c.thdr.fid];
2919a747e4fSDavid du Colombier switch(type){
2923e12c5d1SDavid du Colombier default:
2933e12c5d1SDavid du Colombier error("type");
2943e12c5d1SDavid du Colombier break;
2959a747e4fSDavid du Colombier case Tversion:
2969a747e4fSDavid du Colombier rversion();
2973e12c5d1SDavid du Colombier break;
2989a747e4fSDavid du Colombier case Tauth:
2999a747e4fSDavid du Colombier mf = &mfile[c.thdr.afid];
3009a747e4fSDavid du Colombier rauth(mf);
3013e12c5d1SDavid du Colombier break;
3023e12c5d1SDavid du Colombier case Tflush:
3033e12c5d1SDavid du Colombier rflush();
3043e12c5d1SDavid du Colombier break;
3053e12c5d1SDavid du Colombier case Tattach:
3063e12c5d1SDavid du Colombier rattach(mf);
3073e12c5d1SDavid du Colombier break;
3083e12c5d1SDavid du Colombier case Twalk:
3093e12c5d1SDavid du Colombier rwalk(mf);
3103e12c5d1SDavid du Colombier break;
3113e12c5d1SDavid du Colombier case Topen:
3123e12c5d1SDavid du Colombier ropen(mf);
3133e12c5d1SDavid du Colombier break;
3143e12c5d1SDavid du Colombier case Tcreate:
3153e12c5d1SDavid du Colombier rcreate(mf);
3163e12c5d1SDavid du Colombier break;
3173e12c5d1SDavid du Colombier case Tread:
3183e12c5d1SDavid du Colombier rread(mf);
3193e12c5d1SDavid du Colombier break;
3203e12c5d1SDavid du Colombier case Twrite:
3213e12c5d1SDavid du Colombier rwrite(mf);
3223e12c5d1SDavid du Colombier break;
3233e12c5d1SDavid du Colombier case Tclunk:
3243e12c5d1SDavid du Colombier rclunk(mf);
3253e12c5d1SDavid du Colombier break;
3263e12c5d1SDavid du Colombier case Tremove:
3273e12c5d1SDavid du Colombier rremove(mf);
3283e12c5d1SDavid du Colombier break;
3293e12c5d1SDavid du Colombier case Tstat:
3303e12c5d1SDavid du Colombier rstat(mf);
3313e12c5d1SDavid du Colombier break;
3323e12c5d1SDavid du Colombier case Twstat:
3333e12c5d1SDavid du Colombier rwstat(mf);
3343e12c5d1SDavid du Colombier break;
3353e12c5d1SDavid du Colombier }
3369a747e4fSDavid du Colombier if(statson){
3379a747e4fSDavid du Colombier cfsstat.cm[type].t += nsec() -cfsstat.cm[type].s;
3389a747e4fSDavid du Colombier }
3393e12c5d1SDavid du Colombier goto loop;
3403e12c5d1SDavid du Colombier }
3413e12c5d1SDavid du Colombier
3423e12c5d1SDavid du Colombier void
rversion(void)3439a747e4fSDavid du Colombier rversion(void)
344219b2ee8SDavid du Colombier {
3459a747e4fSDavid du Colombier if(messagesize > c.thdr.msize)
3469a747e4fSDavid du Colombier messagesize = c.thdr.msize;
3479a747e4fSDavid du Colombier c.thdr.msize = messagesize; /* set downstream size */
348219b2ee8SDavid du Colombier delegate();
349219b2ee8SDavid du Colombier }
350219b2ee8SDavid du Colombier
351219b2ee8SDavid du Colombier void
rauth(Mfile * mf)3529a747e4fSDavid du Colombier rauth(Mfile *mf)
3539a747e4fSDavid du Colombier {
3546b6b9ac8SDavid du Colombier if(mf->busy)
3556b6b9ac8SDavid du Colombier error("auth to used channel");
3569a747e4fSDavid du Colombier
3579a747e4fSDavid du Colombier if(delegate() == 0){
3586b6b9ac8SDavid du Colombier mf->qid = s.rhdr.aqid;
3599a747e4fSDavid du Colombier mf->busy = 1;
3609a747e4fSDavid du Colombier }
3619a747e4fSDavid du Colombier }
3629a747e4fSDavid du Colombier
3639a747e4fSDavid du Colombier void
rflush(void)3643e12c5d1SDavid du Colombier rflush(void) /* synchronous so easy */
3653e12c5d1SDavid du Colombier {
3663e12c5d1SDavid du Colombier sendreply(0);
3673e12c5d1SDavid du Colombier }
3683e12c5d1SDavid du Colombier
3693e12c5d1SDavid du Colombier void
rattach(Mfile * mf)3703e12c5d1SDavid du Colombier rattach(Mfile *mf)
3713e12c5d1SDavid du Colombier {
3723e12c5d1SDavid du Colombier if(delegate() == 0){
3733e12c5d1SDavid du Colombier mf->qid = s.rhdr.qid;
3743e12c5d1SDavid du Colombier mf->busy = 1;
3759a747e4fSDavid du Colombier if (statson == 1){
3769a747e4fSDavid du Colombier statson++;
3779a747e4fSDavid du Colombier rootqid = mf->qid;
3783e12c5d1SDavid du Colombier }
3793e12c5d1SDavid du Colombier }
3803e12c5d1SDavid du Colombier }
3813e12c5d1SDavid du Colombier
3823e12c5d1SDavid du Colombier void
rwalk(Mfile * mf)3833e12c5d1SDavid du Colombier rwalk(Mfile *mf)
3843e12c5d1SDavid du Colombier {
3859a747e4fSDavid du Colombier Mfile *nmf;
3869a747e4fSDavid du Colombier
3879a747e4fSDavid du Colombier nmf = nil;
3889a747e4fSDavid du Colombier if(statson
3899a747e4fSDavid du Colombier && mf->qid.type == rootqid.type && mf->qid.path == rootqid.path
3909a747e4fSDavid du Colombier && c.thdr.nwname == 1 && strcmp(c.thdr.wname[0], "cfsctl") == 0){
3919a747e4fSDavid du Colombier /* This is the ctl file */
3929a747e4fSDavid du Colombier nmf = &mfile[c.thdr.newfid];
3939a747e4fSDavid du Colombier if(c.thdr.newfid != c.thdr.fid && nmf->busy)
3949a747e4fSDavid du Colombier error("clone to used channel");
3959a747e4fSDavid du Colombier nmf = &mfile[c.thdr.newfid];
3969a747e4fSDavid du Colombier nmf->qid = ctlqid;
3979a747e4fSDavid du Colombier nmf->busy = 1;
3989a747e4fSDavid du Colombier c.rhdr.nwqid = 1;
3999a747e4fSDavid du Colombier c.rhdr.wqid[0] = ctlqid;
4009a747e4fSDavid du Colombier sendreply(0);
4013e12c5d1SDavid du Colombier return;
4023e12c5d1SDavid du Colombier }
4039a747e4fSDavid du Colombier if(c.thdr.newfid != c.thdr.fid){
40422a127bbSDavid du Colombier if(c.thdr.newfid >= Nfid)
4059a747e4fSDavid du Colombier error("clone nfid out of range");
4069a747e4fSDavid du Colombier nmf = &mfile[c.thdr.newfid];
4079a747e4fSDavid du Colombier if(nmf->busy)
4089a747e4fSDavid du Colombier error("clone to used channel");
4099a747e4fSDavid du Colombier nmf = &mfile[c.thdr.newfid];
4109a747e4fSDavid du Colombier nmf->qid = mf->qid;
4119a747e4fSDavid du Colombier nmf->busy = 1;
4129a747e4fSDavid du Colombier mf = nmf; /* Walk mf */
4133e12c5d1SDavid du Colombier }
4143e12c5d1SDavid du Colombier
4159a747e4fSDavid du Colombier if(delegate() < 0){ /* complete failure */
4169a747e4fSDavid du Colombier if(nmf)
4179a747e4fSDavid du Colombier nmf->busy = 0;
4189a747e4fSDavid du Colombier return;
4199a747e4fSDavid du Colombier }
4209a747e4fSDavid du Colombier
4219a747e4fSDavid du Colombier if(s.rhdr.nwqid == c.thdr.nwname){ /* complete success */
4229a747e4fSDavid du Colombier if(s.rhdr.nwqid > 0)
4239a747e4fSDavid du Colombier mf->qid = s.rhdr.wqid[s.rhdr.nwqid-1];
4249a747e4fSDavid du Colombier return;
4259a747e4fSDavid du Colombier }
4269a747e4fSDavid du Colombier
4279a747e4fSDavid du Colombier /* partial success; release fid */
4289a747e4fSDavid du Colombier if(nmf)
4299a747e4fSDavid du Colombier nmf->busy = 0;
4303e12c5d1SDavid du Colombier }
4313e12c5d1SDavid du Colombier
4323e12c5d1SDavid du Colombier void
ropen(Mfile * mf)4333e12c5d1SDavid du Colombier ropen(Mfile *mf)
4343e12c5d1SDavid du Colombier {
4359a747e4fSDavid du Colombier if(statson && ctltest(mf)){
4369a747e4fSDavid du Colombier /* Opening ctl file */
4379a747e4fSDavid du Colombier if(c.thdr.mode != OREAD){
4389a747e4fSDavid du Colombier sendreply("does not exist");
4399a747e4fSDavid du Colombier return;
4409a747e4fSDavid du Colombier }
4419a747e4fSDavid du Colombier c.rhdr.qid = ctlqid;
4429a747e4fSDavid du Colombier c.rhdr.iounit = 0;
4439a747e4fSDavid du Colombier sendreply(0);
4449a747e4fSDavid du Colombier genstats();
4459a747e4fSDavid du Colombier return;
4469a747e4fSDavid du Colombier }
4473e12c5d1SDavid du Colombier if(delegate() == 0){
4483e12c5d1SDavid du Colombier mf->qid = s.rhdr.qid;
4497dd7cddfSDavid du Colombier if(c.thdr.mode & OTRUNC)
4503e12c5d1SDavid du Colombier iget(&ic, mf->qid);
4513e12c5d1SDavid du Colombier }
4523e12c5d1SDavid du Colombier }
4533e12c5d1SDavid du Colombier
4543e12c5d1SDavid du Colombier void
rcreate(Mfile * mf)4553e12c5d1SDavid du Colombier rcreate(Mfile *mf)
4563e12c5d1SDavid du Colombier {
4579a747e4fSDavid du Colombier if(statson && ctltest(mf)){
4589a747e4fSDavid du Colombier sendreply("exists");
4599a747e4fSDavid du Colombier return;
4609a747e4fSDavid du Colombier }
4613e12c5d1SDavid du Colombier if(delegate() == 0){
4623e12c5d1SDavid du Colombier mf->qid = s.rhdr.qid;
4633e12c5d1SDavid du Colombier mf->qid.vers++;
4643e12c5d1SDavid du Colombier }
4653e12c5d1SDavid du Colombier }
4663e12c5d1SDavid du Colombier
4673e12c5d1SDavid du Colombier void
rclunk(Mfile * mf)4683e12c5d1SDavid du Colombier rclunk(Mfile *mf)
4693e12c5d1SDavid du Colombier {
4703e12c5d1SDavid du Colombier if(!mf->busy){
4713e12c5d1SDavid du Colombier sendreply(0);
4723e12c5d1SDavid du Colombier return;
4733e12c5d1SDavid du Colombier }
4743e12c5d1SDavid du Colombier mf->busy = 0;
4753ff48bf5SDavid du Colombier delegate();
4763e12c5d1SDavid du Colombier }
4773e12c5d1SDavid du Colombier
4783e12c5d1SDavid du Colombier void
rremove(Mfile * mf)4793e12c5d1SDavid du Colombier rremove(Mfile *mf)
4803e12c5d1SDavid du Colombier {
4819a747e4fSDavid du Colombier if(statson && ctltest(mf)){
4829a747e4fSDavid du Colombier sendreply("not removed");
4839a747e4fSDavid du Colombier return;
4849a747e4fSDavid du Colombier }
4853e12c5d1SDavid du Colombier mf->busy = 0;
4863e12c5d1SDavid du Colombier delegate();
4873e12c5d1SDavid du Colombier }
4883e12c5d1SDavid du Colombier
4893e12c5d1SDavid du Colombier void
rread(Mfile * mf)4903e12c5d1SDavid du Colombier rread(Mfile *mf)
4913e12c5d1SDavid du Colombier {
49241fb754aSDavid du Colombier int cnt, done;
4933e12c5d1SDavid du Colombier long n;
49441fb754aSDavid du Colombier vlong off, first;
49541fb754aSDavid du Colombier char *cp;
4963e12c5d1SDavid du Colombier char data[MAXFDATA];
49741fb754aSDavid du Colombier Ibuf *b;
4983e12c5d1SDavid du Colombier
49941fb754aSDavid du Colombier off = c.thdr.offset;
50041fb754aSDavid du Colombier first = off;
5013e12c5d1SDavid du Colombier cnt = c.thdr.count;
5023e12c5d1SDavid du Colombier
5039a747e4fSDavid du Colombier if(statson && ctltest(mf)){
5049a747e4fSDavid du Colombier if(cnt > statlen-off)
5059a747e4fSDavid du Colombier c.rhdr.count = statlen-off;
5069a747e4fSDavid du Colombier else
5079a747e4fSDavid du Colombier c.rhdr.count = cnt;
50822a127bbSDavid du Colombier if((int)c.rhdr.count < 0){
5099a747e4fSDavid du Colombier sendreply("eof");
5109a747e4fSDavid du Colombier return;
5119a747e4fSDavid du Colombier }
5129a747e4fSDavid du Colombier c.rhdr.data = statbuf + off;
5139a747e4fSDavid du Colombier sendreply(0);
5149a747e4fSDavid du Colombier return;
5159a747e4fSDavid du Colombier }
5169a747e4fSDavid du Colombier if(mf->qid.type & (QTDIR|QTAUTH)){
5173e12c5d1SDavid du Colombier delegate();
5189a747e4fSDavid du Colombier if (statson) {
5199a747e4fSDavid du Colombier cfsstat.ndirread++;
5209a747e4fSDavid du Colombier if(c.rhdr.count > 0){
5219a747e4fSDavid du Colombier cfsstat.bytesread += c.rhdr.count;
5229a747e4fSDavid du Colombier cfsstat.bytesfromdirs += c.rhdr.count;
5239a747e4fSDavid du Colombier }
5249a747e4fSDavid du Colombier }
5253e12c5d1SDavid du Colombier return;
5263e12c5d1SDavid du Colombier }
5273e12c5d1SDavid du Colombier
5283e12c5d1SDavid du Colombier b = iget(&ic, mf->qid);
5293e12c5d1SDavid du Colombier if(b == 0){
5309a747e4fSDavid du Colombier DPRINT(2, "delegating read\n");
5313e12c5d1SDavid du Colombier delegate();
5329a747e4fSDavid du Colombier if (statson){
5339a747e4fSDavid du Colombier cfsstat.ndelegateread++;
5349a747e4fSDavid du Colombier if(c.rhdr.count > 0){
5359a747e4fSDavid du Colombier cfsstat.bytesread += c.rhdr.count;
5369a747e4fSDavid du Colombier cfsstat.bytesfromserver += c.rhdr.count;
5379a747e4fSDavid du Colombier }
5389a747e4fSDavid du Colombier }
5393e12c5d1SDavid du Colombier return;
5403e12c5d1SDavid du Colombier }
5413e12c5d1SDavid du Colombier
5423e12c5d1SDavid du Colombier cp = data;
5433e12c5d1SDavid du Colombier done = 0;
5443e12c5d1SDavid du Colombier while(cnt>0 && !done){
5459a747e4fSDavid du Colombier if(off >= b->inode.length){
54641fb754aSDavid du Colombier DPRINT(2, "offset %lld greater than length %lld\n",
54741fb754aSDavid du Colombier off, b->inode.length);
5489a747e4fSDavid du Colombier break;
5499a747e4fSDavid du Colombier }
5503e12c5d1SDavid du Colombier n = fread(&ic, b, cp, off, cnt);
5513e12c5d1SDavid du Colombier if(n <= 0){
5523e12c5d1SDavid du Colombier n = -n;
5533e12c5d1SDavid du Colombier if(n==0 || n>cnt)
5543e12c5d1SDavid du Colombier n = cnt;
55541fb754aSDavid du Colombier DPRINT(2,
55641fb754aSDavid du Colombier "fetch %ld bytes of data from server at offset %lld\n",
55741fb754aSDavid du Colombier n, off);
5583e12c5d1SDavid du Colombier s.thdr.type = c.thdr.type;
5593e12c5d1SDavid du Colombier s.thdr.fid = c.thdr.fid;
5603e12c5d1SDavid du Colombier s.thdr.tag = c.thdr.tag;
5613e12c5d1SDavid du Colombier s.thdr.offset = off;
5623e12c5d1SDavid du Colombier s.thdr.count = n;
56341fb754aSDavid du Colombier if(statson)
5649a747e4fSDavid du Colombier cfsstat.ndelegateread++;
56580ee5cbfSDavid du Colombier if(askserver() < 0){
5663e12c5d1SDavid du Colombier sendreply(s.rhdr.ename);
56780ee5cbfSDavid du Colombier return;
56880ee5cbfSDavid du Colombier }
5693e12c5d1SDavid du Colombier if(s.rhdr.count != n)
5703e12c5d1SDavid du Colombier done = 1;
5713e12c5d1SDavid du Colombier n = s.rhdr.count;
5729a747e4fSDavid du Colombier if(n == 0){
5739a747e4fSDavid du Colombier /* end of file */
5749a747e4fSDavid du Colombier if(b->inode.length > off){
57541fb754aSDavid du Colombier DPRINT(2, "file %llud.%ld, length %lld\n",
57641fb754aSDavid du Colombier b->inode.qid.path,
57741fb754aSDavid du Colombier b->inode.qid.vers, off);
5789a747e4fSDavid du Colombier b->inode.length = off;
5799a747e4fSDavid du Colombier }
5809a747e4fSDavid du Colombier break;
5819a747e4fSDavid du Colombier }
5823e12c5d1SDavid du Colombier memmove(cp, s.rhdr.data, n);
5833e12c5d1SDavid du Colombier fwrite(&ic, b, cp, off, n);
5849a747e4fSDavid du Colombier if (statson){
5859a747e4fSDavid du Colombier cfsstat.bytestocache += n;
5869a747e4fSDavid du Colombier cfsstat.bytesfromserver += n;
5879a747e4fSDavid du Colombier }
5889a747e4fSDavid du Colombier }else{
5899a747e4fSDavid du Colombier DPRINT(2, "fetched %ld bytes from cache\n", n);
59041fb754aSDavid du Colombier if(statson)
5919a747e4fSDavid du Colombier cfsstat.bytesfromcache += n;
5929a747e4fSDavid du Colombier }
5933e12c5d1SDavid du Colombier cnt -= n;
5943e12c5d1SDavid du Colombier off += n;
5953e12c5d1SDavid du Colombier cp += n;
5963e12c5d1SDavid du Colombier }
5973e12c5d1SDavid du Colombier c.rhdr.data = data;
5983e12c5d1SDavid du Colombier c.rhdr.count = off - first;
59941fb754aSDavid du Colombier if(statson)
6009a747e4fSDavid du Colombier cfsstat.bytesread += c.rhdr.count;
6013e12c5d1SDavid du Colombier sendreply(0);
6023e12c5d1SDavid du Colombier }
6033e12c5d1SDavid du Colombier
6043e12c5d1SDavid du Colombier void
rwrite(Mfile * mf)6053e12c5d1SDavid du Colombier rwrite(Mfile *mf)
6063e12c5d1SDavid du Colombier {
6073e12c5d1SDavid du Colombier Ibuf *b;
6083e12c5d1SDavid du Colombier char buf[MAXFDATA];
6093e12c5d1SDavid du Colombier
6109a747e4fSDavid du Colombier if(statson && ctltest(mf)){
6119a747e4fSDavid du Colombier sendreply("read only");
6129a747e4fSDavid du Colombier return;
6139a747e4fSDavid du Colombier }
6149a747e4fSDavid du Colombier if(mf->qid.type & (QTDIR|QTAUTH)){
6153e12c5d1SDavid du Colombier delegate();
6169a747e4fSDavid du Colombier if(statson && c.rhdr.count > 0)
6179a747e4fSDavid du Colombier cfsstat.byteswritten += c.rhdr.count;
6183e12c5d1SDavid du Colombier return;
6193e12c5d1SDavid du Colombier }
6203e12c5d1SDavid du Colombier
6213e12c5d1SDavid du Colombier memmove(buf, c.thdr.data, c.thdr.count);
6223e12c5d1SDavid du Colombier if(delegate() < 0)
6233e12c5d1SDavid du Colombier return;
6243e12c5d1SDavid du Colombier
6259a747e4fSDavid du Colombier if(s.rhdr.count > 0)
6269a747e4fSDavid du Colombier cfsstat.byteswritten += s.rhdr.count;
62741fb754aSDavid du Colombier /* don't modify our cache for append-only data; always read from server*/
62841fb754aSDavid du Colombier if(mf->qid.type & QTAPPEND)
6299a747e4fSDavid du Colombier return;
6303e12c5d1SDavid du Colombier b = iget(&ic, mf->qid);
6313e12c5d1SDavid du Colombier if(b == 0)
6323e12c5d1SDavid du Colombier return;
6339a747e4fSDavid du Colombier if (b->inode.length < c.thdr.offset + s.rhdr.count)
6349a747e4fSDavid du Colombier b->inode.length = c.thdr.offset + s.rhdr.count;
6353e12c5d1SDavid du Colombier mf->qid.vers++;
6369a747e4fSDavid du Colombier if (s.rhdr.count != c.thdr.count)
6379a747e4fSDavid du Colombier syslog(0, "cfslog", "rhdr.count %ud, thdr.count %ud\n",
6389a747e4fSDavid du Colombier s.rhdr.count, c.thdr.count);
6399a747e4fSDavid du Colombier if(fwrite(&ic, b, buf, c.thdr.offset, s.rhdr.count) == s.rhdr.count){
6403e12c5d1SDavid du Colombier iinc(&ic, b);
6419a747e4fSDavid du Colombier if(statson)
6429a747e4fSDavid du Colombier cfsstat.bytestocache += s.rhdr.count;
6439a747e4fSDavid du Colombier }
6443e12c5d1SDavid du Colombier }
6453e12c5d1SDavid du Colombier
6463e12c5d1SDavid du Colombier void
rstat(Mfile * mf)6473e12c5d1SDavid du Colombier rstat(Mfile *mf)
6483e12c5d1SDavid du Colombier {
6499a747e4fSDavid du Colombier Dir d;
6509a747e4fSDavid du Colombier
6519a747e4fSDavid du Colombier if(statson && ctltest(mf)){
6529a747e4fSDavid du Colombier genstats();
6539a747e4fSDavid du Colombier d.qid = ctlqid;
6549a747e4fSDavid du Colombier d.mode = 0444;
6559a747e4fSDavid du Colombier d.length = statlen; /* would be nice to do better */
6569a747e4fSDavid du Colombier d.name = "cfsctl";
6579a747e4fSDavid du Colombier d.uid = "none";
6589a747e4fSDavid du Colombier d.gid = "none";
6599a747e4fSDavid du Colombier d.muid = "none";
6609a747e4fSDavid du Colombier d.atime = time(nil);
6619a747e4fSDavid du Colombier d.mtime = d.atime;
66241fb754aSDavid du Colombier c.rhdr.nstat = convD2M(&d, c.rhdr.stat,
66341fb754aSDavid du Colombier sizeof c.rhdr - (c.rhdr.stat - (uchar*)&c.rhdr));
6649a747e4fSDavid du Colombier sendreply(0);
6659a747e4fSDavid du Colombier return;
6669a747e4fSDavid du Colombier }
6679a747e4fSDavid du Colombier if(delegate() == 0){
6689a747e4fSDavid du Colombier Ibuf *b;
6699a747e4fSDavid du Colombier
6709a747e4fSDavid du Colombier convM2D(s.rhdr.stat, s.rhdr.nstat , &d, nil);
6719a747e4fSDavid du Colombier mf->qid = d.qid;
6729a747e4fSDavid du Colombier b = iget(&ic, mf->qid);
6739a747e4fSDavid du Colombier if(b)
6749a747e4fSDavid du Colombier b->inode.length = d.length;
6759a747e4fSDavid du Colombier }
6763e12c5d1SDavid du Colombier }
6773e12c5d1SDavid du Colombier
6783e12c5d1SDavid du Colombier void
rwstat(Mfile * mf)6793e12c5d1SDavid du Colombier rwstat(Mfile *mf)
6803e12c5d1SDavid du Colombier {
6819a747e4fSDavid du Colombier Ibuf *b;
6829a747e4fSDavid du Colombier
6839a747e4fSDavid du Colombier if(statson && ctltest(mf)){
6849a747e4fSDavid du Colombier sendreply("read only");
6859a747e4fSDavid du Colombier return;
6869a747e4fSDavid du Colombier }
6873e12c5d1SDavid du Colombier delegate();
6889a747e4fSDavid du Colombier if(b = iget(&ic, mf->qid))
6899a747e4fSDavid du Colombier b->inode.length = MAXLEN;
6903e12c5d1SDavid du Colombier }
6913e12c5d1SDavid du Colombier
6923e12c5d1SDavid du Colombier void
error(char * fmt,...)69341fb754aSDavid du Colombier error(char *fmt, ...)
69441fb754aSDavid du Colombier {
6959a747e4fSDavid du Colombier va_list arg;
6969a747e4fSDavid du Colombier static char buf[2048];
6979a747e4fSDavid du Colombier
6989a747e4fSDavid du Colombier va_start(arg, fmt);
6999a747e4fSDavid du Colombier vseprint(buf, buf+sizeof(buf), fmt, arg);
7009a747e4fSDavid du Colombier va_end(arg);
7019a747e4fSDavid du Colombier fprint(2, "%s: %s\n", argv0, buf);
7029a747e4fSDavid du Colombier exits("error");
7033e12c5d1SDavid du Colombier }
7043e12c5d1SDavid du Colombier
7053e12c5d1SDavid du Colombier void
warning(char * s)7063e12c5d1SDavid du Colombier warning(char *s)
7073e12c5d1SDavid du Colombier {
7087dd7cddfSDavid du Colombier fprint(2, "cfs: %s: %r\n", s);
7093e12c5d1SDavid du Colombier }
7103e12c5d1SDavid du Colombier
7113e12c5d1SDavid du Colombier /*
7123e12c5d1SDavid du Colombier * send a reply to the client
7133e12c5d1SDavid du Colombier */
7143e12c5d1SDavid du Colombier void
sendreply(char * err)7153e12c5d1SDavid du Colombier sendreply(char *err)
7163e12c5d1SDavid du Colombier {
7173e12c5d1SDavid du Colombier
7183e12c5d1SDavid du Colombier if(err){
7193e12c5d1SDavid du Colombier c.rhdr.type = Rerror;
7209a747e4fSDavid du Colombier c.rhdr.ename = err;
7213e12c5d1SDavid du Colombier }else{
7223e12c5d1SDavid du Colombier c.rhdr.type = c.thdr.type+1;
7233e12c5d1SDavid du Colombier c.rhdr.fid = c.thdr.fid;
7243e12c5d1SDavid du Colombier }
7253e12c5d1SDavid du Colombier c.rhdr.tag = c.thdr.tag;
7263e12c5d1SDavid du Colombier sendmsg(&c, &c.rhdr);
7273e12c5d1SDavid du Colombier }
7283e12c5d1SDavid du Colombier
7293e12c5d1SDavid du Colombier /*
7303e12c5d1SDavid du Colombier * send a request to the server, get the reply, and send that to
7313e12c5d1SDavid du Colombier * the client
7323e12c5d1SDavid du Colombier */
7333e12c5d1SDavid du Colombier int
delegate(void)7343e12c5d1SDavid du Colombier delegate(void)
7353e12c5d1SDavid du Colombier {
7369a747e4fSDavid du Colombier int type;
7379a747e4fSDavid du Colombier
7389a747e4fSDavid du Colombier type = c.thdr.type;
7399a747e4fSDavid du Colombier if(statson){
7409a747e4fSDavid du Colombier cfsstat.sm[type].n++;
7419a747e4fSDavid du Colombier cfsstat.sm[type].s = nsec();
7429a747e4fSDavid du Colombier }
7439a747e4fSDavid du Colombier
7443e12c5d1SDavid du Colombier sendmsg(&s, &c.thdr);
7453e12c5d1SDavid du Colombier rcvmsg(&s, &s.rhdr);
7469a747e4fSDavid du Colombier
74741fb754aSDavid du Colombier if(statson)
7489a747e4fSDavid du Colombier cfsstat.sm[type].t += nsec() - cfsstat.sm[type].s;
7499a747e4fSDavid du Colombier
7503e12c5d1SDavid du Colombier sendmsg(&c, &s.rhdr);
7513e12c5d1SDavid du Colombier return c.thdr.type+1 == s.rhdr.type ? 0 : -1;
7523e12c5d1SDavid du Colombier }
7533e12c5d1SDavid du Colombier
7543e12c5d1SDavid du Colombier /*
7553e12c5d1SDavid du Colombier * send a request to the server and get a reply
7563e12c5d1SDavid du Colombier */
7573e12c5d1SDavid du Colombier int
askserver(void)7583e12c5d1SDavid du Colombier askserver(void)
7593e12c5d1SDavid du Colombier {
7609a747e4fSDavid du Colombier int type;
7619a747e4fSDavid du Colombier
7623e12c5d1SDavid du Colombier s.thdr.tag = c.thdr.tag;
7639a747e4fSDavid du Colombier
7649a747e4fSDavid du Colombier type = s.thdr.type;
7659a747e4fSDavid du Colombier if(statson){
7669a747e4fSDavid du Colombier cfsstat.sm[type].n++;
7679a747e4fSDavid du Colombier cfsstat.sm[type].s = nsec();
7689a747e4fSDavid du Colombier }
7699a747e4fSDavid du Colombier
7703e12c5d1SDavid du Colombier sendmsg(&s, &s.thdr);
7713e12c5d1SDavid du Colombier rcvmsg(&s, &s.rhdr);
7729a747e4fSDavid du Colombier
77341fb754aSDavid du Colombier if(statson)
7749a747e4fSDavid du Colombier cfsstat.sm[type].t += nsec() - cfsstat.sm[type].s;
7759a747e4fSDavid du Colombier
7763e12c5d1SDavid du Colombier return s.thdr.type+1 == s.rhdr.type ? 0 : -1;
7773e12c5d1SDavid du Colombier }
7783e12c5d1SDavid du Colombier
7793e12c5d1SDavid du Colombier /*
7803e12c5d1SDavid du Colombier * send/receive messages with logging
7813e12c5d1SDavid du Colombier */
7823e12c5d1SDavid du Colombier void
sendmsg(P9fs * p,Fcall * f)7833e12c5d1SDavid du Colombier sendmsg(P9fs *p, Fcall *f)
7843e12c5d1SDavid du Colombier {
7857dd7cddfSDavid du Colombier DPRINT(2, "->%s: %F\n", p->name, f);
7863e12c5d1SDavid du Colombier
7879a747e4fSDavid du Colombier p->len = convS2M(f, datasnd, messagesize);
7889a747e4fSDavid du Colombier if(p->len <= 0)
7899a747e4fSDavid du Colombier error("convS2M");
7909a747e4fSDavid du Colombier if(write(p->fd[1], datasnd, p->len)!=p->len)
7919a747e4fSDavid du Colombier error("sendmsg");
7923e12c5d1SDavid du Colombier }
7933e12c5d1SDavid du Colombier
7943e12c5d1SDavid du Colombier void
dump(uchar * p,int len)7953e12c5d1SDavid du Colombier dump(uchar *p, int len)
7963e12c5d1SDavid du Colombier {
7973e12c5d1SDavid du Colombier fprint(2, "%d bytes", len);
79841fb754aSDavid du Colombier while(len-- > 0)
7993e12c5d1SDavid du Colombier fprint(2, " %.2ux", *p++);
8003e12c5d1SDavid du Colombier fprint(2, "\n");
8013e12c5d1SDavid du Colombier }
8023e12c5d1SDavid du Colombier
8033e12c5d1SDavid du Colombier void
rcvmsg(P9fs * p,Fcall * f)8043e12c5d1SDavid du Colombier rcvmsg(P9fs *p, Fcall *f)
8053e12c5d1SDavid du Colombier {
8069a747e4fSDavid du Colombier int olen, rlen;
8077dd7cddfSDavid du Colombier char buf[128];
8083e12c5d1SDavid du Colombier
8093e12c5d1SDavid du Colombier olen = p->len;
8109a747e4fSDavid du Colombier p->len = read9pmsg(p->fd[0], datarcv, sizeof(datarcv));
8117dd7cddfSDavid du Colombier if(p->len <= 0){
81241fb754aSDavid du Colombier snprint(buf, sizeof buf, "read9pmsg(%d)->%ld: %r",
81341fb754aSDavid du Colombier p->fd[0], p->len);
8147dd7cddfSDavid du Colombier error(buf);
8157dd7cddfSDavid du Colombier }
8169a747e4fSDavid du Colombier
8179a747e4fSDavid du Colombier if((rlen = convM2S(datarcv, p->len, f)) != p->len)
81841fb754aSDavid du Colombier error("rcvmsg format error, expected length %d, got %d",
81941fb754aSDavid du Colombier rlen, p->len);
82022a127bbSDavid du Colombier if(f->fid >= Nfid){
8213e12c5d1SDavid du Colombier fprint(2, "<-%s: %d %s on %d\n", p->name, f->type,
82241fb754aSDavid du Colombier mname[f->type]? mname[f->type]: "mystery", f->fid);
8233e12c5d1SDavid du Colombier dump((uchar*)datasnd, olen);
8243e12c5d1SDavid du Colombier dump((uchar*)datarcv, p->len);
8253e12c5d1SDavid du Colombier error("rcvmsg fid out of range");
8263e12c5d1SDavid du Colombier }
8277dd7cddfSDavid du Colombier DPRINT(2, "<-%s: %F\n", p->name, f);
8283e12c5d1SDavid du Colombier }
8299a747e4fSDavid du Colombier
8309a747e4fSDavid du Colombier int
ctltest(Mfile * mf)8319a747e4fSDavid du Colombier ctltest(Mfile *mf)
8329a747e4fSDavid du Colombier {
83341fb754aSDavid du Colombier return mf->busy && mf->qid.type == ctlqid.type &&
83441fb754aSDavid du Colombier mf->qid.path == ctlqid.path;
8359a747e4fSDavid du Colombier }
8369a747e4fSDavid du Colombier
8379a747e4fSDavid du Colombier void
genstats(void)8389a747e4fSDavid du Colombier genstats(void)
8399a747e4fSDavid du Colombier {
8409a747e4fSDavid du Colombier int i;
8419a747e4fSDavid du Colombier char *p;
8429a747e4fSDavid du Colombier
8439a747e4fSDavid du Colombier p = statbuf;
8449a747e4fSDavid du Colombier
84541fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p,
84641fb754aSDavid du Colombier " Client Server\n");
84741fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p,
84841fb754aSDavid du Colombier " #calls Δ ms/call Δ #calls Δ ms/call Δ\n");
8499a747e4fSDavid du Colombier for (i = 0; i < nelem(cfsstat.cm); i++)
8509a747e4fSDavid du Colombier if(cfsstat.cm[i].n || cfsstat.sm[i].n) {
85141fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p,
85241fb754aSDavid du Colombier "%7lud %7lud ", cfsstat.cm[i].n,
85341fb754aSDavid du Colombier cfsstat.cm[i].n - cfsprev.cm[i].n);
8549a747e4fSDavid du Colombier if (cfsstat.cm[i].n)
85541fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p,
85641fb754aSDavid du Colombier "%7.3f ", 0.000001*cfsstat.cm[i].t/
85741fb754aSDavid du Colombier cfsstat.cm[i].n);
8589a747e4fSDavid du Colombier else
85941fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p,
86041fb754aSDavid du Colombier " ");
8619a747e4fSDavid du Colombier if(cfsstat.cm[i].n - cfsprev.cm[i].n)
86241fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p,
86341fb754aSDavid du Colombier "%7.3f ", 0.000001*
86441fb754aSDavid du Colombier (cfsstat.cm[i].t - cfsprev.cm[i].t)/
86541fb754aSDavid du Colombier (cfsstat.cm[i].n - cfsprev.cm[i].n));
8669a747e4fSDavid du Colombier else
86741fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p,
86841fb754aSDavid du Colombier " ");
86941fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p,
87041fb754aSDavid du Colombier "%7lud %7lud ", cfsstat.sm[i].n,
87141fb754aSDavid du Colombier cfsstat.sm[i].n - cfsprev.sm[i].n);
8729a747e4fSDavid du Colombier if (cfsstat.sm[i].n)
87341fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p,
87441fb754aSDavid du Colombier "%7.3f ", 0.000001*cfsstat.sm[i].t/
87541fb754aSDavid du Colombier cfsstat.sm[i].n);
8769a747e4fSDavid du Colombier else
87741fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p,
87841fb754aSDavid du Colombier " ");
8799a747e4fSDavid du Colombier if(cfsstat.sm[i].n - cfsprev.sm[i].n)
88041fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p,
88141fb754aSDavid du Colombier "%7.3f ", 0.000001*
88241fb754aSDavid du Colombier (cfsstat.sm[i].t - cfsprev.sm[i].t)/
88341fb754aSDavid du Colombier (cfsstat.sm[i].n - cfsprev.sm[i].n));
8849a747e4fSDavid du Colombier else
88541fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p,
88641fb754aSDavid du Colombier " ");
88741fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%s\n",
88841fb754aSDavid du Colombier mname[i]);
8899a747e4fSDavid du Colombier }
89041fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7lud %7lud ndirread\n",
8919a747e4fSDavid du Colombier cfsstat.ndirread, cfsstat.ndirread - cfsprev.ndirread);
89241fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7lud %7lud ndelegateread\n",
89341fb754aSDavid du Colombier cfsstat.ndelegateread, cfsstat.ndelegateread -
89441fb754aSDavid du Colombier cfsprev.ndelegateread);
89541fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7lud %7lud ninsert\n",
8969a747e4fSDavid du Colombier cfsstat.ninsert, cfsstat.ninsert - cfsprev.ninsert);
89741fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7lud %7lud ndelete\n",
8989a747e4fSDavid du Colombier cfsstat.ndelete, cfsstat.ndelete - cfsprev.ndelete);
89941fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7lud %7lud nupdate\n",
9009a747e4fSDavid du Colombier cfsstat.nupdate, cfsstat.nupdate - cfsprev.nupdate);
9019a747e4fSDavid du Colombier
90241fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud bytesread\n",
9039a747e4fSDavid du Colombier cfsstat.bytesread, cfsstat.bytesread - cfsprev.bytesread);
90441fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud byteswritten\n",
90541fb754aSDavid du Colombier cfsstat.byteswritten, cfsstat.byteswritten -
90641fb754aSDavid du Colombier cfsprev.byteswritten);
90741fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud bytesfromserver\n",
90841fb754aSDavid du Colombier cfsstat.bytesfromserver, cfsstat.bytesfromserver -
90941fb754aSDavid du Colombier cfsprev.bytesfromserver);
91041fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud bytesfromdirs\n",
91141fb754aSDavid du Colombier cfsstat.bytesfromdirs, cfsstat.bytesfromdirs -
91241fb754aSDavid du Colombier cfsprev.bytesfromdirs);
91341fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud bytesfromcache\n",
91441fb754aSDavid du Colombier cfsstat.bytesfromcache, cfsstat.bytesfromcache -
91541fb754aSDavid du Colombier cfsprev.bytesfromcache);
91641fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud bytestocache\n",
91741fb754aSDavid du Colombier cfsstat.bytestocache, cfsstat.bytestocache -
91841fb754aSDavid du Colombier cfsprev.bytestocache);
9199a747e4fSDavid du Colombier statlen = p - statbuf;
9209a747e4fSDavid du Colombier cfsprev = cfsstat;
9219a747e4fSDavid du Colombier }
922