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 */ 209a747e4fSDavid du Colombier #define MAXLEN 0x7fffffffffffffffLL 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; 349a747e4fSDavid du Colombier int debug, statson; 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); 843e12c5d1SDavid du Colombier void cachesetup(int, 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 1203e12c5d1SDavid du Colombier usage(void) 1213e12c5d1SDavid du Colombier { 1223e12c5d1SDavid du Colombier fprint(2, "usage:\tcfs -s [-rd] [-f partition]"); 1233e12c5d1SDavid du Colombier fprint(2, "\tcfs [-rd] [-f partition] [-a netaddr] [mt-pt]\n"); 1249a747e4fSDavid du Colombier exits("usage"); 1253e12c5d1SDavid du Colombier } 1263e12c5d1SDavid du Colombier 1273e12c5d1SDavid du Colombier void 1283e12c5d1SDavid du Colombier main(int argc, char *argv[]) 1293e12c5d1SDavid du Colombier { 1303e12c5d1SDavid du Colombier int std; 1313e12c5d1SDavid du Colombier int format; 1323e12c5d1SDavid du Colombier char *part; 1333e12c5d1SDavid du Colombier char *server; 1343e12c5d1SDavid du Colombier char *mtpt; 1353e12c5d1SDavid du Colombier 1363e12c5d1SDavid du Colombier std = 0; 1373e12c5d1SDavid du Colombier format = 0; 1387dd7cddfSDavid du Colombier part = "/dev/sdC0/cache"; 13907b9f4d0SDavid du Colombier server = "tcp!edith"; 1403e12c5d1SDavid du Colombier mtpt = "/tmp"; 1413e12c5d1SDavid du Colombier 1423e12c5d1SDavid du Colombier ARGBEGIN{ 1433e12c5d1SDavid du Colombier case 'a': 14407b9f4d0SDavid du Colombier server = EARGF(usage()); 1453e12c5d1SDavid du Colombier break; 1469a747e4fSDavid du Colombier case 'S': 1479a747e4fSDavid du Colombier statson = 1; 1489a747e4fSDavid du Colombier break; 1493e12c5d1SDavid du Colombier case 's': 1503e12c5d1SDavid du Colombier std = 1; 1513e12c5d1SDavid du Colombier break; 1523e12c5d1SDavid du Colombier case 'r': 1533e12c5d1SDavid du Colombier format = 1; 1543e12c5d1SDavid du Colombier break; 1553e12c5d1SDavid du Colombier case 'f': 15607b9f4d0SDavid du Colombier part = EARGF(usage()); 1573e12c5d1SDavid du Colombier break; 1583e12c5d1SDavid du Colombier case 'd': 1593e12c5d1SDavid du Colombier debug = 1; 1603e12c5d1SDavid du Colombier break; 1613e12c5d1SDavid du Colombier default: 1623e12c5d1SDavid du Colombier usage(); 1633e12c5d1SDavid du Colombier }ARGEND 1643e12c5d1SDavid du Colombier if(argc && *argv) 1653e12c5d1SDavid du Colombier mtpt = *argv; 1663e12c5d1SDavid du Colombier 1677dd7cddfSDavid du Colombier if(debug) 1689a747e4fSDavid du Colombier fmtinstall('F', fcallfmt); 1697dd7cddfSDavid du Colombier 1703e12c5d1SDavid du Colombier cachesetup(format, part); 1713e12c5d1SDavid du Colombier 1723e12c5d1SDavid du Colombier c.name = "client"; 1733e12c5d1SDavid du Colombier s.name = "server"; 1743e12c5d1SDavid du Colombier if(std){ 1753e12c5d1SDavid du Colombier c.fd[0] = c.fd[1] = 1; 1763e12c5d1SDavid du Colombier s.fd[0] = s.fd[1] = 0; 1773e12c5d1SDavid du Colombier }else 1783e12c5d1SDavid du Colombier mountinit(server, mtpt); 1793e12c5d1SDavid du Colombier 1803e12c5d1SDavid du Colombier switch(fork()){ 1813e12c5d1SDavid du Colombier case 0: 1823e12c5d1SDavid du Colombier io(); 1833e12c5d1SDavid du Colombier exits(""); 1843e12c5d1SDavid du Colombier case -1: 1853e12c5d1SDavid du Colombier error("fork"); 1863e12c5d1SDavid du Colombier default: 1873e12c5d1SDavid du Colombier exits(""); 1883e12c5d1SDavid du Colombier } 1893e12c5d1SDavid du Colombier } 1903e12c5d1SDavid du Colombier 1913e12c5d1SDavid du Colombier void 1923e12c5d1SDavid du Colombier cachesetup(int format, char *partition) 1933e12c5d1SDavid du Colombier { 1943e12c5d1SDavid du Colombier int f; 1953e12c5d1SDavid du Colombier int secsize; 1963e12c5d1SDavid du Colombier int inodes; 1973e12c5d1SDavid du Colombier int blocksize; 1983e12c5d1SDavid du Colombier 1993e12c5d1SDavid du Colombier secsize = 512; 2003e12c5d1SDavid du Colombier inodes = 1024; 2013e12c5d1SDavid du Colombier blocksize = 4*1024; 2023e12c5d1SDavid du Colombier 2033e12c5d1SDavid du Colombier f = open(partition, ORDWR); 2043e12c5d1SDavid du Colombier if(f < 0) 2053e12c5d1SDavid du Colombier error("opening partition"); 2063e12c5d1SDavid du Colombier 2073e12c5d1SDavid du Colombier if(format || iinit(&ic, f, secsize)<0){ 2083e12c5d1SDavid du Colombier if(iformat(&ic, f, inodes, "bootes", blocksize, secsize) < 0) 2093e12c5d1SDavid du Colombier error("formatting failed"); 2103e12c5d1SDavid du Colombier } 2113e12c5d1SDavid du Colombier } 2123e12c5d1SDavid du Colombier 2133e12c5d1SDavid du Colombier void 2143e12c5d1SDavid du Colombier mountinit(char *server, char *mountpoint) 2153e12c5d1SDavid du Colombier { 2163e12c5d1SDavid du Colombier int p[2]; 2173e12c5d1SDavid du Colombier 2183e12c5d1SDavid du Colombier /* 2193e12c5d1SDavid du Colombier * grab a channel and call up the file server 2203e12c5d1SDavid du Colombier */ 2217dd7cddfSDavid du Colombier s.fd[0] = s.fd[1] = dial(netmkaddr(server, 0, "9fs"), 0, 0, 0); 2223e12c5d1SDavid du Colombier if(s.fd[0] < 0) 2233e12c5d1SDavid du Colombier error("opening data"); 2243e12c5d1SDavid du Colombier 2253e12c5d1SDavid du Colombier /* 2263e12c5d1SDavid du Colombier * mount onto name space 2273e12c5d1SDavid du Colombier */ 2283e12c5d1SDavid du Colombier if(pipe(p) < 0) 2293e12c5d1SDavid du Colombier error("pipe failed"); 2303e12c5d1SDavid du Colombier switch(fork()){ 2313e12c5d1SDavid du Colombier case 0: 232219b2ee8SDavid du Colombier break; 233219b2ee8SDavid du Colombier default: 234219b2ee8SDavid du Colombier if(amount(p[1], mountpoint, MREPL|MCREATE, "") < 0) 2353e12c5d1SDavid du Colombier error("mount failed"); 2363e12c5d1SDavid du Colombier exits(0); 2373e12c5d1SDavid du Colombier case -1: 2383e12c5d1SDavid du Colombier error("fork failed\n"); 2393e12c5d1SDavid du Colombier /*BUG: no wait!*/ 2403e12c5d1SDavid du Colombier } 2413e12c5d1SDavid du Colombier c.fd[0] = c.fd[1] = p[0]; 2423e12c5d1SDavid du Colombier } 2433e12c5d1SDavid du Colombier 2443e12c5d1SDavid du Colombier void 2453e12c5d1SDavid du Colombier io(void) 2463e12c5d1SDavid du Colombier { 2479a747e4fSDavid du Colombier int type; 2483e12c5d1SDavid du Colombier Mfile *mf; 2493e12c5d1SDavid du Colombier loop: 2503e12c5d1SDavid du Colombier rcvmsg(&c, &c.thdr); 2519a747e4fSDavid du Colombier 2529a747e4fSDavid du Colombier type = c.thdr.type; 2539a747e4fSDavid du Colombier 2549a747e4fSDavid du Colombier if(statson){ 2559a747e4fSDavid du Colombier cfsstat.cm[type].n++; 2569a747e4fSDavid du Colombier cfsstat.cm[type].s = nsec(); 2579a747e4fSDavid du Colombier } 2583e12c5d1SDavid du Colombier mf = &mfile[c.thdr.fid]; 2599a747e4fSDavid du Colombier switch(type){ 2603e12c5d1SDavid du Colombier default: 2613e12c5d1SDavid du Colombier error("type"); 2623e12c5d1SDavid du Colombier break; 2639a747e4fSDavid du Colombier case Tversion: 2649a747e4fSDavid du Colombier rversion(); 2653e12c5d1SDavid du Colombier break; 2669a747e4fSDavid du Colombier case Tauth: 2679a747e4fSDavid du Colombier mf = &mfile[c.thdr.afid]; 2689a747e4fSDavid du Colombier rauth(mf); 2693e12c5d1SDavid du Colombier break; 2703e12c5d1SDavid du Colombier case Tflush: 2713e12c5d1SDavid du Colombier rflush(); 2723e12c5d1SDavid du Colombier break; 2733e12c5d1SDavid du Colombier case Tattach: 2743e12c5d1SDavid du Colombier rattach(mf); 2753e12c5d1SDavid du Colombier break; 2763e12c5d1SDavid du Colombier case Twalk: 2773e12c5d1SDavid du Colombier rwalk(mf); 2783e12c5d1SDavid du Colombier break; 2793e12c5d1SDavid du Colombier case Topen: 2803e12c5d1SDavid du Colombier ropen(mf); 2813e12c5d1SDavid du Colombier break; 2823e12c5d1SDavid du Colombier case Tcreate: 2833e12c5d1SDavid du Colombier rcreate(mf); 2843e12c5d1SDavid du Colombier break; 2853e12c5d1SDavid du Colombier case Tread: 2863e12c5d1SDavid du Colombier rread(mf); 2873e12c5d1SDavid du Colombier break; 2883e12c5d1SDavid du Colombier case Twrite: 2893e12c5d1SDavid du Colombier rwrite(mf); 2903e12c5d1SDavid du Colombier break; 2913e12c5d1SDavid du Colombier case Tclunk: 2923e12c5d1SDavid du Colombier rclunk(mf); 2933e12c5d1SDavid du Colombier break; 2943e12c5d1SDavid du Colombier case Tremove: 2953e12c5d1SDavid du Colombier rremove(mf); 2963e12c5d1SDavid du Colombier break; 2973e12c5d1SDavid du Colombier case Tstat: 2983e12c5d1SDavid du Colombier rstat(mf); 2993e12c5d1SDavid du Colombier break; 3003e12c5d1SDavid du Colombier case Twstat: 3013e12c5d1SDavid du Colombier rwstat(mf); 3023e12c5d1SDavid du Colombier break; 3033e12c5d1SDavid du Colombier } 3049a747e4fSDavid du Colombier if(statson){ 3059a747e4fSDavid du Colombier cfsstat.cm[type].t += nsec() -cfsstat.cm[type].s; 3069a747e4fSDavid du Colombier } 3073e12c5d1SDavid du Colombier goto loop; 3083e12c5d1SDavid du Colombier } 3093e12c5d1SDavid du Colombier 3103e12c5d1SDavid du Colombier void 3119a747e4fSDavid du Colombier rversion(void) 312219b2ee8SDavid du Colombier { 3139a747e4fSDavid du Colombier if(messagesize > c.thdr.msize) 3149a747e4fSDavid du Colombier messagesize = c.thdr.msize; 3159a747e4fSDavid du Colombier c.thdr.msize = messagesize; /* set downstream size */ 316219b2ee8SDavid du Colombier delegate(); 317219b2ee8SDavid du Colombier } 318219b2ee8SDavid du Colombier 319219b2ee8SDavid du Colombier void 3209a747e4fSDavid du Colombier rauth(Mfile *mf) 3219a747e4fSDavid du Colombier { 3226b6b9ac8SDavid du Colombier if(mf->busy) 3236b6b9ac8SDavid du Colombier error("auth to used channel"); 3249a747e4fSDavid du Colombier 3259a747e4fSDavid du Colombier if(delegate() == 0){ 3266b6b9ac8SDavid du Colombier mf->qid = s.rhdr.aqid; 3279a747e4fSDavid du Colombier mf->busy = 1; 3289a747e4fSDavid du Colombier } 3299a747e4fSDavid du Colombier } 3309a747e4fSDavid du Colombier 3319a747e4fSDavid du Colombier void 3323e12c5d1SDavid du Colombier rflush(void) /* synchronous so easy */ 3333e12c5d1SDavid du Colombier { 3343e12c5d1SDavid du Colombier sendreply(0); 3353e12c5d1SDavid du Colombier } 3363e12c5d1SDavid du Colombier 3373e12c5d1SDavid du Colombier void 3383e12c5d1SDavid du Colombier rattach(Mfile *mf) 3393e12c5d1SDavid du Colombier { 3403e12c5d1SDavid du Colombier if(delegate() == 0){ 3413e12c5d1SDavid du Colombier mf->qid = s.rhdr.qid; 3423e12c5d1SDavid du Colombier mf->busy = 1; 3439a747e4fSDavid du Colombier if (statson == 1){ 3449a747e4fSDavid du Colombier statson++; 3459a747e4fSDavid du Colombier rootqid = mf->qid; 3463e12c5d1SDavid du Colombier } 3473e12c5d1SDavid du Colombier } 3483e12c5d1SDavid du Colombier } 3493e12c5d1SDavid du Colombier 3503e12c5d1SDavid du Colombier void 3513e12c5d1SDavid du Colombier rwalk(Mfile *mf) 3523e12c5d1SDavid du Colombier { 3539a747e4fSDavid du Colombier Mfile *nmf; 3549a747e4fSDavid du Colombier 3559a747e4fSDavid du Colombier nmf = nil; 3569a747e4fSDavid du Colombier if(statson 3579a747e4fSDavid du Colombier && mf->qid.type == rootqid.type && mf->qid.path == rootqid.path 3589a747e4fSDavid du Colombier && c.thdr.nwname == 1 && strcmp(c.thdr.wname[0], "cfsctl") == 0){ 3599a747e4fSDavid du Colombier /* This is the ctl file */ 3609a747e4fSDavid du Colombier nmf = &mfile[c.thdr.newfid]; 3619a747e4fSDavid du Colombier if(c.thdr.newfid != c.thdr.fid && nmf->busy) 3629a747e4fSDavid du Colombier error("clone to used channel"); 3639a747e4fSDavid du Colombier nmf = &mfile[c.thdr.newfid]; 3649a747e4fSDavid du Colombier nmf->qid = ctlqid; 3659a747e4fSDavid du Colombier nmf->busy = 1; 3669a747e4fSDavid du Colombier c.rhdr.nwqid = 1; 3679a747e4fSDavid du Colombier c.rhdr.wqid[0] = ctlqid; 3689a747e4fSDavid du Colombier sendreply(0); 3693e12c5d1SDavid du Colombier return; 3703e12c5d1SDavid du Colombier } 3719a747e4fSDavid du Colombier if(c.thdr.newfid != c.thdr.fid){ 37222a127bbSDavid du Colombier if(c.thdr.newfid >= Nfid) 3739a747e4fSDavid du Colombier error("clone nfid out of range"); 3749a747e4fSDavid du Colombier nmf = &mfile[c.thdr.newfid]; 3759a747e4fSDavid du Colombier if(nmf->busy) 3769a747e4fSDavid du Colombier error("clone to used channel"); 3779a747e4fSDavid du Colombier nmf = &mfile[c.thdr.newfid]; 3789a747e4fSDavid du Colombier nmf->qid = mf->qid; 3799a747e4fSDavid du Colombier nmf->busy = 1; 3809a747e4fSDavid du Colombier mf = nmf; /* Walk mf */ 3813e12c5d1SDavid du Colombier } 3823e12c5d1SDavid du Colombier 3839a747e4fSDavid du Colombier if(delegate() < 0){ /* complete failure */ 3849a747e4fSDavid du Colombier if(nmf) 3859a747e4fSDavid du Colombier nmf->busy = 0; 3869a747e4fSDavid du Colombier return; 3879a747e4fSDavid du Colombier } 3889a747e4fSDavid du Colombier 3899a747e4fSDavid du Colombier if(s.rhdr.nwqid == c.thdr.nwname){ /* complete success */ 3909a747e4fSDavid du Colombier if(s.rhdr.nwqid > 0) 3919a747e4fSDavid du Colombier mf->qid = s.rhdr.wqid[s.rhdr.nwqid-1]; 3929a747e4fSDavid du Colombier return; 3939a747e4fSDavid du Colombier } 3949a747e4fSDavid du Colombier 3959a747e4fSDavid du Colombier /* partial success; release fid */ 3969a747e4fSDavid du Colombier if(nmf) 3979a747e4fSDavid du Colombier nmf->busy = 0; 3983e12c5d1SDavid du Colombier } 3993e12c5d1SDavid du Colombier 4003e12c5d1SDavid du Colombier void 4013e12c5d1SDavid du Colombier ropen(Mfile *mf) 4023e12c5d1SDavid du Colombier { 4039a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 4049a747e4fSDavid du Colombier /* Opening ctl file */ 4059a747e4fSDavid du Colombier if(c.thdr.mode != OREAD){ 4069a747e4fSDavid du Colombier sendreply("does not exist"); 4079a747e4fSDavid du Colombier return; 4089a747e4fSDavid du Colombier } 4099a747e4fSDavid du Colombier c.rhdr.qid = ctlqid; 4109a747e4fSDavid du Colombier c.rhdr.iounit = 0; 4119a747e4fSDavid du Colombier sendreply(0); 4129a747e4fSDavid du Colombier genstats(); 4139a747e4fSDavid du Colombier return; 4149a747e4fSDavid du Colombier } 4153e12c5d1SDavid du Colombier if(delegate() == 0){ 4163e12c5d1SDavid du Colombier mf->qid = s.rhdr.qid; 4177dd7cddfSDavid du Colombier if(c.thdr.mode & OTRUNC) 4183e12c5d1SDavid du Colombier iget(&ic, mf->qid); 4193e12c5d1SDavid du Colombier } 4203e12c5d1SDavid du Colombier } 4213e12c5d1SDavid du Colombier 4223e12c5d1SDavid du Colombier void 4233e12c5d1SDavid du Colombier rcreate(Mfile *mf) 4243e12c5d1SDavid du Colombier { 4259a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 4269a747e4fSDavid du Colombier sendreply("exists"); 4279a747e4fSDavid du Colombier return; 4289a747e4fSDavid du Colombier } 4293e12c5d1SDavid du Colombier if(delegate() == 0){ 4303e12c5d1SDavid du Colombier mf->qid = s.rhdr.qid; 4313e12c5d1SDavid du Colombier mf->qid.vers++; 4323e12c5d1SDavid du Colombier } 4333e12c5d1SDavid du Colombier } 4343e12c5d1SDavid du Colombier 4353e12c5d1SDavid du Colombier void 4363e12c5d1SDavid du Colombier rclunk(Mfile *mf) 4373e12c5d1SDavid du Colombier { 4383e12c5d1SDavid du Colombier if(!mf->busy){ 4393e12c5d1SDavid du Colombier sendreply(0); 4403e12c5d1SDavid du Colombier return; 4413e12c5d1SDavid du Colombier } 4423e12c5d1SDavid du Colombier mf->busy = 0; 4433ff48bf5SDavid du Colombier delegate(); 4443e12c5d1SDavid du Colombier } 4453e12c5d1SDavid du Colombier 4463e12c5d1SDavid du Colombier void 4473e12c5d1SDavid du Colombier rremove(Mfile *mf) 4483e12c5d1SDavid du Colombier { 4499a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 4509a747e4fSDavid du Colombier sendreply("not removed"); 4519a747e4fSDavid du Colombier return; 4529a747e4fSDavid du Colombier } 4533e12c5d1SDavid du Colombier mf->busy = 0; 4543e12c5d1SDavid du Colombier delegate(); 4553e12c5d1SDavid du Colombier } 4563e12c5d1SDavid du Colombier 4573e12c5d1SDavid du Colombier void 4583e12c5d1SDavid du Colombier rread(Mfile *mf) 4593e12c5d1SDavid du Colombier { 460*41fb754aSDavid du Colombier int cnt, done; 4613e12c5d1SDavid du Colombier long n; 462*41fb754aSDavid du Colombier vlong off, first; 463*41fb754aSDavid du Colombier char *cp; 4643e12c5d1SDavid du Colombier char data[MAXFDATA]; 465*41fb754aSDavid du Colombier Ibuf *b; 4663e12c5d1SDavid du Colombier 467*41fb754aSDavid du Colombier off = c.thdr.offset; 468*41fb754aSDavid du Colombier first = off; 4693e12c5d1SDavid du Colombier cnt = c.thdr.count; 4703e12c5d1SDavid du Colombier 4719a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 4729a747e4fSDavid du Colombier if(cnt > statlen-off) 4739a747e4fSDavid du Colombier c.rhdr.count = statlen-off; 4749a747e4fSDavid du Colombier else 4759a747e4fSDavid du Colombier c.rhdr.count = cnt; 47622a127bbSDavid du Colombier if((int)c.rhdr.count < 0){ 4779a747e4fSDavid du Colombier sendreply("eof"); 4789a747e4fSDavid du Colombier return; 4799a747e4fSDavid du Colombier } 4809a747e4fSDavid du Colombier c.rhdr.data = statbuf + off; 4819a747e4fSDavid du Colombier sendreply(0); 4829a747e4fSDavid du Colombier return; 4839a747e4fSDavid du Colombier } 4849a747e4fSDavid du Colombier if(mf->qid.type & (QTDIR|QTAUTH)){ 4853e12c5d1SDavid du Colombier delegate(); 4869a747e4fSDavid du Colombier if (statson) { 4879a747e4fSDavid du Colombier cfsstat.ndirread++; 4889a747e4fSDavid du Colombier if(c.rhdr.count > 0){ 4899a747e4fSDavid du Colombier cfsstat.bytesread += c.rhdr.count; 4909a747e4fSDavid du Colombier cfsstat.bytesfromdirs += c.rhdr.count; 4919a747e4fSDavid du Colombier } 4929a747e4fSDavid du Colombier } 4933e12c5d1SDavid du Colombier return; 4943e12c5d1SDavid du Colombier } 4953e12c5d1SDavid du Colombier 4963e12c5d1SDavid du Colombier b = iget(&ic, mf->qid); 4973e12c5d1SDavid du Colombier if(b == 0){ 4989a747e4fSDavid du Colombier DPRINT(2, "delegating read\n"); 4993e12c5d1SDavid du Colombier delegate(); 5009a747e4fSDavid du Colombier if (statson){ 5019a747e4fSDavid du Colombier cfsstat.ndelegateread++; 5029a747e4fSDavid du Colombier if(c.rhdr.count > 0){ 5039a747e4fSDavid du Colombier cfsstat.bytesread += c.rhdr.count; 5049a747e4fSDavid du Colombier cfsstat.bytesfromserver += c.rhdr.count; 5059a747e4fSDavid du Colombier } 5069a747e4fSDavid du Colombier } 5073e12c5d1SDavid du Colombier return; 5083e12c5d1SDavid du Colombier } 5093e12c5d1SDavid du Colombier 5103e12c5d1SDavid du Colombier cp = data; 5113e12c5d1SDavid du Colombier done = 0; 5123e12c5d1SDavid du Colombier while(cnt>0 && !done){ 5139a747e4fSDavid du Colombier if(off >= b->inode.length){ 514*41fb754aSDavid du Colombier DPRINT(2, "offset %lld greater than length %lld\n", 515*41fb754aSDavid du Colombier off, b->inode.length); 5169a747e4fSDavid du Colombier break; 5179a747e4fSDavid du Colombier } 5183e12c5d1SDavid du Colombier n = fread(&ic, b, cp, off, cnt); 5193e12c5d1SDavid du Colombier if(n <= 0){ 5203e12c5d1SDavid du Colombier n = -n; 5213e12c5d1SDavid du Colombier if(n==0 || n>cnt) 5223e12c5d1SDavid du Colombier n = cnt; 523*41fb754aSDavid du Colombier DPRINT(2, 524*41fb754aSDavid du Colombier "fetch %ld bytes of data from server at offset %lld\n", 525*41fb754aSDavid du Colombier n, off); 5263e12c5d1SDavid du Colombier s.thdr.type = c.thdr.type; 5273e12c5d1SDavid du Colombier s.thdr.fid = c.thdr.fid; 5283e12c5d1SDavid du Colombier s.thdr.tag = c.thdr.tag; 5293e12c5d1SDavid du Colombier s.thdr.offset = off; 5303e12c5d1SDavid du Colombier s.thdr.count = n; 531*41fb754aSDavid du Colombier if(statson) 5329a747e4fSDavid du Colombier cfsstat.ndelegateread++; 53380ee5cbfSDavid du Colombier if(askserver() < 0){ 5343e12c5d1SDavid du Colombier sendreply(s.rhdr.ename); 53580ee5cbfSDavid du Colombier return; 53680ee5cbfSDavid du Colombier } 5373e12c5d1SDavid du Colombier if(s.rhdr.count != n) 5383e12c5d1SDavid du Colombier done = 1; 5393e12c5d1SDavid du Colombier n = s.rhdr.count; 5409a747e4fSDavid du Colombier if(n == 0){ 5419a747e4fSDavid du Colombier /* end of file */ 5429a747e4fSDavid du Colombier if(b->inode.length > off){ 543*41fb754aSDavid du Colombier DPRINT(2, "file %llud.%ld, length %lld\n", 544*41fb754aSDavid du Colombier b->inode.qid.path, 545*41fb754aSDavid du Colombier b->inode.qid.vers, off); 5469a747e4fSDavid du Colombier b->inode.length = off; 5479a747e4fSDavid du Colombier } 5489a747e4fSDavid du Colombier break; 5499a747e4fSDavid du Colombier } 5503e12c5d1SDavid du Colombier memmove(cp, s.rhdr.data, n); 5513e12c5d1SDavid du Colombier fwrite(&ic, b, cp, off, n); 5529a747e4fSDavid du Colombier if (statson){ 5539a747e4fSDavid du Colombier cfsstat.bytestocache += n; 5549a747e4fSDavid du Colombier cfsstat.bytesfromserver += n; 5559a747e4fSDavid du Colombier } 5569a747e4fSDavid du Colombier }else{ 5579a747e4fSDavid du Colombier DPRINT(2, "fetched %ld bytes from cache\n", n); 558*41fb754aSDavid du Colombier if(statson) 5599a747e4fSDavid du Colombier cfsstat.bytesfromcache += n; 5609a747e4fSDavid du Colombier } 5613e12c5d1SDavid du Colombier cnt -= n; 5623e12c5d1SDavid du Colombier off += n; 5633e12c5d1SDavid du Colombier cp += n; 5643e12c5d1SDavid du Colombier } 5653e12c5d1SDavid du Colombier c.rhdr.data = data; 5663e12c5d1SDavid du Colombier c.rhdr.count = off - first; 567*41fb754aSDavid du Colombier if(statson) 5689a747e4fSDavid du Colombier cfsstat.bytesread += c.rhdr.count; 5693e12c5d1SDavid du Colombier sendreply(0); 5703e12c5d1SDavid du Colombier } 5713e12c5d1SDavid du Colombier 5723e12c5d1SDavid du Colombier void 5733e12c5d1SDavid du Colombier rwrite(Mfile *mf) 5743e12c5d1SDavid du Colombier { 5753e12c5d1SDavid du Colombier Ibuf *b; 5763e12c5d1SDavid du Colombier char buf[MAXFDATA]; 5773e12c5d1SDavid du Colombier 5789a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 5799a747e4fSDavid du Colombier sendreply("read only"); 5809a747e4fSDavid du Colombier return; 5819a747e4fSDavid du Colombier } 5829a747e4fSDavid du Colombier if(mf->qid.type & (QTDIR|QTAUTH)){ 5833e12c5d1SDavid du Colombier delegate(); 5849a747e4fSDavid du Colombier if(statson && c.rhdr.count > 0) 5859a747e4fSDavid du Colombier cfsstat.byteswritten += c.rhdr.count; 5863e12c5d1SDavid du Colombier return; 5873e12c5d1SDavid du Colombier } 5883e12c5d1SDavid du Colombier 5893e12c5d1SDavid du Colombier memmove(buf, c.thdr.data, c.thdr.count); 5903e12c5d1SDavid du Colombier if(delegate() < 0) 5913e12c5d1SDavid du Colombier return; 5923e12c5d1SDavid du Colombier 5939a747e4fSDavid du Colombier if(s.rhdr.count > 0) 5949a747e4fSDavid du Colombier cfsstat.byteswritten += s.rhdr.count; 595*41fb754aSDavid du Colombier /* don't modify our cache for append-only data; always read from server*/ 596*41fb754aSDavid du Colombier if(mf->qid.type & QTAPPEND) 5979a747e4fSDavid du Colombier return; 5983e12c5d1SDavid du Colombier b = iget(&ic, mf->qid); 5993e12c5d1SDavid du Colombier if(b == 0) 6003e12c5d1SDavid du Colombier return; 6019a747e4fSDavid du Colombier if (b->inode.length < c.thdr.offset + s.rhdr.count) 6029a747e4fSDavid du Colombier b->inode.length = c.thdr.offset + s.rhdr.count; 6033e12c5d1SDavid du Colombier mf->qid.vers++; 6049a747e4fSDavid du Colombier if (s.rhdr.count != c.thdr.count) 6059a747e4fSDavid du Colombier syslog(0, "cfslog", "rhdr.count %ud, thdr.count %ud\n", 6069a747e4fSDavid du Colombier s.rhdr.count, c.thdr.count); 6079a747e4fSDavid du Colombier if(fwrite(&ic, b, buf, c.thdr.offset, s.rhdr.count) == s.rhdr.count){ 6083e12c5d1SDavid du Colombier iinc(&ic, b); 6099a747e4fSDavid du Colombier if(statson) 6109a747e4fSDavid du Colombier cfsstat.bytestocache += s.rhdr.count; 6119a747e4fSDavid du Colombier } 6123e12c5d1SDavid du Colombier } 6133e12c5d1SDavid du Colombier 6143e12c5d1SDavid du Colombier void 6153e12c5d1SDavid du Colombier rstat(Mfile *mf) 6163e12c5d1SDavid du Colombier { 6179a747e4fSDavid du Colombier Dir d; 6189a747e4fSDavid du Colombier 6199a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 6209a747e4fSDavid du Colombier genstats(); 6219a747e4fSDavid du Colombier d.qid = ctlqid; 6229a747e4fSDavid du Colombier d.mode = 0444; 6239a747e4fSDavid du Colombier d.length = statlen; /* would be nice to do better */ 6249a747e4fSDavid du Colombier d.name = "cfsctl"; 6259a747e4fSDavid du Colombier d.uid = "none"; 6269a747e4fSDavid du Colombier d.gid = "none"; 6279a747e4fSDavid du Colombier d.muid = "none"; 6289a747e4fSDavid du Colombier d.atime = time(nil); 6299a747e4fSDavid du Colombier d.mtime = d.atime; 630*41fb754aSDavid du Colombier c.rhdr.nstat = convD2M(&d, c.rhdr.stat, 631*41fb754aSDavid du Colombier sizeof c.rhdr - (c.rhdr.stat - (uchar*)&c.rhdr)); 6329a747e4fSDavid du Colombier sendreply(0); 6339a747e4fSDavid du Colombier return; 6349a747e4fSDavid du Colombier } 6359a747e4fSDavid du Colombier if(delegate() == 0){ 6369a747e4fSDavid du Colombier Ibuf *b; 6379a747e4fSDavid du Colombier 6389a747e4fSDavid du Colombier convM2D(s.rhdr.stat, s.rhdr.nstat , &d, nil); 6399a747e4fSDavid du Colombier mf->qid = d.qid; 6409a747e4fSDavid du Colombier b = iget(&ic, mf->qid); 6419a747e4fSDavid du Colombier if(b) 6429a747e4fSDavid du Colombier b->inode.length = d.length; 6439a747e4fSDavid du Colombier } 6443e12c5d1SDavid du Colombier } 6453e12c5d1SDavid du Colombier 6463e12c5d1SDavid du Colombier void 6473e12c5d1SDavid du Colombier rwstat(Mfile *mf) 6483e12c5d1SDavid du Colombier { 6499a747e4fSDavid du Colombier Ibuf *b; 6509a747e4fSDavid du Colombier 6519a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 6529a747e4fSDavid du Colombier sendreply("read only"); 6539a747e4fSDavid du Colombier return; 6549a747e4fSDavid du Colombier } 6553e12c5d1SDavid du Colombier delegate(); 6569a747e4fSDavid du Colombier if(b = iget(&ic, mf->qid)) 6579a747e4fSDavid du Colombier b->inode.length = MAXLEN; 6583e12c5d1SDavid du Colombier } 6593e12c5d1SDavid du Colombier 6603e12c5d1SDavid du Colombier void 661*41fb754aSDavid du Colombier error(char *fmt, ...) 662*41fb754aSDavid du Colombier { 6639a747e4fSDavid du Colombier va_list arg; 6649a747e4fSDavid du Colombier static char buf[2048]; 6659a747e4fSDavid du Colombier 6669a747e4fSDavid du Colombier va_start(arg, fmt); 6679a747e4fSDavid du Colombier vseprint(buf, buf+sizeof(buf), fmt, arg); 6689a747e4fSDavid du Colombier va_end(arg); 6699a747e4fSDavid du Colombier fprint(2, "%s: %s\n", argv0, buf); 6709a747e4fSDavid du Colombier exits("error"); 6713e12c5d1SDavid du Colombier } 6723e12c5d1SDavid du Colombier 6733e12c5d1SDavid du Colombier void 6743e12c5d1SDavid du Colombier warning(char *s) 6753e12c5d1SDavid du Colombier { 6767dd7cddfSDavid du Colombier fprint(2, "cfs: %s: %r\n", s); 6773e12c5d1SDavid du Colombier } 6783e12c5d1SDavid du Colombier 6793e12c5d1SDavid du Colombier /* 6803e12c5d1SDavid du Colombier * send a reply to the client 6813e12c5d1SDavid du Colombier */ 6823e12c5d1SDavid du Colombier void 6833e12c5d1SDavid du Colombier sendreply(char *err) 6843e12c5d1SDavid du Colombier { 6853e12c5d1SDavid du Colombier 6863e12c5d1SDavid du Colombier if(err){ 6873e12c5d1SDavid du Colombier c.rhdr.type = Rerror; 6889a747e4fSDavid du Colombier c.rhdr.ename = err; 6893e12c5d1SDavid du Colombier }else{ 6903e12c5d1SDavid du Colombier c.rhdr.type = c.thdr.type+1; 6913e12c5d1SDavid du Colombier c.rhdr.fid = c.thdr.fid; 6923e12c5d1SDavid du Colombier } 6933e12c5d1SDavid du Colombier c.rhdr.tag = c.thdr.tag; 6943e12c5d1SDavid du Colombier sendmsg(&c, &c.rhdr); 6953e12c5d1SDavid du Colombier } 6963e12c5d1SDavid du Colombier 6973e12c5d1SDavid du Colombier /* 6983e12c5d1SDavid du Colombier * send a request to the server, get the reply, and send that to 6993e12c5d1SDavid du Colombier * the client 7003e12c5d1SDavid du Colombier */ 7013e12c5d1SDavid du Colombier int 7023e12c5d1SDavid du Colombier delegate(void) 7033e12c5d1SDavid du Colombier { 7049a747e4fSDavid du Colombier int type; 7059a747e4fSDavid du Colombier 7069a747e4fSDavid du Colombier type = c.thdr.type; 7079a747e4fSDavid du Colombier if(statson){ 7089a747e4fSDavid du Colombier cfsstat.sm[type].n++; 7099a747e4fSDavid du Colombier cfsstat.sm[type].s = nsec(); 7109a747e4fSDavid du Colombier } 7119a747e4fSDavid du Colombier 7123e12c5d1SDavid du Colombier sendmsg(&s, &c.thdr); 7133e12c5d1SDavid du Colombier rcvmsg(&s, &s.rhdr); 7149a747e4fSDavid du Colombier 715*41fb754aSDavid du Colombier if(statson) 7169a747e4fSDavid du Colombier cfsstat.sm[type].t += nsec() - cfsstat.sm[type].s; 7179a747e4fSDavid du Colombier 7183e12c5d1SDavid du Colombier sendmsg(&c, &s.rhdr); 7193e12c5d1SDavid du Colombier return c.thdr.type+1 == s.rhdr.type ? 0 : -1; 7203e12c5d1SDavid du Colombier } 7213e12c5d1SDavid du Colombier 7223e12c5d1SDavid du Colombier /* 7233e12c5d1SDavid du Colombier * send a request to the server and get a reply 7243e12c5d1SDavid du Colombier */ 7253e12c5d1SDavid du Colombier int 7263e12c5d1SDavid du Colombier askserver(void) 7273e12c5d1SDavid du Colombier { 7289a747e4fSDavid du Colombier int type; 7299a747e4fSDavid du Colombier 7303e12c5d1SDavid du Colombier s.thdr.tag = c.thdr.tag; 7319a747e4fSDavid du Colombier 7329a747e4fSDavid du Colombier type = s.thdr.type; 7339a747e4fSDavid du Colombier if(statson){ 7349a747e4fSDavid du Colombier cfsstat.sm[type].n++; 7359a747e4fSDavid du Colombier cfsstat.sm[type].s = nsec(); 7369a747e4fSDavid du Colombier } 7379a747e4fSDavid du Colombier 7383e12c5d1SDavid du Colombier sendmsg(&s, &s.thdr); 7393e12c5d1SDavid du Colombier rcvmsg(&s, &s.rhdr); 7409a747e4fSDavid du Colombier 741*41fb754aSDavid du Colombier if(statson) 7429a747e4fSDavid du Colombier cfsstat.sm[type].t += nsec() - cfsstat.sm[type].s; 7439a747e4fSDavid du Colombier 7443e12c5d1SDavid du Colombier return s.thdr.type+1 == s.rhdr.type ? 0 : -1; 7453e12c5d1SDavid du Colombier } 7463e12c5d1SDavid du Colombier 7473e12c5d1SDavid du Colombier /* 7483e12c5d1SDavid du Colombier * send/receive messages with logging 7493e12c5d1SDavid du Colombier */ 7503e12c5d1SDavid du Colombier void 7513e12c5d1SDavid du Colombier sendmsg(P9fs *p, Fcall *f) 7523e12c5d1SDavid du Colombier { 7537dd7cddfSDavid du Colombier DPRINT(2, "->%s: %F\n", p->name, f); 7543e12c5d1SDavid du Colombier 7559a747e4fSDavid du Colombier p->len = convS2M(f, datasnd, messagesize); 7569a747e4fSDavid du Colombier if(p->len <= 0) 7579a747e4fSDavid du Colombier error("convS2M"); 7589a747e4fSDavid du Colombier if(write(p->fd[1], datasnd, p->len)!=p->len) 7599a747e4fSDavid du Colombier error("sendmsg"); 7603e12c5d1SDavid du Colombier } 7613e12c5d1SDavid du Colombier 7623e12c5d1SDavid du Colombier void 7633e12c5d1SDavid du Colombier dump(uchar *p, int len) 7643e12c5d1SDavid du Colombier { 7653e12c5d1SDavid du Colombier fprint(2, "%d bytes", len); 766*41fb754aSDavid du Colombier while(len-- > 0) 7673e12c5d1SDavid du Colombier fprint(2, " %.2ux", *p++); 7683e12c5d1SDavid du Colombier fprint(2, "\n"); 7693e12c5d1SDavid du Colombier } 7703e12c5d1SDavid du Colombier 7713e12c5d1SDavid du Colombier void 7723e12c5d1SDavid du Colombier rcvmsg(P9fs *p, Fcall *f) 7733e12c5d1SDavid du Colombier { 7749a747e4fSDavid du Colombier int olen, rlen; 7757dd7cddfSDavid du Colombier char buf[128]; 7763e12c5d1SDavid du Colombier 7773e12c5d1SDavid du Colombier olen = p->len; 7789a747e4fSDavid du Colombier p->len = read9pmsg(p->fd[0], datarcv, sizeof(datarcv)); 7797dd7cddfSDavid du Colombier if(p->len <= 0){ 780*41fb754aSDavid du Colombier snprint(buf, sizeof buf, "read9pmsg(%d)->%ld: %r", 781*41fb754aSDavid du Colombier p->fd[0], p->len); 7827dd7cddfSDavid du Colombier error(buf); 7837dd7cddfSDavid du Colombier } 7849a747e4fSDavid du Colombier 7859a747e4fSDavid du Colombier if((rlen = convM2S(datarcv, p->len, f)) != p->len) 786*41fb754aSDavid du Colombier error("rcvmsg format error, expected length %d, got %d", 787*41fb754aSDavid du Colombier rlen, p->len); 78822a127bbSDavid du Colombier if(f->fid >= Nfid){ 7893e12c5d1SDavid du Colombier fprint(2, "<-%s: %d %s on %d\n", p->name, f->type, 790*41fb754aSDavid du Colombier mname[f->type]? mname[f->type]: "mystery", f->fid); 7913e12c5d1SDavid du Colombier dump((uchar*)datasnd, olen); 7923e12c5d1SDavid du Colombier dump((uchar*)datarcv, p->len); 7933e12c5d1SDavid du Colombier error("rcvmsg fid out of range"); 7943e12c5d1SDavid du Colombier } 7957dd7cddfSDavid du Colombier DPRINT(2, "<-%s: %F\n", p->name, f); 7963e12c5d1SDavid du Colombier } 7979a747e4fSDavid du Colombier 7989a747e4fSDavid du Colombier int 7999a747e4fSDavid du Colombier ctltest(Mfile *mf) 8009a747e4fSDavid du Colombier { 801*41fb754aSDavid du Colombier return mf->busy && mf->qid.type == ctlqid.type && 802*41fb754aSDavid du Colombier mf->qid.path == ctlqid.path; 8039a747e4fSDavid du Colombier } 8049a747e4fSDavid du Colombier 8059a747e4fSDavid du Colombier void 8069a747e4fSDavid du Colombier genstats(void) 8079a747e4fSDavid du Colombier { 8089a747e4fSDavid du Colombier int i; 8099a747e4fSDavid du Colombier char *p; 8109a747e4fSDavid du Colombier 8119a747e4fSDavid du Colombier p = statbuf; 8129a747e4fSDavid du Colombier 813*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 814*41fb754aSDavid du Colombier " Client Server\n"); 815*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 816*41fb754aSDavid du Colombier " #calls Δ ms/call Δ #calls Δ ms/call Δ\n"); 8179a747e4fSDavid du Colombier for (i = 0; i < nelem(cfsstat.cm); i++) 8189a747e4fSDavid du Colombier if(cfsstat.cm[i].n || cfsstat.sm[i].n) { 819*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 820*41fb754aSDavid du Colombier "%7lud %7lud ", cfsstat.cm[i].n, 821*41fb754aSDavid du Colombier cfsstat.cm[i].n - cfsprev.cm[i].n); 8229a747e4fSDavid du Colombier if (cfsstat.cm[i].n) 823*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 824*41fb754aSDavid du Colombier "%7.3f ", 0.000001*cfsstat.cm[i].t/ 825*41fb754aSDavid du Colombier cfsstat.cm[i].n); 8269a747e4fSDavid du Colombier else 827*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 828*41fb754aSDavid du Colombier " "); 8299a747e4fSDavid du Colombier if(cfsstat.cm[i].n - cfsprev.cm[i].n) 830*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 831*41fb754aSDavid du Colombier "%7.3f ", 0.000001* 832*41fb754aSDavid du Colombier (cfsstat.cm[i].t - cfsprev.cm[i].t)/ 833*41fb754aSDavid du Colombier (cfsstat.cm[i].n - cfsprev.cm[i].n)); 8349a747e4fSDavid du Colombier else 835*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 836*41fb754aSDavid du Colombier " "); 837*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 838*41fb754aSDavid du Colombier "%7lud %7lud ", cfsstat.sm[i].n, 839*41fb754aSDavid du Colombier cfsstat.sm[i].n - cfsprev.sm[i].n); 8409a747e4fSDavid du Colombier if (cfsstat.sm[i].n) 841*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 842*41fb754aSDavid du Colombier "%7.3f ", 0.000001*cfsstat.sm[i].t/ 843*41fb754aSDavid du Colombier cfsstat.sm[i].n); 8449a747e4fSDavid du Colombier else 845*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 846*41fb754aSDavid du Colombier " "); 8479a747e4fSDavid du Colombier if(cfsstat.sm[i].n - cfsprev.sm[i].n) 848*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 849*41fb754aSDavid du Colombier "%7.3f ", 0.000001* 850*41fb754aSDavid du Colombier (cfsstat.sm[i].t - cfsprev.sm[i].t)/ 851*41fb754aSDavid du Colombier (cfsstat.sm[i].n - cfsprev.sm[i].n)); 8529a747e4fSDavid du Colombier else 853*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 854*41fb754aSDavid du Colombier " "); 855*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%s\n", 856*41fb754aSDavid du Colombier mname[i]); 8579a747e4fSDavid du Colombier } 858*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7lud %7lud ndirread\n", 8599a747e4fSDavid du Colombier cfsstat.ndirread, cfsstat.ndirread - cfsprev.ndirread); 860*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7lud %7lud ndelegateread\n", 861*41fb754aSDavid du Colombier cfsstat.ndelegateread, cfsstat.ndelegateread - 862*41fb754aSDavid du Colombier cfsprev.ndelegateread); 863*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7lud %7lud ninsert\n", 8649a747e4fSDavid du Colombier cfsstat.ninsert, cfsstat.ninsert - cfsprev.ninsert); 865*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7lud %7lud ndelete\n", 8669a747e4fSDavid du Colombier cfsstat.ndelete, cfsstat.ndelete - cfsprev.ndelete); 867*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7lud %7lud nupdate\n", 8689a747e4fSDavid du Colombier cfsstat.nupdate, cfsstat.nupdate - cfsprev.nupdate); 8699a747e4fSDavid du Colombier 870*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud bytesread\n", 8719a747e4fSDavid du Colombier cfsstat.bytesread, cfsstat.bytesread - cfsprev.bytesread); 872*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud byteswritten\n", 873*41fb754aSDavid du Colombier cfsstat.byteswritten, cfsstat.byteswritten - 874*41fb754aSDavid du Colombier cfsprev.byteswritten); 875*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud bytesfromserver\n", 876*41fb754aSDavid du Colombier cfsstat.bytesfromserver, cfsstat.bytesfromserver - 877*41fb754aSDavid du Colombier cfsprev.bytesfromserver); 878*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud bytesfromdirs\n", 879*41fb754aSDavid du Colombier cfsstat.bytesfromdirs, cfsstat.bytesfromdirs - 880*41fb754aSDavid du Colombier cfsprev.bytesfromdirs); 881*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud bytesfromcache\n", 882*41fb754aSDavid du Colombier cfsstat.bytesfromcache, cfsstat.bytesfromcache - 883*41fb754aSDavid du Colombier cfsprev.bytesfromcache); 884*41fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud bytestocache\n", 885*41fb754aSDavid du Colombier cfsstat.bytestocache, cfsstat.bytestocache - 886*41fb754aSDavid du Colombier cfsprev.bytestocache); 8879a747e4fSDavid du Colombier statlen = p - statbuf; 8889a747e4fSDavid du Colombier cfsprev = cfsstat; 8899a747e4fSDavid du Colombier } 890