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); 84*7c70c028SDavid 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 1203e12c5d1SDavid du Colombier usage(void) 1213e12c5d1SDavid du Colombier { 122*7c70c028SDavid du Colombier fprint(2, "usage:\tcfs -s [-krd] [-f partition]\n"); 123*7c70c028SDavid du Colombier fprint(2, "\tcfs [-krd] [-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 136*7c70c028SDavid du Colombier int chkid; 137*7c70c028SDavid du Colombier NetConnInfo * snci; 138*7c70c028SDavid du Colombier 1393e12c5d1SDavid du Colombier std = 0; 1403e12c5d1SDavid du Colombier format = 0; 141*7c70c028SDavid du Colombier chkid = 1; 1427dd7cddfSDavid du Colombier part = "/dev/sdC0/cache"; 143*7c70c028SDavid du Colombier server = "tcp!fs"; 1443e12c5d1SDavid du Colombier mtpt = "/tmp"; 1453e12c5d1SDavid du Colombier 1463e12c5d1SDavid du Colombier ARGBEGIN{ 1473e12c5d1SDavid du Colombier case 'a': 14807b9f4d0SDavid du Colombier server = EARGF(usage()); 1493e12c5d1SDavid du Colombier break; 1509a747e4fSDavid du Colombier case 'S': 1519a747e4fSDavid du Colombier statson = 1; 1529a747e4fSDavid du Colombier break; 1533e12c5d1SDavid du Colombier case 's': 1543e12c5d1SDavid du Colombier std = 1; 1553e12c5d1SDavid du Colombier break; 1563e12c5d1SDavid du Colombier case 'r': 1573e12c5d1SDavid du Colombier format = 1; 1583e12c5d1SDavid du Colombier break; 1593e12c5d1SDavid du Colombier case 'f': 16007b9f4d0SDavid du Colombier part = EARGF(usage()); 1613e12c5d1SDavid du Colombier break; 1623e12c5d1SDavid du Colombier case 'd': 1633e12c5d1SDavid du Colombier debug = 1; 1643e12c5d1SDavid du Colombier break; 165*7c70c028SDavid du Colombier case 'k': 166*7c70c028SDavid du Colombier chkid = 0; 167*7c70c028SDavid du Colombier break; 1683e12c5d1SDavid du Colombier default: 1693e12c5d1SDavid du Colombier usage(); 1703e12c5d1SDavid du Colombier }ARGEND 1713e12c5d1SDavid du Colombier if(argc && *argv) 1723e12c5d1SDavid du Colombier mtpt = *argv; 1733e12c5d1SDavid du Colombier 1747dd7cddfSDavid du Colombier if(debug) 1759a747e4fSDavid du Colombier fmtinstall('F', fcallfmt); 1767dd7cddfSDavid du Colombier 1773e12c5d1SDavid du Colombier c.name = "client"; 1783e12c5d1SDavid du Colombier s.name = "server"; 1793e12c5d1SDavid du Colombier if(std){ 1803e12c5d1SDavid du Colombier c.fd[0] = c.fd[1] = 1; 1813e12c5d1SDavid du Colombier s.fd[0] = s.fd[1] = 0; 1823e12c5d1SDavid du Colombier }else 1833e12c5d1SDavid du Colombier mountinit(server, mtpt); 1843e12c5d1SDavid du Colombier 185*7c70c028SDavid du Colombier if(chkid){ 186*7c70c028SDavid du Colombier if((snci = getnetconninfo(nil, s.fd[0])) == nil) 187*7c70c028SDavid du Colombier /* Failed to lookup information; format */ 188*7c70c028SDavid du Colombier cachesetup(1, nil, part); 189*7c70c028SDavid du Colombier else 190*7c70c028SDavid du Colombier /* Do partition check */ 191*7c70c028SDavid du Colombier cachesetup(0, snci->raddr, part); 192*7c70c028SDavid du Colombier }else 193*7c70c028SDavid du Colombier /* Obey -f w/o regard to cache vs. remote server */ 194*7c70c028SDavid du Colombier cachesetup(format, nil, part); 195*7c70c028SDavid du Colombier 1963e12c5d1SDavid du Colombier switch(fork()){ 1973e12c5d1SDavid du Colombier case 0: 1983e12c5d1SDavid du Colombier io(); 1993e12c5d1SDavid du Colombier exits(""); 2003e12c5d1SDavid du Colombier case -1: 2013e12c5d1SDavid du Colombier error("fork"); 2023e12c5d1SDavid du Colombier default: 2033e12c5d1SDavid du Colombier exits(""); 2043e12c5d1SDavid du Colombier } 2053e12c5d1SDavid du Colombier } 2063e12c5d1SDavid du Colombier 2073e12c5d1SDavid du Colombier void 208*7c70c028SDavid du Colombier cachesetup(int format, char *name, char *partition) 2093e12c5d1SDavid du Colombier { 2103e12c5d1SDavid du Colombier int f; 2113e12c5d1SDavid du Colombier int secsize; 2123e12c5d1SDavid du Colombier int inodes; 2133e12c5d1SDavid du Colombier int blocksize; 2143e12c5d1SDavid du Colombier 2153e12c5d1SDavid du Colombier secsize = 512; 2163e12c5d1SDavid du Colombier inodes = 1024; 2173e12c5d1SDavid du Colombier blocksize = 4*1024; 2183e12c5d1SDavid du Colombier 2193e12c5d1SDavid du Colombier f = open(partition, ORDWR); 2203e12c5d1SDavid du Colombier if(f < 0) 2213e12c5d1SDavid du Colombier error("opening partition"); 2223e12c5d1SDavid du Colombier 223*7c70c028SDavid du Colombier if(format || iinit(&ic, f, secsize, name) < 0){ 224*7c70c028SDavid du Colombier /* 225*7c70c028SDavid du Colombier * If we need to format and don't have a name, fall 226*7c70c028SDavid du Colombier * back to our old behavior of using "bootes" 227*7c70c028SDavid du Colombier */ 228*7c70c028SDavid du Colombier name = (name == nil? "bootes": name); 229*7c70c028SDavid du Colombier if(iformat(&ic, f, inodes, name, blocksize, secsize) < 0) 2303e12c5d1SDavid du Colombier error("formatting failed"); 2313e12c5d1SDavid du Colombier } 2323e12c5d1SDavid du Colombier } 2333e12c5d1SDavid du Colombier 2343e12c5d1SDavid du Colombier void 2353e12c5d1SDavid du Colombier mountinit(char *server, char *mountpoint) 2363e12c5d1SDavid du Colombier { 2373e12c5d1SDavid du Colombier int p[2]; 2383e12c5d1SDavid du Colombier 2393e12c5d1SDavid du Colombier /* 2403e12c5d1SDavid du Colombier * grab a channel and call up the file server 2413e12c5d1SDavid du Colombier */ 2427dd7cddfSDavid du Colombier s.fd[0] = s.fd[1] = dial(netmkaddr(server, 0, "9fs"), 0, 0, 0); 2433e12c5d1SDavid du Colombier if(s.fd[0] < 0) 2443e12c5d1SDavid du Colombier error("opening data"); 2453e12c5d1SDavid du Colombier 2463e12c5d1SDavid du Colombier /* 2473e12c5d1SDavid du Colombier * mount onto name space 2483e12c5d1SDavid du Colombier */ 2493e12c5d1SDavid du Colombier if(pipe(p) < 0) 2503e12c5d1SDavid du Colombier error("pipe failed"); 2513e12c5d1SDavid du Colombier switch(fork()){ 2523e12c5d1SDavid du Colombier case 0: 253219b2ee8SDavid du Colombier break; 254219b2ee8SDavid du Colombier default: 255219b2ee8SDavid du Colombier if(amount(p[1], mountpoint, MREPL|MCREATE, "") < 0) 2563e12c5d1SDavid du Colombier error("mount failed"); 2573e12c5d1SDavid du Colombier exits(0); 2583e12c5d1SDavid du Colombier case -1: 2593e12c5d1SDavid du Colombier error("fork failed\n"); 2603e12c5d1SDavid du Colombier /*BUG: no wait!*/ 2613e12c5d1SDavid du Colombier } 2623e12c5d1SDavid du Colombier c.fd[0] = c.fd[1] = p[0]; 2633e12c5d1SDavid du Colombier } 2643e12c5d1SDavid du Colombier 2653e12c5d1SDavid du Colombier void 2663e12c5d1SDavid du Colombier io(void) 2673e12c5d1SDavid du Colombier { 2689a747e4fSDavid du Colombier int type; 2693e12c5d1SDavid du Colombier Mfile *mf; 2703e12c5d1SDavid du Colombier loop: 2713e12c5d1SDavid du Colombier rcvmsg(&c, &c.thdr); 2729a747e4fSDavid du Colombier 2739a747e4fSDavid du Colombier type = c.thdr.type; 2749a747e4fSDavid du Colombier 2759a747e4fSDavid du Colombier if(statson){ 2769a747e4fSDavid du Colombier cfsstat.cm[type].n++; 2779a747e4fSDavid du Colombier cfsstat.cm[type].s = nsec(); 2789a747e4fSDavid du Colombier } 2793e12c5d1SDavid du Colombier mf = &mfile[c.thdr.fid]; 2809a747e4fSDavid du Colombier switch(type){ 2813e12c5d1SDavid du Colombier default: 2823e12c5d1SDavid du Colombier error("type"); 2833e12c5d1SDavid du Colombier break; 2849a747e4fSDavid du Colombier case Tversion: 2859a747e4fSDavid du Colombier rversion(); 2863e12c5d1SDavid du Colombier break; 2879a747e4fSDavid du Colombier case Tauth: 2889a747e4fSDavid du Colombier mf = &mfile[c.thdr.afid]; 2899a747e4fSDavid du Colombier rauth(mf); 2903e12c5d1SDavid du Colombier break; 2913e12c5d1SDavid du Colombier case Tflush: 2923e12c5d1SDavid du Colombier rflush(); 2933e12c5d1SDavid du Colombier break; 2943e12c5d1SDavid du Colombier case Tattach: 2953e12c5d1SDavid du Colombier rattach(mf); 2963e12c5d1SDavid du Colombier break; 2973e12c5d1SDavid du Colombier case Twalk: 2983e12c5d1SDavid du Colombier rwalk(mf); 2993e12c5d1SDavid du Colombier break; 3003e12c5d1SDavid du Colombier case Topen: 3013e12c5d1SDavid du Colombier ropen(mf); 3023e12c5d1SDavid du Colombier break; 3033e12c5d1SDavid du Colombier case Tcreate: 3043e12c5d1SDavid du Colombier rcreate(mf); 3053e12c5d1SDavid du Colombier break; 3063e12c5d1SDavid du Colombier case Tread: 3073e12c5d1SDavid du Colombier rread(mf); 3083e12c5d1SDavid du Colombier break; 3093e12c5d1SDavid du Colombier case Twrite: 3103e12c5d1SDavid du Colombier rwrite(mf); 3113e12c5d1SDavid du Colombier break; 3123e12c5d1SDavid du Colombier case Tclunk: 3133e12c5d1SDavid du Colombier rclunk(mf); 3143e12c5d1SDavid du Colombier break; 3153e12c5d1SDavid du Colombier case Tremove: 3163e12c5d1SDavid du Colombier rremove(mf); 3173e12c5d1SDavid du Colombier break; 3183e12c5d1SDavid du Colombier case Tstat: 3193e12c5d1SDavid du Colombier rstat(mf); 3203e12c5d1SDavid du Colombier break; 3213e12c5d1SDavid du Colombier case Twstat: 3223e12c5d1SDavid du Colombier rwstat(mf); 3233e12c5d1SDavid du Colombier break; 3243e12c5d1SDavid du Colombier } 3259a747e4fSDavid du Colombier if(statson){ 3269a747e4fSDavid du Colombier cfsstat.cm[type].t += nsec() -cfsstat.cm[type].s; 3279a747e4fSDavid du Colombier } 3283e12c5d1SDavid du Colombier goto loop; 3293e12c5d1SDavid du Colombier } 3303e12c5d1SDavid du Colombier 3313e12c5d1SDavid du Colombier void 3329a747e4fSDavid du Colombier rversion(void) 333219b2ee8SDavid du Colombier { 3349a747e4fSDavid du Colombier if(messagesize > c.thdr.msize) 3359a747e4fSDavid du Colombier messagesize = c.thdr.msize; 3369a747e4fSDavid du Colombier c.thdr.msize = messagesize; /* set downstream size */ 337219b2ee8SDavid du Colombier delegate(); 338219b2ee8SDavid du Colombier } 339219b2ee8SDavid du Colombier 340219b2ee8SDavid du Colombier void 3419a747e4fSDavid du Colombier rauth(Mfile *mf) 3429a747e4fSDavid du Colombier { 3436b6b9ac8SDavid du Colombier if(mf->busy) 3446b6b9ac8SDavid du Colombier error("auth to used channel"); 3459a747e4fSDavid du Colombier 3469a747e4fSDavid du Colombier if(delegate() == 0){ 3476b6b9ac8SDavid du Colombier mf->qid = s.rhdr.aqid; 3489a747e4fSDavid du Colombier mf->busy = 1; 3499a747e4fSDavid du Colombier } 3509a747e4fSDavid du Colombier } 3519a747e4fSDavid du Colombier 3529a747e4fSDavid du Colombier void 3533e12c5d1SDavid du Colombier rflush(void) /* synchronous so easy */ 3543e12c5d1SDavid du Colombier { 3553e12c5d1SDavid du Colombier sendreply(0); 3563e12c5d1SDavid du Colombier } 3573e12c5d1SDavid du Colombier 3583e12c5d1SDavid du Colombier void 3593e12c5d1SDavid du Colombier rattach(Mfile *mf) 3603e12c5d1SDavid du Colombier { 3613e12c5d1SDavid du Colombier if(delegate() == 0){ 3623e12c5d1SDavid du Colombier mf->qid = s.rhdr.qid; 3633e12c5d1SDavid du Colombier mf->busy = 1; 3649a747e4fSDavid du Colombier if (statson == 1){ 3659a747e4fSDavid du Colombier statson++; 3669a747e4fSDavid du Colombier rootqid = mf->qid; 3673e12c5d1SDavid du Colombier } 3683e12c5d1SDavid du Colombier } 3693e12c5d1SDavid du Colombier } 3703e12c5d1SDavid du Colombier 3713e12c5d1SDavid du Colombier void 3723e12c5d1SDavid du Colombier rwalk(Mfile *mf) 3733e12c5d1SDavid du Colombier { 3749a747e4fSDavid du Colombier Mfile *nmf; 3759a747e4fSDavid du Colombier 3769a747e4fSDavid du Colombier nmf = nil; 3779a747e4fSDavid du Colombier if(statson 3789a747e4fSDavid du Colombier && mf->qid.type == rootqid.type && mf->qid.path == rootqid.path 3799a747e4fSDavid du Colombier && c.thdr.nwname == 1 && strcmp(c.thdr.wname[0], "cfsctl") == 0){ 3809a747e4fSDavid du Colombier /* This is the ctl file */ 3819a747e4fSDavid du Colombier nmf = &mfile[c.thdr.newfid]; 3829a747e4fSDavid du Colombier if(c.thdr.newfid != c.thdr.fid && nmf->busy) 3839a747e4fSDavid du Colombier error("clone to used channel"); 3849a747e4fSDavid du Colombier nmf = &mfile[c.thdr.newfid]; 3859a747e4fSDavid du Colombier nmf->qid = ctlqid; 3869a747e4fSDavid du Colombier nmf->busy = 1; 3879a747e4fSDavid du Colombier c.rhdr.nwqid = 1; 3889a747e4fSDavid du Colombier c.rhdr.wqid[0] = ctlqid; 3899a747e4fSDavid du Colombier sendreply(0); 3903e12c5d1SDavid du Colombier return; 3913e12c5d1SDavid du Colombier } 3929a747e4fSDavid du Colombier if(c.thdr.newfid != c.thdr.fid){ 39322a127bbSDavid du Colombier if(c.thdr.newfid >= Nfid) 3949a747e4fSDavid du Colombier error("clone nfid out of range"); 3959a747e4fSDavid du Colombier nmf = &mfile[c.thdr.newfid]; 3969a747e4fSDavid du Colombier if(nmf->busy) 3979a747e4fSDavid du Colombier error("clone to used channel"); 3989a747e4fSDavid du Colombier nmf = &mfile[c.thdr.newfid]; 3999a747e4fSDavid du Colombier nmf->qid = mf->qid; 4009a747e4fSDavid du Colombier nmf->busy = 1; 4019a747e4fSDavid du Colombier mf = nmf; /* Walk mf */ 4023e12c5d1SDavid du Colombier } 4033e12c5d1SDavid du Colombier 4049a747e4fSDavid du Colombier if(delegate() < 0){ /* complete failure */ 4059a747e4fSDavid du Colombier if(nmf) 4069a747e4fSDavid du Colombier nmf->busy = 0; 4079a747e4fSDavid du Colombier return; 4089a747e4fSDavid du Colombier } 4099a747e4fSDavid du Colombier 4109a747e4fSDavid du Colombier if(s.rhdr.nwqid == c.thdr.nwname){ /* complete success */ 4119a747e4fSDavid du Colombier if(s.rhdr.nwqid > 0) 4129a747e4fSDavid du Colombier mf->qid = s.rhdr.wqid[s.rhdr.nwqid-1]; 4139a747e4fSDavid du Colombier return; 4149a747e4fSDavid du Colombier } 4159a747e4fSDavid du Colombier 4169a747e4fSDavid du Colombier /* partial success; release fid */ 4179a747e4fSDavid du Colombier if(nmf) 4189a747e4fSDavid du Colombier nmf->busy = 0; 4193e12c5d1SDavid du Colombier } 4203e12c5d1SDavid du Colombier 4213e12c5d1SDavid du Colombier void 4223e12c5d1SDavid du Colombier ropen(Mfile *mf) 4233e12c5d1SDavid du Colombier { 4249a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 4259a747e4fSDavid du Colombier /* Opening ctl file */ 4269a747e4fSDavid du Colombier if(c.thdr.mode != OREAD){ 4279a747e4fSDavid du Colombier sendreply("does not exist"); 4289a747e4fSDavid du Colombier return; 4299a747e4fSDavid du Colombier } 4309a747e4fSDavid du Colombier c.rhdr.qid = ctlqid; 4319a747e4fSDavid du Colombier c.rhdr.iounit = 0; 4329a747e4fSDavid du Colombier sendreply(0); 4339a747e4fSDavid du Colombier genstats(); 4349a747e4fSDavid du Colombier return; 4359a747e4fSDavid du Colombier } 4363e12c5d1SDavid du Colombier if(delegate() == 0){ 4373e12c5d1SDavid du Colombier mf->qid = s.rhdr.qid; 4387dd7cddfSDavid du Colombier if(c.thdr.mode & OTRUNC) 4393e12c5d1SDavid du Colombier iget(&ic, mf->qid); 4403e12c5d1SDavid du Colombier } 4413e12c5d1SDavid du Colombier } 4423e12c5d1SDavid du Colombier 4433e12c5d1SDavid du Colombier void 4443e12c5d1SDavid du Colombier rcreate(Mfile *mf) 4453e12c5d1SDavid du Colombier { 4469a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 4479a747e4fSDavid du Colombier sendreply("exists"); 4489a747e4fSDavid du Colombier return; 4499a747e4fSDavid du Colombier } 4503e12c5d1SDavid du Colombier if(delegate() == 0){ 4513e12c5d1SDavid du Colombier mf->qid = s.rhdr.qid; 4523e12c5d1SDavid du Colombier mf->qid.vers++; 4533e12c5d1SDavid du Colombier } 4543e12c5d1SDavid du Colombier } 4553e12c5d1SDavid du Colombier 4563e12c5d1SDavid du Colombier void 4573e12c5d1SDavid du Colombier rclunk(Mfile *mf) 4583e12c5d1SDavid du Colombier { 4593e12c5d1SDavid du Colombier if(!mf->busy){ 4603e12c5d1SDavid du Colombier sendreply(0); 4613e12c5d1SDavid du Colombier return; 4623e12c5d1SDavid du Colombier } 4633e12c5d1SDavid du Colombier mf->busy = 0; 4643ff48bf5SDavid du Colombier delegate(); 4653e12c5d1SDavid du Colombier } 4663e12c5d1SDavid du Colombier 4673e12c5d1SDavid du Colombier void 4683e12c5d1SDavid du Colombier rremove(Mfile *mf) 4693e12c5d1SDavid du Colombier { 4709a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 4719a747e4fSDavid du Colombier sendreply("not removed"); 4729a747e4fSDavid du Colombier return; 4739a747e4fSDavid du Colombier } 4743e12c5d1SDavid du Colombier mf->busy = 0; 4753e12c5d1SDavid du Colombier delegate(); 4763e12c5d1SDavid du Colombier } 4773e12c5d1SDavid du Colombier 4783e12c5d1SDavid du Colombier void 4793e12c5d1SDavid du Colombier rread(Mfile *mf) 4803e12c5d1SDavid du Colombier { 48141fb754aSDavid du Colombier int cnt, done; 4823e12c5d1SDavid du Colombier long n; 48341fb754aSDavid du Colombier vlong off, first; 48441fb754aSDavid du Colombier char *cp; 4853e12c5d1SDavid du Colombier char data[MAXFDATA]; 48641fb754aSDavid du Colombier Ibuf *b; 4873e12c5d1SDavid du Colombier 48841fb754aSDavid du Colombier off = c.thdr.offset; 48941fb754aSDavid du Colombier first = off; 4903e12c5d1SDavid du Colombier cnt = c.thdr.count; 4913e12c5d1SDavid du Colombier 4929a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 4939a747e4fSDavid du Colombier if(cnt > statlen-off) 4949a747e4fSDavid du Colombier c.rhdr.count = statlen-off; 4959a747e4fSDavid du Colombier else 4969a747e4fSDavid du Colombier c.rhdr.count = cnt; 49722a127bbSDavid du Colombier if((int)c.rhdr.count < 0){ 4989a747e4fSDavid du Colombier sendreply("eof"); 4999a747e4fSDavid du Colombier return; 5009a747e4fSDavid du Colombier } 5019a747e4fSDavid du Colombier c.rhdr.data = statbuf + off; 5029a747e4fSDavid du Colombier sendreply(0); 5039a747e4fSDavid du Colombier return; 5049a747e4fSDavid du Colombier } 5059a747e4fSDavid du Colombier if(mf->qid.type & (QTDIR|QTAUTH)){ 5063e12c5d1SDavid du Colombier delegate(); 5079a747e4fSDavid du Colombier if (statson) { 5089a747e4fSDavid du Colombier cfsstat.ndirread++; 5099a747e4fSDavid du Colombier if(c.rhdr.count > 0){ 5109a747e4fSDavid du Colombier cfsstat.bytesread += c.rhdr.count; 5119a747e4fSDavid du Colombier cfsstat.bytesfromdirs += c.rhdr.count; 5129a747e4fSDavid du Colombier } 5139a747e4fSDavid du Colombier } 5143e12c5d1SDavid du Colombier return; 5153e12c5d1SDavid du Colombier } 5163e12c5d1SDavid du Colombier 5173e12c5d1SDavid du Colombier b = iget(&ic, mf->qid); 5183e12c5d1SDavid du Colombier if(b == 0){ 5199a747e4fSDavid du Colombier DPRINT(2, "delegating read\n"); 5203e12c5d1SDavid du Colombier delegate(); 5219a747e4fSDavid du Colombier if (statson){ 5229a747e4fSDavid du Colombier cfsstat.ndelegateread++; 5239a747e4fSDavid du Colombier if(c.rhdr.count > 0){ 5249a747e4fSDavid du Colombier cfsstat.bytesread += c.rhdr.count; 5259a747e4fSDavid du Colombier cfsstat.bytesfromserver += c.rhdr.count; 5269a747e4fSDavid du Colombier } 5279a747e4fSDavid du Colombier } 5283e12c5d1SDavid du Colombier return; 5293e12c5d1SDavid du Colombier } 5303e12c5d1SDavid du Colombier 5313e12c5d1SDavid du Colombier cp = data; 5323e12c5d1SDavid du Colombier done = 0; 5333e12c5d1SDavid du Colombier while(cnt>0 && !done){ 5349a747e4fSDavid du Colombier if(off >= b->inode.length){ 53541fb754aSDavid du Colombier DPRINT(2, "offset %lld greater than length %lld\n", 53641fb754aSDavid du Colombier off, b->inode.length); 5379a747e4fSDavid du Colombier break; 5389a747e4fSDavid du Colombier } 5393e12c5d1SDavid du Colombier n = fread(&ic, b, cp, off, cnt); 5403e12c5d1SDavid du Colombier if(n <= 0){ 5413e12c5d1SDavid du Colombier n = -n; 5423e12c5d1SDavid du Colombier if(n==0 || n>cnt) 5433e12c5d1SDavid du Colombier n = cnt; 54441fb754aSDavid du Colombier DPRINT(2, 54541fb754aSDavid du Colombier "fetch %ld bytes of data from server at offset %lld\n", 54641fb754aSDavid du Colombier n, off); 5473e12c5d1SDavid du Colombier s.thdr.type = c.thdr.type; 5483e12c5d1SDavid du Colombier s.thdr.fid = c.thdr.fid; 5493e12c5d1SDavid du Colombier s.thdr.tag = c.thdr.tag; 5503e12c5d1SDavid du Colombier s.thdr.offset = off; 5513e12c5d1SDavid du Colombier s.thdr.count = n; 55241fb754aSDavid du Colombier if(statson) 5539a747e4fSDavid du Colombier cfsstat.ndelegateread++; 55480ee5cbfSDavid du Colombier if(askserver() < 0){ 5553e12c5d1SDavid du Colombier sendreply(s.rhdr.ename); 55680ee5cbfSDavid du Colombier return; 55780ee5cbfSDavid du Colombier } 5583e12c5d1SDavid du Colombier if(s.rhdr.count != n) 5593e12c5d1SDavid du Colombier done = 1; 5603e12c5d1SDavid du Colombier n = s.rhdr.count; 5619a747e4fSDavid du Colombier if(n == 0){ 5629a747e4fSDavid du Colombier /* end of file */ 5639a747e4fSDavid du Colombier if(b->inode.length > off){ 56441fb754aSDavid du Colombier DPRINT(2, "file %llud.%ld, length %lld\n", 56541fb754aSDavid du Colombier b->inode.qid.path, 56641fb754aSDavid du Colombier b->inode.qid.vers, off); 5679a747e4fSDavid du Colombier b->inode.length = off; 5689a747e4fSDavid du Colombier } 5699a747e4fSDavid du Colombier break; 5709a747e4fSDavid du Colombier } 5713e12c5d1SDavid du Colombier memmove(cp, s.rhdr.data, n); 5723e12c5d1SDavid du Colombier fwrite(&ic, b, cp, off, n); 5739a747e4fSDavid du Colombier if (statson){ 5749a747e4fSDavid du Colombier cfsstat.bytestocache += n; 5759a747e4fSDavid du Colombier cfsstat.bytesfromserver += n; 5769a747e4fSDavid du Colombier } 5779a747e4fSDavid du Colombier }else{ 5789a747e4fSDavid du Colombier DPRINT(2, "fetched %ld bytes from cache\n", n); 57941fb754aSDavid du Colombier if(statson) 5809a747e4fSDavid du Colombier cfsstat.bytesfromcache += n; 5819a747e4fSDavid du Colombier } 5823e12c5d1SDavid du Colombier cnt -= n; 5833e12c5d1SDavid du Colombier off += n; 5843e12c5d1SDavid du Colombier cp += n; 5853e12c5d1SDavid du Colombier } 5863e12c5d1SDavid du Colombier c.rhdr.data = data; 5873e12c5d1SDavid du Colombier c.rhdr.count = off - first; 58841fb754aSDavid du Colombier if(statson) 5899a747e4fSDavid du Colombier cfsstat.bytesread += c.rhdr.count; 5903e12c5d1SDavid du Colombier sendreply(0); 5913e12c5d1SDavid du Colombier } 5923e12c5d1SDavid du Colombier 5933e12c5d1SDavid du Colombier void 5943e12c5d1SDavid du Colombier rwrite(Mfile *mf) 5953e12c5d1SDavid du Colombier { 5963e12c5d1SDavid du Colombier Ibuf *b; 5973e12c5d1SDavid du Colombier char buf[MAXFDATA]; 5983e12c5d1SDavid du Colombier 5999a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 6009a747e4fSDavid du Colombier sendreply("read only"); 6019a747e4fSDavid du Colombier return; 6029a747e4fSDavid du Colombier } 6039a747e4fSDavid du Colombier if(mf->qid.type & (QTDIR|QTAUTH)){ 6043e12c5d1SDavid du Colombier delegate(); 6059a747e4fSDavid du Colombier if(statson && c.rhdr.count > 0) 6069a747e4fSDavid du Colombier cfsstat.byteswritten += c.rhdr.count; 6073e12c5d1SDavid du Colombier return; 6083e12c5d1SDavid du Colombier } 6093e12c5d1SDavid du Colombier 6103e12c5d1SDavid du Colombier memmove(buf, c.thdr.data, c.thdr.count); 6113e12c5d1SDavid du Colombier if(delegate() < 0) 6123e12c5d1SDavid du Colombier return; 6133e12c5d1SDavid du Colombier 6149a747e4fSDavid du Colombier if(s.rhdr.count > 0) 6159a747e4fSDavid du Colombier cfsstat.byteswritten += s.rhdr.count; 61641fb754aSDavid du Colombier /* don't modify our cache for append-only data; always read from server*/ 61741fb754aSDavid du Colombier if(mf->qid.type & QTAPPEND) 6189a747e4fSDavid du Colombier return; 6193e12c5d1SDavid du Colombier b = iget(&ic, mf->qid); 6203e12c5d1SDavid du Colombier if(b == 0) 6213e12c5d1SDavid du Colombier return; 6229a747e4fSDavid du Colombier if (b->inode.length < c.thdr.offset + s.rhdr.count) 6239a747e4fSDavid du Colombier b->inode.length = c.thdr.offset + s.rhdr.count; 6243e12c5d1SDavid du Colombier mf->qid.vers++; 6259a747e4fSDavid du Colombier if (s.rhdr.count != c.thdr.count) 6269a747e4fSDavid du Colombier syslog(0, "cfslog", "rhdr.count %ud, thdr.count %ud\n", 6279a747e4fSDavid du Colombier s.rhdr.count, c.thdr.count); 6289a747e4fSDavid du Colombier if(fwrite(&ic, b, buf, c.thdr.offset, s.rhdr.count) == s.rhdr.count){ 6293e12c5d1SDavid du Colombier iinc(&ic, b); 6309a747e4fSDavid du Colombier if(statson) 6319a747e4fSDavid du Colombier cfsstat.bytestocache += s.rhdr.count; 6329a747e4fSDavid du Colombier } 6333e12c5d1SDavid du Colombier } 6343e12c5d1SDavid du Colombier 6353e12c5d1SDavid du Colombier void 6363e12c5d1SDavid du Colombier rstat(Mfile *mf) 6373e12c5d1SDavid du Colombier { 6389a747e4fSDavid du Colombier Dir d; 6399a747e4fSDavid du Colombier 6409a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 6419a747e4fSDavid du Colombier genstats(); 6429a747e4fSDavid du Colombier d.qid = ctlqid; 6439a747e4fSDavid du Colombier d.mode = 0444; 6449a747e4fSDavid du Colombier d.length = statlen; /* would be nice to do better */ 6459a747e4fSDavid du Colombier d.name = "cfsctl"; 6469a747e4fSDavid du Colombier d.uid = "none"; 6479a747e4fSDavid du Colombier d.gid = "none"; 6489a747e4fSDavid du Colombier d.muid = "none"; 6499a747e4fSDavid du Colombier d.atime = time(nil); 6509a747e4fSDavid du Colombier d.mtime = d.atime; 65141fb754aSDavid du Colombier c.rhdr.nstat = convD2M(&d, c.rhdr.stat, 65241fb754aSDavid du Colombier sizeof c.rhdr - (c.rhdr.stat - (uchar*)&c.rhdr)); 6539a747e4fSDavid du Colombier sendreply(0); 6549a747e4fSDavid du Colombier return; 6559a747e4fSDavid du Colombier } 6569a747e4fSDavid du Colombier if(delegate() == 0){ 6579a747e4fSDavid du Colombier Ibuf *b; 6589a747e4fSDavid du Colombier 6599a747e4fSDavid du Colombier convM2D(s.rhdr.stat, s.rhdr.nstat , &d, nil); 6609a747e4fSDavid du Colombier mf->qid = d.qid; 6619a747e4fSDavid du Colombier b = iget(&ic, mf->qid); 6629a747e4fSDavid du Colombier if(b) 6639a747e4fSDavid du Colombier b->inode.length = d.length; 6649a747e4fSDavid du Colombier } 6653e12c5d1SDavid du Colombier } 6663e12c5d1SDavid du Colombier 6673e12c5d1SDavid du Colombier void 6683e12c5d1SDavid du Colombier rwstat(Mfile *mf) 6693e12c5d1SDavid du Colombier { 6709a747e4fSDavid du Colombier Ibuf *b; 6719a747e4fSDavid du Colombier 6729a747e4fSDavid du Colombier if(statson && ctltest(mf)){ 6739a747e4fSDavid du Colombier sendreply("read only"); 6749a747e4fSDavid du Colombier return; 6759a747e4fSDavid du Colombier } 6763e12c5d1SDavid du Colombier delegate(); 6779a747e4fSDavid du Colombier if(b = iget(&ic, mf->qid)) 6789a747e4fSDavid du Colombier b->inode.length = MAXLEN; 6793e12c5d1SDavid du Colombier } 6803e12c5d1SDavid du Colombier 6813e12c5d1SDavid du Colombier void 68241fb754aSDavid du Colombier error(char *fmt, ...) 68341fb754aSDavid du Colombier { 6849a747e4fSDavid du Colombier va_list arg; 6859a747e4fSDavid du Colombier static char buf[2048]; 6869a747e4fSDavid du Colombier 6879a747e4fSDavid du Colombier va_start(arg, fmt); 6889a747e4fSDavid du Colombier vseprint(buf, buf+sizeof(buf), fmt, arg); 6899a747e4fSDavid du Colombier va_end(arg); 6909a747e4fSDavid du Colombier fprint(2, "%s: %s\n", argv0, buf); 6919a747e4fSDavid du Colombier exits("error"); 6923e12c5d1SDavid du Colombier } 6933e12c5d1SDavid du Colombier 6943e12c5d1SDavid du Colombier void 6953e12c5d1SDavid du Colombier warning(char *s) 6963e12c5d1SDavid du Colombier { 6977dd7cddfSDavid du Colombier fprint(2, "cfs: %s: %r\n", s); 6983e12c5d1SDavid du Colombier } 6993e12c5d1SDavid du Colombier 7003e12c5d1SDavid du Colombier /* 7013e12c5d1SDavid du Colombier * send a reply to the client 7023e12c5d1SDavid du Colombier */ 7033e12c5d1SDavid du Colombier void 7043e12c5d1SDavid du Colombier sendreply(char *err) 7053e12c5d1SDavid du Colombier { 7063e12c5d1SDavid du Colombier 7073e12c5d1SDavid du Colombier if(err){ 7083e12c5d1SDavid du Colombier c.rhdr.type = Rerror; 7099a747e4fSDavid du Colombier c.rhdr.ename = err; 7103e12c5d1SDavid du Colombier }else{ 7113e12c5d1SDavid du Colombier c.rhdr.type = c.thdr.type+1; 7123e12c5d1SDavid du Colombier c.rhdr.fid = c.thdr.fid; 7133e12c5d1SDavid du Colombier } 7143e12c5d1SDavid du Colombier c.rhdr.tag = c.thdr.tag; 7153e12c5d1SDavid du Colombier sendmsg(&c, &c.rhdr); 7163e12c5d1SDavid du Colombier } 7173e12c5d1SDavid du Colombier 7183e12c5d1SDavid du Colombier /* 7193e12c5d1SDavid du Colombier * send a request to the server, get the reply, and send that to 7203e12c5d1SDavid du Colombier * the client 7213e12c5d1SDavid du Colombier */ 7223e12c5d1SDavid du Colombier int 7233e12c5d1SDavid du Colombier delegate(void) 7243e12c5d1SDavid du Colombier { 7259a747e4fSDavid du Colombier int type; 7269a747e4fSDavid du Colombier 7279a747e4fSDavid du Colombier type = c.thdr.type; 7289a747e4fSDavid du Colombier if(statson){ 7299a747e4fSDavid du Colombier cfsstat.sm[type].n++; 7309a747e4fSDavid du Colombier cfsstat.sm[type].s = nsec(); 7319a747e4fSDavid du Colombier } 7329a747e4fSDavid du Colombier 7333e12c5d1SDavid du Colombier sendmsg(&s, &c.thdr); 7343e12c5d1SDavid du Colombier rcvmsg(&s, &s.rhdr); 7359a747e4fSDavid du Colombier 73641fb754aSDavid du Colombier if(statson) 7379a747e4fSDavid du Colombier cfsstat.sm[type].t += nsec() - cfsstat.sm[type].s; 7389a747e4fSDavid du Colombier 7393e12c5d1SDavid du Colombier sendmsg(&c, &s.rhdr); 7403e12c5d1SDavid du Colombier return c.thdr.type+1 == s.rhdr.type ? 0 : -1; 7413e12c5d1SDavid du Colombier } 7423e12c5d1SDavid du Colombier 7433e12c5d1SDavid du Colombier /* 7443e12c5d1SDavid du Colombier * send a request to the server and get a reply 7453e12c5d1SDavid du Colombier */ 7463e12c5d1SDavid du Colombier int 7473e12c5d1SDavid du Colombier askserver(void) 7483e12c5d1SDavid du Colombier { 7499a747e4fSDavid du Colombier int type; 7509a747e4fSDavid du Colombier 7513e12c5d1SDavid du Colombier s.thdr.tag = c.thdr.tag; 7529a747e4fSDavid du Colombier 7539a747e4fSDavid du Colombier type = s.thdr.type; 7549a747e4fSDavid du Colombier if(statson){ 7559a747e4fSDavid du Colombier cfsstat.sm[type].n++; 7569a747e4fSDavid du Colombier cfsstat.sm[type].s = nsec(); 7579a747e4fSDavid du Colombier } 7589a747e4fSDavid du Colombier 7593e12c5d1SDavid du Colombier sendmsg(&s, &s.thdr); 7603e12c5d1SDavid du Colombier rcvmsg(&s, &s.rhdr); 7619a747e4fSDavid du Colombier 76241fb754aSDavid du Colombier if(statson) 7639a747e4fSDavid du Colombier cfsstat.sm[type].t += nsec() - cfsstat.sm[type].s; 7649a747e4fSDavid du Colombier 7653e12c5d1SDavid du Colombier return s.thdr.type+1 == s.rhdr.type ? 0 : -1; 7663e12c5d1SDavid du Colombier } 7673e12c5d1SDavid du Colombier 7683e12c5d1SDavid du Colombier /* 7693e12c5d1SDavid du Colombier * send/receive messages with logging 7703e12c5d1SDavid du Colombier */ 7713e12c5d1SDavid du Colombier void 7723e12c5d1SDavid du Colombier sendmsg(P9fs *p, Fcall *f) 7733e12c5d1SDavid du Colombier { 7747dd7cddfSDavid du Colombier DPRINT(2, "->%s: %F\n", p->name, f); 7753e12c5d1SDavid du Colombier 7769a747e4fSDavid du Colombier p->len = convS2M(f, datasnd, messagesize); 7779a747e4fSDavid du Colombier if(p->len <= 0) 7789a747e4fSDavid du Colombier error("convS2M"); 7799a747e4fSDavid du Colombier if(write(p->fd[1], datasnd, p->len)!=p->len) 7809a747e4fSDavid du Colombier error("sendmsg"); 7813e12c5d1SDavid du Colombier } 7823e12c5d1SDavid du Colombier 7833e12c5d1SDavid du Colombier void 7843e12c5d1SDavid du Colombier dump(uchar *p, int len) 7853e12c5d1SDavid du Colombier { 7863e12c5d1SDavid du Colombier fprint(2, "%d bytes", len); 78741fb754aSDavid du Colombier while(len-- > 0) 7883e12c5d1SDavid du Colombier fprint(2, " %.2ux", *p++); 7893e12c5d1SDavid du Colombier fprint(2, "\n"); 7903e12c5d1SDavid du Colombier } 7913e12c5d1SDavid du Colombier 7923e12c5d1SDavid du Colombier void 7933e12c5d1SDavid du Colombier rcvmsg(P9fs *p, Fcall *f) 7943e12c5d1SDavid du Colombier { 7959a747e4fSDavid du Colombier int olen, rlen; 7967dd7cddfSDavid du Colombier char buf[128]; 7973e12c5d1SDavid du Colombier 7983e12c5d1SDavid du Colombier olen = p->len; 7999a747e4fSDavid du Colombier p->len = read9pmsg(p->fd[0], datarcv, sizeof(datarcv)); 8007dd7cddfSDavid du Colombier if(p->len <= 0){ 80141fb754aSDavid du Colombier snprint(buf, sizeof buf, "read9pmsg(%d)->%ld: %r", 80241fb754aSDavid du Colombier p->fd[0], p->len); 8037dd7cddfSDavid du Colombier error(buf); 8047dd7cddfSDavid du Colombier } 8059a747e4fSDavid du Colombier 8069a747e4fSDavid du Colombier if((rlen = convM2S(datarcv, p->len, f)) != p->len) 80741fb754aSDavid du Colombier error("rcvmsg format error, expected length %d, got %d", 80841fb754aSDavid du Colombier rlen, p->len); 80922a127bbSDavid du Colombier if(f->fid >= Nfid){ 8103e12c5d1SDavid du Colombier fprint(2, "<-%s: %d %s on %d\n", p->name, f->type, 81141fb754aSDavid du Colombier mname[f->type]? mname[f->type]: "mystery", f->fid); 8123e12c5d1SDavid du Colombier dump((uchar*)datasnd, olen); 8133e12c5d1SDavid du Colombier dump((uchar*)datarcv, p->len); 8143e12c5d1SDavid du Colombier error("rcvmsg fid out of range"); 8153e12c5d1SDavid du Colombier } 8167dd7cddfSDavid du Colombier DPRINT(2, "<-%s: %F\n", p->name, f); 8173e12c5d1SDavid du Colombier } 8189a747e4fSDavid du Colombier 8199a747e4fSDavid du Colombier int 8209a747e4fSDavid du Colombier ctltest(Mfile *mf) 8219a747e4fSDavid du Colombier { 82241fb754aSDavid du Colombier return mf->busy && mf->qid.type == ctlqid.type && 82341fb754aSDavid du Colombier mf->qid.path == ctlqid.path; 8249a747e4fSDavid du Colombier } 8259a747e4fSDavid du Colombier 8269a747e4fSDavid du Colombier void 8279a747e4fSDavid du Colombier genstats(void) 8289a747e4fSDavid du Colombier { 8299a747e4fSDavid du Colombier int i; 8309a747e4fSDavid du Colombier char *p; 8319a747e4fSDavid du Colombier 8329a747e4fSDavid du Colombier p = statbuf; 8339a747e4fSDavid du Colombier 83441fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 83541fb754aSDavid du Colombier " Client Server\n"); 83641fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 83741fb754aSDavid du Colombier " #calls Δ ms/call Δ #calls Δ ms/call Δ\n"); 8389a747e4fSDavid du Colombier for (i = 0; i < nelem(cfsstat.cm); i++) 8399a747e4fSDavid du Colombier if(cfsstat.cm[i].n || cfsstat.sm[i].n) { 84041fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 84141fb754aSDavid du Colombier "%7lud %7lud ", cfsstat.cm[i].n, 84241fb754aSDavid du Colombier cfsstat.cm[i].n - cfsprev.cm[i].n); 8439a747e4fSDavid du Colombier if (cfsstat.cm[i].n) 84441fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 84541fb754aSDavid du Colombier "%7.3f ", 0.000001*cfsstat.cm[i].t/ 84641fb754aSDavid du Colombier cfsstat.cm[i].n); 8479a747e4fSDavid du Colombier else 84841fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 84941fb754aSDavid du Colombier " "); 8509a747e4fSDavid du Colombier if(cfsstat.cm[i].n - cfsprev.cm[i].n) 85141fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 85241fb754aSDavid du Colombier "%7.3f ", 0.000001* 85341fb754aSDavid du Colombier (cfsstat.cm[i].t - cfsprev.cm[i].t)/ 85441fb754aSDavid du Colombier (cfsstat.cm[i].n - cfsprev.cm[i].n)); 8559a747e4fSDavid du Colombier else 85641fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 85741fb754aSDavid du Colombier " "); 85841fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 85941fb754aSDavid du Colombier "%7lud %7lud ", cfsstat.sm[i].n, 86041fb754aSDavid du Colombier cfsstat.sm[i].n - cfsprev.sm[i].n); 8619a747e4fSDavid du Colombier if (cfsstat.sm[i].n) 86241fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 86341fb754aSDavid du Colombier "%7.3f ", 0.000001*cfsstat.sm[i].t/ 86441fb754aSDavid du Colombier cfsstat.sm[i].n); 8659a747e4fSDavid du Colombier else 86641fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 86741fb754aSDavid du Colombier " "); 8689a747e4fSDavid du Colombier if(cfsstat.sm[i].n - cfsprev.sm[i].n) 86941fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 87041fb754aSDavid du Colombier "%7.3f ", 0.000001* 87141fb754aSDavid du Colombier (cfsstat.sm[i].t - cfsprev.sm[i].t)/ 87241fb754aSDavid du Colombier (cfsstat.sm[i].n - cfsprev.sm[i].n)); 8739a747e4fSDavid du Colombier else 87441fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, 87541fb754aSDavid du Colombier " "); 87641fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%s\n", 87741fb754aSDavid du Colombier mname[i]); 8789a747e4fSDavid du Colombier } 87941fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7lud %7lud ndirread\n", 8809a747e4fSDavid du Colombier cfsstat.ndirread, cfsstat.ndirread - cfsprev.ndirread); 88141fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7lud %7lud ndelegateread\n", 88241fb754aSDavid du Colombier cfsstat.ndelegateread, cfsstat.ndelegateread - 88341fb754aSDavid du Colombier cfsprev.ndelegateread); 88441fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7lud %7lud ninsert\n", 8859a747e4fSDavid du Colombier cfsstat.ninsert, cfsstat.ninsert - cfsprev.ninsert); 88641fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7lud %7lud ndelete\n", 8879a747e4fSDavid du Colombier cfsstat.ndelete, cfsstat.ndelete - cfsprev.ndelete); 88841fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7lud %7lud nupdate\n", 8899a747e4fSDavid du Colombier cfsstat.nupdate, cfsstat.nupdate - cfsprev.nupdate); 8909a747e4fSDavid du Colombier 89141fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud bytesread\n", 8929a747e4fSDavid du Colombier cfsstat.bytesread, cfsstat.bytesread - cfsprev.bytesread); 89341fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud byteswritten\n", 89441fb754aSDavid du Colombier cfsstat.byteswritten, cfsstat.byteswritten - 89541fb754aSDavid du Colombier cfsprev.byteswritten); 89641fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud bytesfromserver\n", 89741fb754aSDavid du Colombier cfsstat.bytesfromserver, cfsstat.bytesfromserver - 89841fb754aSDavid du Colombier cfsprev.bytesfromserver); 89941fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud bytesfromdirs\n", 90041fb754aSDavid du Colombier cfsstat.bytesfromdirs, cfsstat.bytesfromdirs - 90141fb754aSDavid du Colombier cfsprev.bytesfromdirs); 90241fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud bytesfromcache\n", 90341fb754aSDavid du Colombier cfsstat.bytesfromcache, cfsstat.bytesfromcache - 90441fb754aSDavid du Colombier cfsprev.bytesfromcache); 90541fb754aSDavid du Colombier p += snprint(p, sizeof statbuf+statbuf-p, "%7llud %7llud bytestocache\n", 90641fb754aSDavid du Colombier cfsstat.bytestocache, cfsstat.bytestocache - 90741fb754aSDavid du Colombier cfsprev.bytestocache); 9089a747e4fSDavid du Colombier statlen = p - statbuf; 9099a747e4fSDavid du Colombier cfsprev = cfsstat; 9109a747e4fSDavid du Colombier } 911