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"; 1397dd7cddfSDavid du Colombier server = "il!emelie"; 1403e12c5d1SDavid du Colombier mtpt = "/tmp"; 1413e12c5d1SDavid du Colombier 1423e12c5d1SDavid du Colombier ARGBEGIN{ 1433e12c5d1SDavid du Colombier case 'a': 1443e12c5d1SDavid du Colombier server = ARGF(); 1453e12c5d1SDavid du Colombier if(server == 0) 1463e12c5d1SDavid du Colombier usage(); 1473e12c5d1SDavid du Colombier break; 1489a747e4fSDavid du Colombier case 'S': 1499a747e4fSDavid du Colombier statson = 1; 1509a747e4fSDavid du Colombier break; 1513e12c5d1SDavid du Colombier case 's': 1523e12c5d1SDavid du Colombier std = 1; 1533e12c5d1SDavid du Colombier break; 1543e12c5d1SDavid du Colombier case 'r': 1553e12c5d1SDavid du Colombier format = 1; 1563e12c5d1SDavid du Colombier break; 1573e12c5d1SDavid du Colombier case 'f': 1583e12c5d1SDavid du Colombier part = ARGF(); 1593e12c5d1SDavid du Colombier if(part == 0) 1603e12c5d1SDavid du Colombier usage(); 1613e12c5d1SDavid du Colombier break; 1623e12c5d1SDavid du Colombier case 'd': 1633e12c5d1SDavid du Colombier debug = 1; 1643e12c5d1SDavid du Colombier break; 1653e12c5d1SDavid du Colombier default: 1663e12c5d1SDavid du Colombier usage(); 1673e12c5d1SDavid du Colombier }ARGEND 1683e12c5d1SDavid du Colombier if(argc && *argv) 1693e12c5d1SDavid du Colombier mtpt = *argv; 1703e12c5d1SDavid du Colombier 1717dd7cddfSDavid du Colombier if(debug) 1729a747e4fSDavid du Colombier fmtinstall('F', fcallfmt); 1737dd7cddfSDavid du Colombier 1743e12c5d1SDavid du Colombier cachesetup(format, part); 1753e12c5d1SDavid du Colombier 1763e12c5d1SDavid du Colombier c.name = "client"; 1773e12c5d1SDavid du Colombier s.name = "server"; 1783e12c5d1SDavid du Colombier if(std){ 1793e12c5d1SDavid du Colombier c.fd[0] = c.fd[1] = 1; 1803e12c5d1SDavid du Colombier s.fd[0] = s.fd[1] = 0; 1813e12c5d1SDavid du Colombier }else 1823e12c5d1SDavid du Colombier mountinit(server, mtpt); 1833e12c5d1SDavid du Colombier 1843e12c5d1SDavid du Colombier switch(fork()){ 1853e12c5d1SDavid du Colombier case 0: 1863e12c5d1SDavid du Colombier io(); 1873e12c5d1SDavid du Colombier exits(""); 1883e12c5d1SDavid du Colombier case -1: 1893e12c5d1SDavid du Colombier error("fork"); 1903e12c5d1SDavid du Colombier default: 1913e12c5d1SDavid du Colombier exits(""); 1923e12c5d1SDavid du Colombier } 1933e12c5d1SDavid du Colombier } 1943e12c5d1SDavid du Colombier 1953e12c5d1SDavid du Colombier void 1963e12c5d1SDavid du Colombier cachesetup(int format, char *partition) 1973e12c5d1SDavid du Colombier { 1983e12c5d1SDavid du Colombier int f; 1993e12c5d1SDavid du Colombier int secsize; 2003e12c5d1SDavid du Colombier int inodes; 2013e12c5d1SDavid du Colombier int blocksize; 2023e12c5d1SDavid du Colombier 2033e12c5d1SDavid du Colombier secsize = 512; 2043e12c5d1SDavid du Colombier inodes = 1024; 2053e12c5d1SDavid du Colombier blocksize = 4*1024; 2063e12c5d1SDavid du Colombier 2073e12c5d1SDavid du Colombier f = open(partition, ORDWR); 2083e12c5d1SDavid du Colombier if(f < 0) 2093e12c5d1SDavid du Colombier error("opening partition"); 2103e12c5d1SDavid du Colombier 2113e12c5d1SDavid du Colombier if(format || iinit(&ic, f, secsize)<0){ 2123e12c5d1SDavid du Colombier if(iformat(&ic, f, inodes, "bootes", blocksize, secsize) < 0) 2133e12c5d1SDavid du Colombier error("formatting failed"); 2143e12c5d1SDavid du Colombier } 2153e12c5d1SDavid du Colombier } 2163e12c5d1SDavid du Colombier 2173e12c5d1SDavid du Colombier void 2183e12c5d1SDavid du Colombier mountinit(char *server, char *mountpoint) 2193e12c5d1SDavid du Colombier { 2203e12c5d1SDavid du Colombier int p[2]; 2213e12c5d1SDavid du Colombier 2223e12c5d1SDavid du Colombier /* 2233e12c5d1SDavid du Colombier * grab a channel and call up the file server 2243e12c5d1SDavid du Colombier */ 2257dd7cddfSDavid du Colombier s.fd[0] = s.fd[1] = dial(netmkaddr(server, 0, "9fs"), 0, 0, 0); 2263e12c5d1SDavid du Colombier if(s.fd[0] < 0) 2273e12c5d1SDavid du Colombier error("opening data"); 2283e12c5d1SDavid du Colombier 2293e12c5d1SDavid du Colombier /* 2303e12c5d1SDavid du Colombier * mount onto name space 2313e12c5d1SDavid du Colombier */ 2323e12c5d1SDavid du Colombier if(pipe(p) < 0) 2333e12c5d1SDavid du Colombier error("pipe failed"); 2343e12c5d1SDavid du Colombier switch(fork()){ 2353e12c5d1SDavid du Colombier case 0: 236219b2ee8SDavid du Colombier break; 237219b2ee8SDavid du Colombier default: 238219b2ee8SDavid du Colombier if(amount(p[1], mountpoint, MREPL|MCREATE, "") < 0) 2393e12c5d1SDavid du Colombier error("mount failed"); 2403e12c5d1SDavid du Colombier exits(0); 2413e12c5d1SDavid du Colombier case -1: 2423e12c5d1SDavid du Colombier error("fork failed\n"); 2433e12c5d1SDavid du Colombier /*BUG: no wait!*/ 2443e12c5d1SDavid du Colombier } 2453e12c5d1SDavid du Colombier c.fd[0] = c.fd[1] = p[0]; 2463e12c5d1SDavid du Colombier } 2473e12c5d1SDavid du Colombier 2483e12c5d1SDavid du Colombier void 2493e12c5d1SDavid du Colombier io(void) 2503e12c5d1SDavid du Colombier { 2519a747e4fSDavid du Colombier int type; 2523e12c5d1SDavid du Colombier Mfile *mf; 2533e12c5d1SDavid du Colombier loop: 2543e12c5d1SDavid du Colombier rcvmsg(&c, &c.thdr); 2559a747e4fSDavid du Colombier 2569a747e4fSDavid du Colombier type = c.thdr.type; 2579a747e4fSDavid du Colombier 2589a747e4fSDavid du Colombier if(statson){ 2599a747e4fSDavid du Colombier cfsstat.cm[type].n++; 2609a747e4fSDavid du Colombier cfsstat.cm[type].s = nsec(); 2619a747e4fSDavid du Colombier } 2623e12c5d1SDavid du Colombier mf = &mfile[c.thdr.fid]; 2639a747e4fSDavid du Colombier switch(type){ 2643e12c5d1SDavid du Colombier default: 2653e12c5d1SDavid du Colombier error("type"); 2663e12c5d1SDavid du Colombier break; 2679a747e4fSDavid du Colombier case Tversion: 2689a747e4fSDavid du Colombier rversion(); 2693e12c5d1SDavid du Colombier break; 2709a747e4fSDavid du Colombier case Tauth: 2719a747e4fSDavid du Colombier mf = &mfile[c.thdr.afid]; 2729a747e4fSDavid du Colombier rauth(mf); 2733e12c5d1SDavid du Colombier break; 2743e12c5d1SDavid du Colombier case Tflush: 2753e12c5d1SDavid du Colombier rflush(); 2763e12c5d1SDavid du Colombier break; 2773e12c5d1SDavid du Colombier case Tattach: 2783e12c5d1SDavid du Colombier rattach(mf); 2793e12c5d1SDavid du Colombier break; 2803e12c5d1SDavid du Colombier case Twalk: 2813e12c5d1SDavid du Colombier rwalk(mf); 2823e12c5d1SDavid du Colombier break; 2833e12c5d1SDavid du Colombier case Topen: 2843e12c5d1SDavid du Colombier ropen(mf); 2853e12c5d1SDavid du Colombier break; 2863e12c5d1SDavid du Colombier case Tcreate: 2873e12c5d1SDavid du Colombier rcreate(mf); 2883e12c5d1SDavid du Colombier break; 2893e12c5d1SDavid du Colombier case Tread: 2903e12c5d1SDavid du Colombier rread(mf); 2913e12c5d1SDavid du Colombier break; 2923e12c5d1SDavid du Colombier case Twrite: 2933e12c5d1SDavid du Colombier rwrite(mf); 2943e12c5d1SDavid du Colombier break; 2953e12c5d1SDavid du Colombier case Tclunk: 2963e12c5d1SDavid du Colombier rclunk(mf); 2973e12c5d1SDavid du Colombier break; 2983e12c5d1SDavid du Colombier case Tremove: 2993e12c5d1SDavid du Colombier rremove(mf); 3003e12c5d1SDavid du Colombier break; 3013e12c5d1SDavid du Colombier case Tstat: 3023e12c5d1SDavid du Colombier rstat(mf); 3033e12c5d1SDavid du Colombier break; 3043e12c5d1SDavid du Colombier case Twstat: 3053e12c5d1SDavid du Colombier rwstat(mf); 3063e12c5d1SDavid du Colombier break; 3073e12c5d1SDavid du Colombier } 3089a747e4fSDavid du Colombier if(statson){ 3099a747e4fSDavid du Colombier cfsstat.cm[type].t += nsec() -cfsstat.cm[type].s; 3109a747e4fSDavid du Colombier } 3113e12c5d1SDavid du Colombier goto loop; 3123e12c5d1SDavid du Colombier } 3133e12c5d1SDavid du Colombier 3143e12c5d1SDavid du Colombier void 3159a747e4fSDavid du Colombier rversion(void) 316219b2ee8SDavid du Colombier { 3179a747e4fSDavid du Colombier if(messagesize > c.thdr.msize) 3189a747e4fSDavid du Colombier messagesize = c.thdr.msize; 3199a747e4fSDavid du Colombier c.thdr.msize = messagesize; /* set downstream size */ 320219b2ee8SDavid du Colombier delegate(); 321219b2ee8SDavid du Colombier } 322219b2ee8SDavid du Colombier 323219b2ee8SDavid du Colombier void 3249a747e4fSDavid du Colombier rauth(Mfile *mf) 3259a747e4fSDavid du Colombier { 3269a747e4fSDavid du Colombier Mfile *amf; 3279a747e4fSDavid du Colombier 3289a747e4fSDavid du Colombier if(delegate() == 0){ 3299a747e4fSDavid du Colombier if (c.thdr.afid != NOFID){ 3309a747e4fSDavid du Colombier amf = &mfile[c.thdr.afid]; 3319a747e4fSDavid du Colombier if(amf->busy) 3329a747e4fSDavid du Colombier error("rauth afid on used channel"); 3339a747e4fSDavid du Colombier amf->qid = s.rhdr.aqid; 3349a747e4fSDavid du Colombier amf->busy = 1; 3359a747e4fSDavid du Colombier } 3369a747e4fSDavid du Colombier mf->qid = s.rhdr.qid; 3379a747e4fSDavid du Colombier mf->busy = 1; 3389a747e4fSDavid du Colombier } 3399a747e4fSDavid du Colombier } 3409a747e4fSDavid du Colombier 3419a747e4fSDavid du Colombier void 3423e12c5d1SDavid du Colombier rflush(void) /* synchronous so easy */ 3433e12c5d1SDavid du Colombier { 3443e12c5d1SDavid du Colombier sendreply(0); 3453e12c5d1SDavid du Colombier } 3463e12c5d1SDavid du Colombier 3473e12c5d1SDavid du Colombier void 3483e12c5d1SDavid du Colombier rattach(Mfile *mf) 3493e12c5d1SDavid du Colombier { 3503e12c5d1SDavid du Colombier if(delegate() == 0){ 3513e12c5d1SDavid du Colombier mf->qid = s.rhdr.qid; 3523e12c5d1SDavid du Colombier mf->busy = 1; 3539a747e4fSDavid du Colombier if (statson == 1){ 3549a747e4fSDavid du Colombier statson++; 3559a747e4fSDavid du Colombier rootqid = mf->qid; 3563e12c5d1SDavid du Colombier } 3573e12c5d1SDavid du Colombier } 3583e12c5d1SDavid du Colombier } 3593e12c5d1SDavid du Colombier 3603e12c5d1SDavid du Colombier void 3613e12c5d1SDavid du Colombier rwalk(Mfile *mf) 3623e12c5d1SDavid du Colombier { 3639a747e4fSDavid du Colombier Mfile *nmf; 3649a747e4fSDavid du Colombier 3659a747e4fSDavid du Colombier nmf = nil; 3669a747e4fSDavid du Colombier if(statson 3679a747e4fSDavid du Colombier && mf->qid.type == rootqid.type && mf->qid.path == rootqid.path 3689a747e4fSDavid du Colombier && c.thdr.nwname == 1 && strcmp(c.thdr.wname[0], "cfsctl") == 0){ 3699a747e4fSDavid du Colombier /* This is the ctl file */ 3709a747e4fSDavid du Colombier nmf = &mfile[c.thdr.newfid]; 3719a747e4fSDavid du Colombier if(c.thdr.newfid != c.thdr.fid && nmf->busy) 3729a747e4fSDavid du Colombier error("clone to used channel"); 3739a747e4fSDavid du Colombier nmf = &mfile[c.thdr.newfid]; 3749a747e4fSDavid du Colombier nmf->qid = ctlqid; 3759a747e4fSDavid du Colombier nmf->busy = 1; 3769a747e4fSDavid du Colombier c.rhdr.nwqid = 1; 3779a747e4fSDavid du Colombier c.rhdr.wqid[0] = ctlqid; 3789a747e4fSDavid du Colombier sendreply(0); 3793e12c5d1SDavid du Colombier return; 3803e12c5d1SDavid du Colombier } 3819a747e4fSDavid du Colombier if(c.thdr.newfid != c.thdr.fid){ 3829a747e4fSDavid du Colombier if(c.thdr.newfid<0 || Nfid<=c.thdr.newfid) 3839a747e4fSDavid du Colombier error("clone nfid out of range"); 3849a747e4fSDavid du Colombier nmf = &mfile[c.thdr.newfid]; 3859a747e4fSDavid du Colombier if(nmf->busy) 3869a747e4fSDavid du Colombier error("clone to used channel"); 3879a747e4fSDavid du Colombier nmf = &mfile[c.thdr.newfid]; 3889a747e4fSDavid du Colombier nmf->qid = mf->qid; 3899a747e4fSDavid du Colombier nmf->busy = 1; 3909a747e4fSDavid du Colombier mf = nmf; /* Walk mf */ 3913e12c5d1SDavid du Colombier } 3923e12c5d1SDavid du Colombier 3939a747e4fSDavid du Colombier if(delegate() < 0){ /* complete failure */ 3949a747e4fSDavid du Colombier if(nmf) 3959a747e4fSDavid du Colombier nmf->busy = 0; 3969a747e4fSDavid du Colombier return; 3979a747e4fSDavid du Colombier } 3989a747e4fSDavid du Colombier 3999a747e4fSDavid du Colombier if(s.rhdr.nwqid == c.thdr.nwname){ /* complete success */ 4009a747e4fSDavid du Colombier if(s.rhdr.nwqid > 0) 4019a747e4fSDavid du Colombier mf->qid = s.rhdr.wqid[s.rhdr.nwqid-1]; 4029a747e4fSDavid du Colombier return; 4039a747e4fSDavid du Colombier } 4049a747e4fSDavid du Colombier 4059a747e4fSDavid du Colombier /* partial success; release fid */ 4069a747e4fSDavid du Colombier if(nmf) 4079a747e4fSDavid du Colombier nmf->busy = 0; 4083e12c5d1SDavid du Colombier } 4093e12c5d1SDavid du Colombier 4103e12c5d1SDavid du Colombier void 4113e12c5d1SDavid du Colombier ropen(Mfile *mf) 4123e12c5d1SDavid du Colombier { 4139a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 4149a747e4fSDavid du Colombier /* Opening ctl file */ 4159a747e4fSDavid du Colombier if(c.thdr.mode != OREAD){ 4169a747e4fSDavid du Colombier sendreply("does not exist"); 4179a747e4fSDavid du Colombier return; 4189a747e4fSDavid du Colombier } 4199a747e4fSDavid du Colombier c.rhdr.qid = ctlqid; 4209a747e4fSDavid du Colombier c.rhdr.iounit = 0; 4219a747e4fSDavid du Colombier sendreply(0); 4229a747e4fSDavid du Colombier genstats(); 4239a747e4fSDavid du Colombier return; 4249a747e4fSDavid du Colombier } 4253e12c5d1SDavid du Colombier if(delegate() == 0){ 4263e12c5d1SDavid du Colombier mf->qid = s.rhdr.qid; 4277dd7cddfSDavid du Colombier if(c.thdr.mode & OTRUNC) 4283e12c5d1SDavid du Colombier iget(&ic, mf->qid); 4293e12c5d1SDavid du Colombier } 4303e12c5d1SDavid du Colombier } 4313e12c5d1SDavid du Colombier 4323e12c5d1SDavid du Colombier void 4333e12c5d1SDavid du Colombier rcreate(Mfile *mf) 4343e12c5d1SDavid du Colombier { 4359a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 4369a747e4fSDavid du Colombier sendreply("exists"); 4379a747e4fSDavid du Colombier return; 4389a747e4fSDavid du Colombier } 4393e12c5d1SDavid du Colombier if(delegate() == 0){ 4403e12c5d1SDavid du Colombier mf->qid = s.rhdr.qid; 4413e12c5d1SDavid du Colombier mf->qid.vers++; 4423e12c5d1SDavid du Colombier } 4433e12c5d1SDavid du Colombier } 4443e12c5d1SDavid du Colombier 4453e12c5d1SDavid du Colombier void 4463e12c5d1SDavid du Colombier rclunk(Mfile *mf) 4473e12c5d1SDavid du Colombier { 4483e12c5d1SDavid du Colombier if(!mf->busy){ 4493e12c5d1SDavid du Colombier sendreply(0); 4503e12c5d1SDavid du Colombier return; 4513e12c5d1SDavid du Colombier } 4523e12c5d1SDavid du Colombier mf->busy = 0; 453*3ff48bf5SDavid du Colombier delegate(); 4543e12c5d1SDavid du Colombier } 4553e12c5d1SDavid du Colombier 4563e12c5d1SDavid du Colombier void 4573e12c5d1SDavid du Colombier rremove(Mfile *mf) 4583e12c5d1SDavid du Colombier { 4599a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 4609a747e4fSDavid du Colombier sendreply("not removed"); 4619a747e4fSDavid du Colombier return; 4629a747e4fSDavid du Colombier } 4633e12c5d1SDavid du Colombier mf->busy = 0; 4643e12c5d1SDavid du Colombier delegate(); 4653e12c5d1SDavid du Colombier } 4663e12c5d1SDavid du Colombier 4673e12c5d1SDavid du Colombier void 4683e12c5d1SDavid du Colombier rread(Mfile *mf) 4693e12c5d1SDavid du Colombier { 4703e12c5d1SDavid du Colombier int cnt; 4713e12c5d1SDavid du Colombier long off, first; 4723e12c5d1SDavid du Colombier char *cp; 4733e12c5d1SDavid du Colombier Ibuf *b; 4743e12c5d1SDavid du Colombier long n; 4753e12c5d1SDavid du Colombier char data[MAXFDATA]; 4763e12c5d1SDavid du Colombier int done; 4773e12c5d1SDavid du Colombier 4783e12c5d1SDavid du Colombier first = off = c.thdr.offset; 4793e12c5d1SDavid du Colombier cnt = c.thdr.count; 4803e12c5d1SDavid du Colombier 4819a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 4829a747e4fSDavid du Colombier if(cnt > statlen-off) 4839a747e4fSDavid du Colombier c.rhdr.count = statlen-off; 4849a747e4fSDavid du Colombier else 4859a747e4fSDavid du Colombier c.rhdr.count = cnt; 4869a747e4fSDavid du Colombier if(c.rhdr.count < 0){ 4879a747e4fSDavid du Colombier sendreply("eof"); 4889a747e4fSDavid du Colombier return; 4899a747e4fSDavid du Colombier } 4909a747e4fSDavid du Colombier c.rhdr.data = statbuf + off; 4919a747e4fSDavid du Colombier sendreply(0); 4929a747e4fSDavid du Colombier return; 4939a747e4fSDavid du Colombier } 4949a747e4fSDavid du Colombier if(mf->qid.type & (QTDIR|QTAUTH)){ 4953e12c5d1SDavid du Colombier delegate(); 4969a747e4fSDavid du Colombier if (statson) { 4979a747e4fSDavid du Colombier cfsstat.ndirread++; 4989a747e4fSDavid du Colombier if(c.rhdr.count > 0){ 4999a747e4fSDavid du Colombier cfsstat.bytesread += c.rhdr.count; 5009a747e4fSDavid du Colombier cfsstat.bytesfromdirs += c.rhdr.count; 5019a747e4fSDavid du Colombier } 5029a747e4fSDavid du Colombier } 5033e12c5d1SDavid du Colombier return; 5043e12c5d1SDavid du Colombier } 5053e12c5d1SDavid du Colombier 5063e12c5d1SDavid du Colombier b = iget(&ic, mf->qid); 5073e12c5d1SDavid du Colombier if(b == 0){ 5089a747e4fSDavid du Colombier DPRINT(2, "delegating read\n"); 5093e12c5d1SDavid du Colombier delegate(); 5109a747e4fSDavid du Colombier if (statson){ 5119a747e4fSDavid du Colombier cfsstat.ndelegateread++; 5129a747e4fSDavid du Colombier if(c.rhdr.count > 0){ 5139a747e4fSDavid du Colombier cfsstat.bytesread += c.rhdr.count; 5149a747e4fSDavid du Colombier cfsstat.bytesfromserver += c.rhdr.count; 5159a747e4fSDavid du Colombier } 5169a747e4fSDavid du Colombier } 5173e12c5d1SDavid du Colombier return; 5183e12c5d1SDavid du Colombier } 5193e12c5d1SDavid du Colombier 5203e12c5d1SDavid du Colombier cp = data; 5213e12c5d1SDavid du Colombier done = 0; 5223e12c5d1SDavid du Colombier while(cnt>0 && !done){ 5239a747e4fSDavid du Colombier if(off >= b->inode.length){ 5249a747e4fSDavid du Colombier DPRINT(2, "offset %ld greater than length %lld\n", off, b->inode.length); 5259a747e4fSDavid du Colombier break; 5269a747e4fSDavid du Colombier } 5273e12c5d1SDavid du Colombier n = fread(&ic, b, cp, off, cnt); 5283e12c5d1SDavid du Colombier if(n <= 0){ 5293e12c5d1SDavid du Colombier n = -n; 5303e12c5d1SDavid du Colombier if(n==0 || n>cnt) 5313e12c5d1SDavid du Colombier n = cnt; 5329a747e4fSDavid du Colombier DPRINT(2, "fetch %ld bytes of data from server at offset %ld\n", n, off); 5333e12c5d1SDavid du Colombier s.thdr.type = c.thdr.type; 5343e12c5d1SDavid du Colombier s.thdr.fid = c.thdr.fid; 5353e12c5d1SDavid du Colombier s.thdr.tag = c.thdr.tag; 5363e12c5d1SDavid du Colombier s.thdr.offset = off; 5373e12c5d1SDavid du Colombier s.thdr.count = n; 5389a747e4fSDavid du Colombier if(statson){ 5399a747e4fSDavid du Colombier cfsstat.ndelegateread++; 5409a747e4fSDavid du Colombier } 54180ee5cbfSDavid du Colombier if(askserver() < 0){ 5423e12c5d1SDavid du Colombier sendreply(s.rhdr.ename); 54380ee5cbfSDavid du Colombier return; 54480ee5cbfSDavid du Colombier } 5453e12c5d1SDavid du Colombier if(s.rhdr.count != n) 5463e12c5d1SDavid du Colombier done = 1; 5473e12c5d1SDavid du Colombier n = s.rhdr.count; 5489a747e4fSDavid du Colombier if(n == 0){ 5499a747e4fSDavid du Colombier /* end of file */ 5509a747e4fSDavid du Colombier if(b->inode.length > off){ 5519a747e4fSDavid du Colombier DPRINT(2, "file %llud.%ld, length %ld\n", 5529a747e4fSDavid du Colombier b->inode.qid.path, b->inode.qid.vers, off); 5539a747e4fSDavid du Colombier b->inode.length = off; 5549a747e4fSDavid du Colombier } 5559a747e4fSDavid du Colombier break; 5569a747e4fSDavid du Colombier } 5573e12c5d1SDavid du Colombier memmove(cp, s.rhdr.data, n); 5583e12c5d1SDavid du Colombier fwrite(&ic, b, cp, off, n); 5599a747e4fSDavid du Colombier if (statson){ 5609a747e4fSDavid du Colombier cfsstat.bytestocache += n; 5619a747e4fSDavid du Colombier cfsstat.bytesfromserver += n; 5629a747e4fSDavid du Colombier } 5639a747e4fSDavid du Colombier }else{ 5649a747e4fSDavid du Colombier DPRINT(2, "fetched %ld bytes from cache\n", n); 5659a747e4fSDavid du Colombier if(statson){ 5669a747e4fSDavid du Colombier cfsstat.bytesfromcache += n; 5679a747e4fSDavid du Colombier } 5683e12c5d1SDavid du Colombier } 5693e12c5d1SDavid du Colombier cnt -= n; 5703e12c5d1SDavid du Colombier off += n; 5713e12c5d1SDavid du Colombier cp += n; 5723e12c5d1SDavid du Colombier } 5733e12c5d1SDavid du Colombier c.rhdr.data = data; 5743e12c5d1SDavid du Colombier c.rhdr.count = off - first; 5759a747e4fSDavid du Colombier if(statson){ 5769a747e4fSDavid du Colombier cfsstat.bytesread += c.rhdr.count; 5779a747e4fSDavid du Colombier } 5783e12c5d1SDavid du Colombier sendreply(0); 5793e12c5d1SDavid du Colombier } 5803e12c5d1SDavid du Colombier 5813e12c5d1SDavid du Colombier void 5823e12c5d1SDavid du Colombier rwrite(Mfile *mf) 5833e12c5d1SDavid du Colombier { 5843e12c5d1SDavid du Colombier Ibuf *b; 5853e12c5d1SDavid du Colombier char buf[MAXFDATA]; 5863e12c5d1SDavid du Colombier 5879a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 5889a747e4fSDavid du Colombier sendreply("read only"); 5899a747e4fSDavid du Colombier return; 5909a747e4fSDavid du Colombier } 5919a747e4fSDavid du Colombier if(mf->qid.type & (QTDIR|QTAUTH)){ 5923e12c5d1SDavid du Colombier delegate(); 5939a747e4fSDavid du Colombier if(statson && c.rhdr.count > 0) 5949a747e4fSDavid du Colombier cfsstat.byteswritten += c.rhdr.count; 5953e12c5d1SDavid du Colombier return; 5963e12c5d1SDavid du Colombier } 5973e12c5d1SDavid du Colombier 5983e12c5d1SDavid du Colombier memmove(buf, c.thdr.data, c.thdr.count); 5993e12c5d1SDavid du Colombier if(delegate() < 0) 6003e12c5d1SDavid du Colombier return; 6013e12c5d1SDavid du Colombier 6029a747e4fSDavid du Colombier if(s.rhdr.count > 0) 6039a747e4fSDavid du Colombier cfsstat.byteswritten += s.rhdr.count; 6049a747e4fSDavid du Colombier if(mf->qid.type & QTAPPEND) /* don't modify our cache for append-only data; always read from server*/ 6059a747e4fSDavid du Colombier return; 6063e12c5d1SDavid du Colombier b = iget(&ic, mf->qid); 6073e12c5d1SDavid du Colombier if(b == 0) 6083e12c5d1SDavid du Colombier return; 6099a747e4fSDavid du Colombier if (b->inode.length < c.thdr.offset + s.rhdr.count) 6109a747e4fSDavid du Colombier b->inode.length = c.thdr.offset + s.rhdr.count; 6113e12c5d1SDavid du Colombier mf->qid.vers++; 6129a747e4fSDavid du Colombier if (s.rhdr.count != c.thdr.count) 6139a747e4fSDavid du Colombier syslog(0, "cfslog", "rhdr.count %ud, thdr.count %ud\n", 6149a747e4fSDavid du Colombier s.rhdr.count, c.thdr.count); 6159a747e4fSDavid du Colombier if(fwrite(&ic, b, buf, c.thdr.offset, s.rhdr.count) == s.rhdr.count){ 6163e12c5d1SDavid du Colombier iinc(&ic, b); 6179a747e4fSDavid du Colombier if(statson) 6189a747e4fSDavid du Colombier cfsstat.bytestocache += s.rhdr.count; 6199a747e4fSDavid du Colombier } 6203e12c5d1SDavid du Colombier } 6213e12c5d1SDavid du Colombier 6223e12c5d1SDavid du Colombier void 6233e12c5d1SDavid du Colombier rstat(Mfile *mf) 6243e12c5d1SDavid du Colombier { 6259a747e4fSDavid du Colombier Dir d; 6269a747e4fSDavid du Colombier 6279a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 6289a747e4fSDavid du Colombier genstats(); 6299a747e4fSDavid du Colombier d.qid = ctlqid; 6309a747e4fSDavid du Colombier d.mode = 0444; 6319a747e4fSDavid du Colombier d.length = statlen; /* would be nice to do better */ 6329a747e4fSDavid du Colombier d.name = "cfsctl"; 6339a747e4fSDavid du Colombier d.uid = "none"; 6349a747e4fSDavid du Colombier d.gid = "none"; 6359a747e4fSDavid du Colombier d.muid = "none"; 6369a747e4fSDavid du Colombier d.atime = time(nil); 6379a747e4fSDavid du Colombier d.mtime = d.atime; 6389a747e4fSDavid du Colombier c.rhdr.nstat = convD2M(&d, c.rhdr.stat, sizeof(c.rhdr) - (c.rhdr.stat - (uchar*)&c.rhdr)); 6399a747e4fSDavid du Colombier sendreply(0); 6409a747e4fSDavid du Colombier return; 6419a747e4fSDavid du Colombier } 6429a747e4fSDavid du Colombier if(delegate() == 0){ 6439a747e4fSDavid du Colombier Ibuf *b; 6449a747e4fSDavid du Colombier 6459a747e4fSDavid du Colombier convM2D(s.rhdr.stat, s.rhdr.nstat , &d, nil); 6469a747e4fSDavid du Colombier mf->qid = d.qid; 6479a747e4fSDavid du Colombier b = iget(&ic, mf->qid); 6489a747e4fSDavid du Colombier if(b) 6499a747e4fSDavid du Colombier b->inode.length = d.length; 6509a747e4fSDavid du Colombier } 6513e12c5d1SDavid du Colombier } 6523e12c5d1SDavid du Colombier 6533e12c5d1SDavid du Colombier void 6543e12c5d1SDavid du Colombier rwstat(Mfile *mf) 6553e12c5d1SDavid du Colombier { 6569a747e4fSDavid du Colombier Ibuf *b; 6579a747e4fSDavid du Colombier 6589a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 6599a747e4fSDavid du Colombier sendreply("read only"); 6609a747e4fSDavid du Colombier return; 6619a747e4fSDavid du Colombier } 6623e12c5d1SDavid du Colombier delegate(); 6639a747e4fSDavid du Colombier if(b = iget(&ic, mf->qid)) 6649a747e4fSDavid du Colombier b->inode.length = MAXLEN; 6653e12c5d1SDavid du Colombier } 6663e12c5d1SDavid du Colombier 6673e12c5d1SDavid du Colombier void 6689a747e4fSDavid du Colombier error(char *fmt, ...) { 6699a747e4fSDavid du Colombier va_list arg; 6709a747e4fSDavid du Colombier static char buf[2048]; 6719a747e4fSDavid du Colombier 6729a747e4fSDavid du Colombier va_start(arg, fmt); 6739a747e4fSDavid du Colombier vseprint(buf, buf+sizeof(buf), fmt, arg); 6749a747e4fSDavid du Colombier va_end(arg); 6759a747e4fSDavid du Colombier fprint(2, "%s: %s\n", argv0, buf); 6769a747e4fSDavid du Colombier exits("error"); 6773e12c5d1SDavid du Colombier } 6783e12c5d1SDavid du Colombier 6793e12c5d1SDavid du Colombier void 6803e12c5d1SDavid du Colombier warning(char *s) 6813e12c5d1SDavid du Colombier { 6827dd7cddfSDavid du Colombier fprint(2, "cfs: %s: %r\n", s); 6833e12c5d1SDavid du Colombier } 6843e12c5d1SDavid du Colombier 6853e12c5d1SDavid du Colombier /* 6863e12c5d1SDavid du Colombier * send a reply to the client 6873e12c5d1SDavid du Colombier */ 6883e12c5d1SDavid du Colombier void 6893e12c5d1SDavid du Colombier sendreply(char *err) 6903e12c5d1SDavid du Colombier { 6913e12c5d1SDavid du Colombier 6923e12c5d1SDavid du Colombier if(err){ 6933e12c5d1SDavid du Colombier c.rhdr.type = Rerror; 6949a747e4fSDavid du Colombier c.rhdr.ename = err; 6953e12c5d1SDavid du Colombier }else{ 6963e12c5d1SDavid du Colombier c.rhdr.type = c.thdr.type+1; 6973e12c5d1SDavid du Colombier c.rhdr.fid = c.thdr.fid; 6983e12c5d1SDavid du Colombier } 6993e12c5d1SDavid du Colombier c.rhdr.tag = c.thdr.tag; 7003e12c5d1SDavid du Colombier sendmsg(&c, &c.rhdr); 7013e12c5d1SDavid du Colombier } 7023e12c5d1SDavid du Colombier 7033e12c5d1SDavid du Colombier /* 7043e12c5d1SDavid du Colombier * send a request to the server, get the reply, and send that to 7053e12c5d1SDavid du Colombier * the client 7063e12c5d1SDavid du Colombier */ 7073e12c5d1SDavid du Colombier int 7083e12c5d1SDavid du Colombier delegate(void) 7093e12c5d1SDavid du Colombier { 7109a747e4fSDavid du Colombier int type; 7119a747e4fSDavid du Colombier 7129a747e4fSDavid du Colombier type = c.thdr.type; 7139a747e4fSDavid du Colombier if(statson){ 7149a747e4fSDavid du Colombier cfsstat.sm[type].n++; 7159a747e4fSDavid du Colombier cfsstat.sm[type].s = nsec(); 7169a747e4fSDavid du Colombier } 7179a747e4fSDavid du Colombier 7183e12c5d1SDavid du Colombier sendmsg(&s, &c.thdr); 7193e12c5d1SDavid du Colombier rcvmsg(&s, &s.rhdr); 7209a747e4fSDavid du Colombier 7219a747e4fSDavid du Colombier if(statson){ 7229a747e4fSDavid du Colombier cfsstat.sm[type].t += nsec() - cfsstat.sm[type].s; 7239a747e4fSDavid du Colombier } 7249a747e4fSDavid du Colombier 7253e12c5d1SDavid du Colombier sendmsg(&c, &s.rhdr); 7263e12c5d1SDavid du Colombier return c.thdr.type+1 == s.rhdr.type ? 0 : -1; 7273e12c5d1SDavid du Colombier } 7283e12c5d1SDavid du Colombier 7293e12c5d1SDavid du Colombier /* 7303e12c5d1SDavid du Colombier * send a request to the server and get a reply 7313e12c5d1SDavid du Colombier */ 7323e12c5d1SDavid du Colombier int 7333e12c5d1SDavid du Colombier askserver(void) 7343e12c5d1SDavid du Colombier { 7359a747e4fSDavid du Colombier int type; 7369a747e4fSDavid du Colombier 7373e12c5d1SDavid du Colombier s.thdr.tag = c.thdr.tag; 7389a747e4fSDavid du Colombier 7399a747e4fSDavid du Colombier type = s.thdr.type; 7409a747e4fSDavid du Colombier if(statson){ 7419a747e4fSDavid du Colombier cfsstat.sm[type].n++; 7429a747e4fSDavid du Colombier cfsstat.sm[type].s = nsec(); 7439a747e4fSDavid du Colombier } 7449a747e4fSDavid du Colombier 7453e12c5d1SDavid du Colombier sendmsg(&s, &s.thdr); 7463e12c5d1SDavid du Colombier rcvmsg(&s, &s.rhdr); 7479a747e4fSDavid du Colombier 7489a747e4fSDavid du Colombier if(statson){ 7499a747e4fSDavid du Colombier cfsstat.sm[type].t += nsec() - cfsstat.sm[type].s; 7509a747e4fSDavid du Colombier } 7519a747e4fSDavid du Colombier 7523e12c5d1SDavid du Colombier return s.thdr.type+1 == s.rhdr.type ? 0 : -1; 7533e12c5d1SDavid du Colombier } 7543e12c5d1SDavid du Colombier 7553e12c5d1SDavid du Colombier /* 7563e12c5d1SDavid du Colombier * send/receive messages with logging 7573e12c5d1SDavid du Colombier */ 7583e12c5d1SDavid du Colombier void 7593e12c5d1SDavid du Colombier sendmsg(P9fs *p, Fcall *f) 7603e12c5d1SDavid du Colombier { 7617dd7cddfSDavid du Colombier DPRINT(2, "->%s: %F\n", p->name, f); 7623e12c5d1SDavid du Colombier 7639a747e4fSDavid du Colombier p->len = convS2M(f, datasnd, messagesize); 7649a747e4fSDavid du Colombier if(p->len <= 0) 7659a747e4fSDavid du Colombier error("convS2M"); 7669a747e4fSDavid du Colombier if(write(p->fd[1], datasnd, p->len)!=p->len) 7679a747e4fSDavid du Colombier error("sendmsg"); 7683e12c5d1SDavid du Colombier } 7693e12c5d1SDavid du Colombier 7703e12c5d1SDavid du Colombier void 7713e12c5d1SDavid du Colombier dump(uchar *p, int len) 7723e12c5d1SDavid du Colombier { 7733e12c5d1SDavid du Colombier fprint(2, "%d bytes", len); 7743e12c5d1SDavid du Colombier while(len > 0){ 7753e12c5d1SDavid du Colombier fprint(2, " %.2ux", *p++); 7763e12c5d1SDavid du Colombier len--; 7773e12c5d1SDavid du Colombier } 7783e12c5d1SDavid du Colombier fprint(2, "\n"); 7793e12c5d1SDavid du Colombier } 7803e12c5d1SDavid du Colombier 7813e12c5d1SDavid du Colombier void 7823e12c5d1SDavid du Colombier rcvmsg(P9fs *p, Fcall *f) 7833e12c5d1SDavid du Colombier { 7849a747e4fSDavid du Colombier int olen, rlen; 7857dd7cddfSDavid du Colombier char buf[128]; 7863e12c5d1SDavid du Colombier 7873e12c5d1SDavid du Colombier olen = p->len; 7889a747e4fSDavid du Colombier p->len = read9pmsg(p->fd[0], datarcv, sizeof(datarcv)); 7897dd7cddfSDavid du Colombier if(p->len <= 0){ 7909a747e4fSDavid du Colombier sprint(buf, "read9pmsg(%d)->%ld: %r", p->fd[0], p->len); 7917dd7cddfSDavid du Colombier error(buf); 7927dd7cddfSDavid du Colombier } 7939a747e4fSDavid du Colombier 7949a747e4fSDavid du Colombier if((rlen = convM2S(datarcv, p->len, f)) != p->len) 7959a747e4fSDavid du Colombier error("rcvmsg format error, expected length %d, got %d", rlen, p->len); 7969a747e4fSDavid du Colombier if(f->fid<0 || Nfid<=f->fid){ 7973e12c5d1SDavid du Colombier fprint(2, "<-%s: %d %s on %d\n", p->name, f->type, 7983e12c5d1SDavid du Colombier mname[f->type]? mname[f->type] : "mystery", 7993e12c5d1SDavid du Colombier f->fid); 8003e12c5d1SDavid du Colombier dump((uchar*)datasnd, olen); 8013e12c5d1SDavid du Colombier dump((uchar*)datarcv, p->len); 8023e12c5d1SDavid du Colombier error("rcvmsg fid out of range"); 8033e12c5d1SDavid du Colombier } 8047dd7cddfSDavid du Colombier DPRINT(2, "<-%s: %F\n", p->name, f); 8053e12c5d1SDavid du Colombier } 8069a747e4fSDavid du Colombier 8079a747e4fSDavid du Colombier int 8089a747e4fSDavid du Colombier ctltest(Mfile *mf) 8099a747e4fSDavid du Colombier { 8109a747e4fSDavid du Colombier return mf->busy && mf->qid.type == ctlqid.type && mf->qid.path == ctlqid.path; 8119a747e4fSDavid du Colombier } 8129a747e4fSDavid du Colombier 8139a747e4fSDavid du Colombier void 8149a747e4fSDavid du Colombier genstats(void) 8159a747e4fSDavid du Colombier { 8169a747e4fSDavid du Colombier int i; 8179a747e4fSDavid du Colombier char *p; 8189a747e4fSDavid du Colombier 8199a747e4fSDavid du Colombier p = statbuf; 8209a747e4fSDavid du Colombier 8219a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, " Client Server\n"); 8229a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, " #calls Δ ms/call Δ #calls Δ ms/call Δ\n"); 8239a747e4fSDavid du Colombier for (i = 0; i < nelem(cfsstat.cm); i++) 8249a747e4fSDavid du Colombier if(cfsstat.cm[i].n || cfsstat.sm[i].n) { 8259a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ", 8269a747e4fSDavid du Colombier cfsstat.cm[i].n, cfsstat.cm[i].n - cfsprev.cm[i].n); 8279a747e4fSDavid du Colombier if (cfsstat.cm[i].n) 8289a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7.3f ", 8299a747e4fSDavid du Colombier 0.000001*cfsstat.cm[i].t/cfsstat.cm[i].n); 8309a747e4fSDavid du Colombier else 8319a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, " "); 8329a747e4fSDavid du Colombier if(cfsstat.cm[i].n - cfsprev.cm[i].n) 8339a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7.3f ", 8349a747e4fSDavid du Colombier 0.000001*(cfsstat.cm[i].t - cfsprev.cm[i].t)/(cfsstat.cm[i].n - cfsprev.cm[i].n)); 8359a747e4fSDavid du Colombier else 8369a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, " "); 8379a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ", 8389a747e4fSDavid du Colombier cfsstat.sm[i].n, cfsstat.sm[i].n - cfsprev.sm[i].n); 8399a747e4fSDavid du Colombier if (cfsstat.sm[i].n) 8409a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7.3f ", 8419a747e4fSDavid du Colombier 0.000001*cfsstat.sm[i].t/cfsstat.sm[i].n); 8429a747e4fSDavid du Colombier else 8439a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, " "); 8449a747e4fSDavid du Colombier if(cfsstat.sm[i].n - cfsprev.sm[i].n) 8459a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7.3f ", 8469a747e4fSDavid du Colombier 0.000001*(cfsstat.sm[i].t - cfsprev.sm[i].t)/(cfsstat.sm[i].n - cfsprev.sm[i].n)); 8479a747e4fSDavid du Colombier else 8489a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, " "); 8499a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%s\n", mname[i]); 8509a747e4fSDavid du Colombier } 8519a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ndirread\n", 8529a747e4fSDavid du Colombier cfsstat.ndirread, cfsstat.ndirread - cfsprev.ndirread); 8539a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ndelegateread\n", 8549a747e4fSDavid du Colombier cfsstat.ndelegateread, cfsstat.ndelegateread - cfsprev.ndelegateread); 8559a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ninsert\n", 8569a747e4fSDavid du Colombier cfsstat.ninsert, cfsstat.ninsert - cfsprev.ninsert); 8579a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud ndelete\n", 8589a747e4fSDavid du Colombier cfsstat.ndelete, cfsstat.ndelete - cfsprev.ndelete); 8599a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud nupdate\n", 8609a747e4fSDavid du Colombier cfsstat.nupdate, cfsstat.nupdate - cfsprev.nupdate); 8619a747e4fSDavid du Colombier 8629a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud bytesread\n", 8639a747e4fSDavid du Colombier cfsstat.bytesread, cfsstat.bytesread - cfsprev.bytesread); 8649a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud byteswritten\n", 8659a747e4fSDavid du Colombier cfsstat.byteswritten, cfsstat.byteswritten - cfsprev.byteswritten); 8669a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud bytesfromserver\n", 8679a747e4fSDavid du Colombier cfsstat.bytesfromserver, cfsstat.bytesfromserver - cfsprev.bytesfromserver); 8689a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud bytesfromdirs\n", 8699a747e4fSDavid du Colombier cfsstat.bytesfromdirs, cfsstat.bytesfromdirs - cfsprev.bytesfromdirs); 8709a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud bytesfromcache\n", 8719a747e4fSDavid du Colombier cfsstat.bytesfromcache, cfsstat.bytesfromcache - cfsprev.bytesfromcache); 8729a747e4fSDavid du Colombier p += snprint(p, sizeof(statbuf)+statbuf-p, "%7lud %7lud bytestocache\n", 8739a747e4fSDavid du Colombier cfsstat.bytestocache, cfsstat.bytestocache - cfsprev.bytestocache); 8749a747e4fSDavid du Colombier statlen = p - statbuf; 8759a747e4fSDavid du Colombier cfsprev = cfsstat; 8769a747e4fSDavid du Colombier } 877