1*906943f9SDavid du Colombier #include <u.h> 2*906943f9SDavid du Colombier #include <libc.h> 3*906943f9SDavid du Colombier #include <thread.h> 4*906943f9SDavid du Colombier #include <fcall.h> 5*906943f9SDavid du Colombier #include "usb.h" 6*906943f9SDavid du Colombier #include "usbfs.h" 7*906943f9SDavid du Colombier 8*906943f9SDavid du Colombier typedef struct Rpc Rpc; 9*906943f9SDavid du Colombier 10*906943f9SDavid du Colombier enum 11*906943f9SDavid du Colombier { 12*906943f9SDavid du Colombier Incr = 3, /* increments for fs array */ 13*906943f9SDavid du Colombier Dtop = 0, /* high 32 bits for / */ 14*906943f9SDavid du Colombier Qdir = 0, /* low 32 bits for /devdir */ 15*906943f9SDavid du Colombier }; 16*906943f9SDavid du Colombier 17*906943f9SDavid du Colombier QLock fslck; 18*906943f9SDavid du Colombier static Usbfs** fs; 19*906943f9SDavid du Colombier static int nfs; 20*906943f9SDavid du Colombier static int fsused; 21*906943f9SDavid du Colombier static int exitonclose = 1; 22*906943f9SDavid du Colombier 23*906943f9SDavid du Colombier void 24*906943f9SDavid du Colombier usbfsexits(int y) 25*906943f9SDavid du Colombier { 26*906943f9SDavid du Colombier exitonclose = y; 27*906943f9SDavid du Colombier } 28*906943f9SDavid du Colombier 29*906943f9SDavid du Colombier static int 30*906943f9SDavid du Colombier qiddev(uvlong path) 31*906943f9SDavid du Colombier { 32*906943f9SDavid du Colombier return (int)(path>>32) & 0xFF; 33*906943f9SDavid du Colombier } 34*906943f9SDavid du Colombier 35*906943f9SDavid du Colombier static int 36*906943f9SDavid du Colombier qidfile(uvlong path) 37*906943f9SDavid du Colombier { 38*906943f9SDavid du Colombier return (int)(path & 0xFFFFFFFFULL); 39*906943f9SDavid du Colombier } 40*906943f9SDavid du Colombier 41*906943f9SDavid du Colombier static uvlong 42*906943f9SDavid du Colombier mkqid(int qd, int qf) 43*906943f9SDavid du Colombier { 44*906943f9SDavid du Colombier return ((uvlong)qd << 32) | (uvlong)qf; 45*906943f9SDavid du Colombier } 46*906943f9SDavid du Colombier 47*906943f9SDavid du Colombier void 48*906943f9SDavid du Colombier usbfsdirdump(void) 49*906943f9SDavid du Colombier { 50*906943f9SDavid du Colombier int i; 51*906943f9SDavid du Colombier 52*906943f9SDavid du Colombier qlock(&fslck); 53*906943f9SDavid du Colombier fprint(2, "%s: fs list: (%d used %d total)\n", argv0, fsused, nfs); 54*906943f9SDavid du Colombier for(i = 1; i < nfs; i++) 55*906943f9SDavid du Colombier if(fs[i] != nil) 56*906943f9SDavid du Colombier if(fs[i]->dev != nil) 57*906943f9SDavid du Colombier fprint(2, "%s\t%s dev %#p refs %ld\n", 58*906943f9SDavid du Colombier argv0, fs[i]->name, fs[i]->dev, fs[i]->dev->ref); 59*906943f9SDavid du Colombier else 60*906943f9SDavid du Colombier fprint(2, "%s:\t%s\n", argv0, fs[i]->name); 61*906943f9SDavid du Colombier qunlock(&fslck); 62*906943f9SDavid du Colombier } 63*906943f9SDavid du Colombier 64*906943f9SDavid du Colombier void 65*906943f9SDavid du Colombier usbfsadd(Usbfs *dfs) 66*906943f9SDavid du Colombier { 67*906943f9SDavid du Colombier int i, j; 68*906943f9SDavid du Colombier 69*906943f9SDavid du Colombier dprint(2, "%s: fsadd %s\n", argv0, dfs->name); 70*906943f9SDavid du Colombier qlock(&fslck); 71*906943f9SDavid du Colombier for(i = 1; i < nfs; i++) 72*906943f9SDavid du Colombier if(fs[i] == nil) 73*906943f9SDavid du Colombier break; 74*906943f9SDavid du Colombier if(i >= nfs){ 75*906943f9SDavid du Colombier if((nfs%Incr) == 0){ 76*906943f9SDavid du Colombier fs = realloc(fs, sizeof(Usbfs*) * (nfs+Incr)); 77*906943f9SDavid du Colombier if(fs == nil) 78*906943f9SDavid du Colombier sysfatal("realloc: %r"); 79*906943f9SDavid du Colombier for(j = nfs; j < nfs+Incr; j++) 80*906943f9SDavid du Colombier fs[j] = nil; 81*906943f9SDavid du Colombier } 82*906943f9SDavid du Colombier if(nfs == 0) /* do not use entry 0 */ 83*906943f9SDavid du Colombier nfs++; 84*906943f9SDavid du Colombier fs[nfs++] = dfs; 85*906943f9SDavid du Colombier }else 86*906943f9SDavid du Colombier fs[i] = dfs; 87*906943f9SDavid du Colombier dfs->qid = mkqid(i, 0); 88*906943f9SDavid du Colombier fsused++; 89*906943f9SDavid du Colombier qunlock(&fslck); 90*906943f9SDavid du Colombier } 91*906943f9SDavid du Colombier 92*906943f9SDavid du Colombier static void 93*906943f9SDavid du Colombier usbfsdelnth(int i) 94*906943f9SDavid du Colombier { 95*906943f9SDavid du Colombier if(fs[i] != nil){ 96*906943f9SDavid du Colombier dprint(2, "%s: fsdel %s", argv0, fs[i]->name); 97*906943f9SDavid du Colombier if(fs[i]->dev != nil){ 98*906943f9SDavid du Colombier dprint(2, " dev %#p ref %ld\n", 99*906943f9SDavid du Colombier fs[i]->dev, fs[i]->dev->ref); 100*906943f9SDavid du Colombier }else 101*906943f9SDavid du Colombier dprint(2, "no dev\n"); 102*906943f9SDavid du Colombier if(fs[i]->end != nil) 103*906943f9SDavid du Colombier fs[i]->end(fs[i]); 104*906943f9SDavid du Colombier else 105*906943f9SDavid du Colombier closedev(fs[i]->dev); 106*906943f9SDavid du Colombier fsused--; 107*906943f9SDavid du Colombier } 108*906943f9SDavid du Colombier fs[i] = nil; 109*906943f9SDavid du Colombier if(fsused == 0 && exitonclose != 0){ 110*906943f9SDavid du Colombier fprint(2, "%s: all file systems gone: exiting\n", argv0); 111*906943f9SDavid du Colombier threadexitsall(nil); 112*906943f9SDavid du Colombier } 113*906943f9SDavid du Colombier } 114*906943f9SDavid du Colombier 115*906943f9SDavid du Colombier void 116*906943f9SDavid du Colombier usbfsdel(Usbfs *dfs) 117*906943f9SDavid du Colombier { 118*906943f9SDavid du Colombier int i; 119*906943f9SDavid du Colombier 120*906943f9SDavid du Colombier qlock(&fslck); 121*906943f9SDavid du Colombier for(i = 0; i < nfs; i++) 122*906943f9SDavid du Colombier if(dfs == nil || fs[i] == dfs){ 123*906943f9SDavid du Colombier usbfsdelnth(i); 124*906943f9SDavid du Colombier if(dfs != nil) 125*906943f9SDavid du Colombier break; 126*906943f9SDavid du Colombier } 127*906943f9SDavid du Colombier qunlock(&fslck); 128*906943f9SDavid du Colombier } 129*906943f9SDavid du Colombier 130*906943f9SDavid du Colombier static void 131*906943f9SDavid du Colombier fsend(Usbfs*) 132*906943f9SDavid du Colombier { 133*906943f9SDavid du Colombier dprint(2, "%s: fsend\n", argv0); 134*906943f9SDavid du Colombier usbfsdel(nil); 135*906943f9SDavid du Colombier } 136*906943f9SDavid du Colombier 137*906943f9SDavid du Colombier void 138*906943f9SDavid du Colombier usbfsgone(char *dir) 139*906943f9SDavid du Colombier { 140*906943f9SDavid du Colombier int i; 141*906943f9SDavid du Colombier 142*906943f9SDavid du Colombier qlock(&fslck); 143*906943f9SDavid du Colombier /* devices may have more than one fs */ 144*906943f9SDavid du Colombier for(i = 0; i < nfs; i++) 145*906943f9SDavid du Colombier if(fs[i] != nil && fs[i]->dev != nil) 146*906943f9SDavid du Colombier if(strcmp(fs[i]->dev->dir, dir) == 0) 147*906943f9SDavid du Colombier usbfsdelnth(i); 148*906943f9SDavid du Colombier qunlock(&fslck); 149*906943f9SDavid du Colombier } 150*906943f9SDavid du Colombier 151*906943f9SDavid du Colombier static void 152*906943f9SDavid du Colombier fsclone(Usbfs*, Fid *o, Fid *n) 153*906943f9SDavid du Colombier { 154*906943f9SDavid du Colombier int qd; 155*906943f9SDavid du Colombier Dev *dev; 156*906943f9SDavid du Colombier void (*xfsclone)(Usbfs *fs, Fid *of, Fid *nf); 157*906943f9SDavid du Colombier 158*906943f9SDavid du Colombier xfsclone = nil; 159*906943f9SDavid du Colombier dev = nil; 160*906943f9SDavid du Colombier qd = qiddev(o->qid.path); 161*906943f9SDavid du Colombier qlock(&fslck); 162*906943f9SDavid du Colombier if(qd != Dtop && fs[qd] != nil && fs[qd]->clone != nil){ 163*906943f9SDavid du Colombier dev = fs[qd]->dev; 164*906943f9SDavid du Colombier if(dev != nil) 165*906943f9SDavid du Colombier incref(dev); 166*906943f9SDavid du Colombier xfsclone = fs[qd]->clone; 167*906943f9SDavid du Colombier } 168*906943f9SDavid du Colombier qunlock(&fslck); 169*906943f9SDavid du Colombier if(xfsclone != nil){ 170*906943f9SDavid du Colombier xfsclone(fs[qd], o, n); 171*906943f9SDavid du Colombier } 172*906943f9SDavid du Colombier if(dev != nil) 173*906943f9SDavid du Colombier closedev(dev); 174*906943f9SDavid du Colombier } 175*906943f9SDavid du Colombier 176*906943f9SDavid du Colombier static int 177*906943f9SDavid du Colombier fswalk(Usbfs*, Fid *fid, char *name) 178*906943f9SDavid du Colombier { 179*906943f9SDavid du Colombier Qid q; 180*906943f9SDavid du Colombier int qd, qf; 181*906943f9SDavid du Colombier int i; 182*906943f9SDavid du Colombier int rc; 183*906943f9SDavid du Colombier Dev *dev; 184*906943f9SDavid du Colombier Dir d; 185*906943f9SDavid du Colombier int (*xfswalk)(Usbfs *fs, Fid *f, char *name); 186*906943f9SDavid du Colombier 187*906943f9SDavid du Colombier q = fid->qid; 188*906943f9SDavid du Colombier qd = qiddev(q.path); 189*906943f9SDavid du Colombier qf = qidfile(q.path); 190*906943f9SDavid du Colombier 191*906943f9SDavid du Colombier q.type = QTDIR; 192*906943f9SDavid du Colombier q.vers = 0; 193*906943f9SDavid du Colombier if(strcmp(name, "..") == 0) 194*906943f9SDavid du Colombier if(qd == Dtop || qf == Qdir){ 195*906943f9SDavid du Colombier q.path = mkqid(Dtop, Qdir); 196*906943f9SDavid du Colombier fid->qid = q; 197*906943f9SDavid du Colombier return 0; 198*906943f9SDavid du Colombier } 199*906943f9SDavid du Colombier if(qd != 0){ 200*906943f9SDavid du Colombier qlock(&fslck); 201*906943f9SDavid du Colombier if(fs[qd] == nil){ 202*906943f9SDavid du Colombier qunlock(&fslck); 203*906943f9SDavid du Colombier werrstr(Eio); 204*906943f9SDavid du Colombier return -1; 205*906943f9SDavid du Colombier } 206*906943f9SDavid du Colombier dev = fs[qd]->dev; 207*906943f9SDavid du Colombier if(dev != nil) 208*906943f9SDavid du Colombier incref(dev); 209*906943f9SDavid du Colombier xfswalk = fs[qd]->walk; 210*906943f9SDavid du Colombier qunlock(&fslck); 211*906943f9SDavid du Colombier rc = xfswalk(fs[qd], fid, name); 212*906943f9SDavid du Colombier if(dev != nil) 213*906943f9SDavid du Colombier closedev(dev); 214*906943f9SDavid du Colombier return rc; 215*906943f9SDavid du Colombier } 216*906943f9SDavid du Colombier qlock(&fslck); 217*906943f9SDavid du Colombier for(i = 0; i < nfs; i++) 218*906943f9SDavid du Colombier if(fs[i] != nil && strcmp(name, fs[i]->name) == 0){ 219*906943f9SDavid du Colombier q.path = mkqid(i, Qdir); 220*906943f9SDavid du Colombier fs[i]->stat(fs[i], q, &d); /* may be a file */ 221*906943f9SDavid du Colombier fid->qid = d.qid; 222*906943f9SDavid du Colombier qunlock(&fslck); 223*906943f9SDavid du Colombier return 0; 224*906943f9SDavid du Colombier } 225*906943f9SDavid du Colombier qunlock(&fslck); 226*906943f9SDavid du Colombier werrstr(Enotfound); 227*906943f9SDavid du Colombier return -1; 228*906943f9SDavid du Colombier } 229*906943f9SDavid du Colombier 230*906943f9SDavid du Colombier static int 231*906943f9SDavid du Colombier fsopen(Usbfs*, Fid *fid, int mode) 232*906943f9SDavid du Colombier { 233*906943f9SDavid du Colombier int qd; 234*906943f9SDavid du Colombier int rc; 235*906943f9SDavid du Colombier Dev *dev; 236*906943f9SDavid du Colombier int (*xfsopen)(Usbfs *fs, Fid *f, int mode); 237*906943f9SDavid du Colombier 238*906943f9SDavid du Colombier qd = qiddev(fid->qid.path); 239*906943f9SDavid du Colombier if(qd == Dtop) 240*906943f9SDavid du Colombier return 0; 241*906943f9SDavid du Colombier qlock(&fslck); 242*906943f9SDavid du Colombier if(fs[qd] == nil){ 243*906943f9SDavid du Colombier qunlock(&fslck); 244*906943f9SDavid du Colombier werrstr(Eio); 245*906943f9SDavid du Colombier return -1; 246*906943f9SDavid du Colombier } 247*906943f9SDavid du Colombier dev = fs[qd]->dev; 248*906943f9SDavid du Colombier if(dev != nil) 249*906943f9SDavid du Colombier incref(dev); 250*906943f9SDavid du Colombier xfsopen = fs[qd]->open; 251*906943f9SDavid du Colombier qunlock(&fslck); 252*906943f9SDavid du Colombier if(xfsopen != nil) 253*906943f9SDavid du Colombier rc = xfsopen(fs[qd], fid, mode); 254*906943f9SDavid du Colombier else 255*906943f9SDavid du Colombier rc = 0; 256*906943f9SDavid du Colombier if(dev != nil) 257*906943f9SDavid du Colombier closedev(dev); 258*906943f9SDavid du Colombier return rc; 259*906943f9SDavid du Colombier } 260*906943f9SDavid du Colombier 261*906943f9SDavid du Colombier static int 262*906943f9SDavid du Colombier dirgen(Usbfs*, Qid, int n, Dir *d, void *) 263*906943f9SDavid du Colombier { 264*906943f9SDavid du Colombier int i; 265*906943f9SDavid du Colombier Dev *dev; 266*906943f9SDavid du Colombier char *nm; 267*906943f9SDavid du Colombier 268*906943f9SDavid du Colombier qlock(&fslck); 269*906943f9SDavid du Colombier for(i = 0; i < nfs; i++) 270*906943f9SDavid du Colombier if(fs[i] != nil && n-- == 0){ 271*906943f9SDavid du Colombier d->qid.type = QTDIR; 272*906943f9SDavid du Colombier d->qid.path = mkqid(i, Qdir); 273*906943f9SDavid du Colombier d->qid.vers = 0; 274*906943f9SDavid du Colombier dev = fs[i]->dev; 275*906943f9SDavid du Colombier if(dev != nil) 276*906943f9SDavid du Colombier incref(dev); 277*906943f9SDavid du Colombier nm = d->name; 278*906943f9SDavid du Colombier fs[i]->stat(fs[i], d->qid, d); 279*906943f9SDavid du Colombier d->name = nm; 280*906943f9SDavid du Colombier strncpy(d->name, fs[i]->name, Namesz); 281*906943f9SDavid du Colombier if(dev != nil) 282*906943f9SDavid du Colombier closedev(dev); 283*906943f9SDavid du Colombier qunlock(&fslck); 284*906943f9SDavid du Colombier return 0; 285*906943f9SDavid du Colombier } 286*906943f9SDavid du Colombier qunlock(&fslck); 287*906943f9SDavid du Colombier return -1; 288*906943f9SDavid du Colombier } 289*906943f9SDavid du Colombier 290*906943f9SDavid du Colombier static long 291*906943f9SDavid du Colombier fsread(Usbfs*, Fid *fid, void *data, long cnt, vlong off) 292*906943f9SDavid du Colombier { 293*906943f9SDavid du Colombier int qd; 294*906943f9SDavid du Colombier int rc; 295*906943f9SDavid du Colombier Dev *dev; 296*906943f9SDavid du Colombier Qid q; 297*906943f9SDavid du Colombier long (*xfsread)(Usbfs *fs, Fid *f, void *data, long count, vlong ); 298*906943f9SDavid du Colombier 299*906943f9SDavid du Colombier q = fid->qid; 300*906943f9SDavid du Colombier qd = qiddev(q.path); 301*906943f9SDavid du Colombier if(qd == Dtop) 302*906943f9SDavid du Colombier return usbdirread(nil, q, data, cnt, off, dirgen, nil); 303*906943f9SDavid du Colombier qlock(&fslck); 304*906943f9SDavid du Colombier if(fs[qd] == nil){ 305*906943f9SDavid du Colombier qunlock(&fslck); 306*906943f9SDavid du Colombier werrstr(Eio); 307*906943f9SDavid du Colombier return -1; 308*906943f9SDavid du Colombier } 309*906943f9SDavid du Colombier dev = fs[qd]->dev; 310*906943f9SDavid du Colombier if(dev != nil) 311*906943f9SDavid du Colombier incref(dev); 312*906943f9SDavid du Colombier xfsread = fs[qd]->read; 313*906943f9SDavid du Colombier qunlock(&fslck); 314*906943f9SDavid du Colombier rc = xfsread(fs[qd], fid, data, cnt, off); 315*906943f9SDavid du Colombier if(dev != nil) 316*906943f9SDavid du Colombier closedev(dev); 317*906943f9SDavid du Colombier return rc; 318*906943f9SDavid du Colombier } 319*906943f9SDavid du Colombier 320*906943f9SDavid du Colombier static long 321*906943f9SDavid du Colombier fswrite(Usbfs*, Fid *fid, void *data, long cnt, vlong off) 322*906943f9SDavid du Colombier { 323*906943f9SDavid du Colombier int qd; 324*906943f9SDavid du Colombier int rc; 325*906943f9SDavid du Colombier Dev *dev; 326*906943f9SDavid du Colombier long (*xfswrite)(Usbfs *fs, Fid *f, void *data, long count, vlong ); 327*906943f9SDavid du Colombier 328*906943f9SDavid du Colombier qd = qiddev(fid->qid.path); 329*906943f9SDavid du Colombier if(qd == Dtop) 330*906943f9SDavid du Colombier sysfatal("fswrite: not for usbd /"); 331*906943f9SDavid du Colombier qlock(&fslck); 332*906943f9SDavid du Colombier if(fs[qd] == nil){ 333*906943f9SDavid du Colombier qunlock(&fslck); 334*906943f9SDavid du Colombier werrstr(Eio); 335*906943f9SDavid du Colombier return -1; 336*906943f9SDavid du Colombier } 337*906943f9SDavid du Colombier dev = fs[qd]->dev; 338*906943f9SDavid du Colombier if(dev != nil) 339*906943f9SDavid du Colombier incref(dev); 340*906943f9SDavid du Colombier xfswrite = fs[qd]->write; 341*906943f9SDavid du Colombier qunlock(&fslck); 342*906943f9SDavid du Colombier rc = xfswrite(fs[qd], fid, data, cnt, off); 343*906943f9SDavid du Colombier if(dev != nil) 344*906943f9SDavid du Colombier closedev(dev); 345*906943f9SDavid du Colombier return rc; 346*906943f9SDavid du Colombier } 347*906943f9SDavid du Colombier 348*906943f9SDavid du Colombier 349*906943f9SDavid du Colombier static void 350*906943f9SDavid du Colombier fsclunk(Usbfs*, Fid* fid) 351*906943f9SDavid du Colombier { 352*906943f9SDavid du Colombier int qd; 353*906943f9SDavid du Colombier Dev *dev; 354*906943f9SDavid du Colombier void (*xfsclunk)(Usbfs *fs, Fid *f); 355*906943f9SDavid du Colombier 356*906943f9SDavid du Colombier dev = nil; 357*906943f9SDavid du Colombier qd = qiddev(fid->qid.path); 358*906943f9SDavid du Colombier qlock(&fslck); 359*906943f9SDavid du Colombier if(qd != Dtop && fs[qd] != nil){ 360*906943f9SDavid du Colombier dev=fs[qd]->dev; 361*906943f9SDavid du Colombier if(dev != nil) 362*906943f9SDavid du Colombier incref(dev); 363*906943f9SDavid du Colombier xfsclunk = fs[qd]->clunk; 364*906943f9SDavid du Colombier }else 365*906943f9SDavid du Colombier xfsclunk = nil; 366*906943f9SDavid du Colombier qunlock(&fslck); 367*906943f9SDavid du Colombier if(xfsclunk != nil){ 368*906943f9SDavid du Colombier xfsclunk(fs[qd], fid); 369*906943f9SDavid du Colombier } 370*906943f9SDavid du Colombier if(dev != nil) 371*906943f9SDavid du Colombier closedev(dev); 372*906943f9SDavid du Colombier } 373*906943f9SDavid du Colombier 374*906943f9SDavid du Colombier static int 375*906943f9SDavid du Colombier fsstat(Usbfs*, Qid qid, Dir *d) 376*906943f9SDavid du Colombier { 377*906943f9SDavid du Colombier int qd; 378*906943f9SDavid du Colombier int rc; 379*906943f9SDavid du Colombier Dev *dev; 380*906943f9SDavid du Colombier int (*xfsstat)(Usbfs *fs, Qid q, Dir *d); 381*906943f9SDavid du Colombier 382*906943f9SDavid du Colombier qd = qiddev(qid.path); 383*906943f9SDavid du Colombier if(qd == Dtop){ 384*906943f9SDavid du Colombier d->qid = qid; 385*906943f9SDavid du Colombier d->name = "usb"; 386*906943f9SDavid du Colombier d->length = 0; 387*906943f9SDavid du Colombier d->mode = 0555|DMDIR; 388*906943f9SDavid du Colombier return 0; 389*906943f9SDavid du Colombier } 390*906943f9SDavid du Colombier qlock(&fslck); 391*906943f9SDavid du Colombier if(fs[qd] == nil){ 392*906943f9SDavid du Colombier qunlock(&fslck); 393*906943f9SDavid du Colombier werrstr(Eio); 394*906943f9SDavid du Colombier return -1; 395*906943f9SDavid du Colombier } 396*906943f9SDavid du Colombier xfsstat = fs[qd]->stat; 397*906943f9SDavid du Colombier dev = fs[qd]->dev; 398*906943f9SDavid du Colombier if(dev != nil) 399*906943f9SDavid du Colombier incref(dev); 400*906943f9SDavid du Colombier qunlock(&fslck); 401*906943f9SDavid du Colombier rc = xfsstat(fs[qd], qid, d); 402*906943f9SDavid du Colombier if(dev != nil) 403*906943f9SDavid du Colombier closedev(dev); 404*906943f9SDavid du Colombier return rc; 405*906943f9SDavid du Colombier } 406*906943f9SDavid du Colombier 407*906943f9SDavid du Colombier Usbfs usbdirfs = 408*906943f9SDavid du Colombier { 409*906943f9SDavid du Colombier .walk = fswalk, 410*906943f9SDavid du Colombier .clone = fsclone, 411*906943f9SDavid du Colombier .clunk = fsclunk, 412*906943f9SDavid du Colombier .open = fsopen, 413*906943f9SDavid du Colombier .read = fsread, 414*906943f9SDavid du Colombier .write = fswrite, 415*906943f9SDavid du Colombier .stat = fsstat, 416*906943f9SDavid du Colombier .end = fsend, 417*906943f9SDavid du Colombier }; 418*906943f9SDavid du Colombier 419