sub.c 24 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537
  1. #include "all.h"
  2. #include "io.h"
  3. enum {
  4. Slop = 256, /* room at the start of a message buf for proto hdrs */
  5. };
  6. Filsys*
  7. fsstr(char *p)
  8. {
  9. Filsys *fs;
  10. for(fs=filsys; fs->name; fs++)
  11. if(strcmp(fs->name, p) == 0)
  12. return fs;
  13. return 0;
  14. }
  15. Filsys*
  16. dev2fs(Device *dev)
  17. {
  18. Filsys *fs;
  19. for(fs=filsys; fs->name; fs++)
  20. if(fs->dev == dev)
  21. return fs;
  22. return 0;
  23. }
  24. /*
  25. * allocate 'count' contiguous channels
  26. * of type 'type' and return pointer to base
  27. */
  28. Chan*
  29. fs_chaninit(int type, int count, int data)
  30. {
  31. uchar *p;
  32. Chan *cp, *icp;
  33. int i;
  34. p = malloc(count * (sizeof(Chan)+data));
  35. icp = (Chan*)p;
  36. for(i = 0; i < count; i++) {
  37. cp = (Chan*)p;
  38. cp->next = chans;
  39. chans = cp;
  40. cp->type = type;
  41. cp->chan = cons.chano;
  42. cons.chano++;
  43. strncpy(cp->whoname, "<none>", sizeof cp->whoname);
  44. wlock(&cp->reflock);
  45. wunlock(&cp->reflock);
  46. rlock(&cp->reflock);
  47. runlock(&cp->reflock);
  48. p += sizeof(Chan);
  49. if(data){
  50. cp->pdata = p;
  51. p += data;
  52. }
  53. }
  54. return icp;
  55. }
  56. void
  57. fileinit(Chan *cp)
  58. {
  59. File *f, *prev;
  60. Tlock *t;
  61. int h;
  62. loop:
  63. lock(&flock);
  64. for (h=0; h < nelem(flist); h++)
  65. for (prev=0, f = flist[h]; f; prev=f, f=f->next) {
  66. if(f->cp != cp)
  67. continue;
  68. if(prev) {
  69. prev->next = f->next;
  70. f->next = flist[h];
  71. flist[h] = f;
  72. }
  73. flist[h] = f->next;
  74. unlock(&flock);
  75. qlock(f);
  76. if(t = f->tlock) {
  77. if(t->file == f)
  78. t->time = 0; /* free the lock */
  79. f->tlock = 0;
  80. }
  81. if(f->open & FREMOV)
  82. doremove(f, 0);
  83. freewp(f->wpath);
  84. f->open = 0;
  85. authfree(f->auth);
  86. f->auth = 0;
  87. f->cp = 0;
  88. qunlock(f);
  89. goto loop;
  90. }
  91. unlock(&flock);
  92. }
  93. enum { NOFID = (ulong)~0 };
  94. /*
  95. * returns a locked file structure
  96. */
  97. File*
  98. filep(Chan *cp, ulong fid, int flag)
  99. {
  100. File *f;
  101. int h;
  102. if(fid == NOFID)
  103. return 0;
  104. h = (long)cp + fid;
  105. if(h < 0)
  106. h = ~h;
  107. h %= nelem(flist);
  108. loop:
  109. lock(&flock);
  110. for(f=flist[h]; f; f=f->next)
  111. if(f->fid == fid && f->cp == cp){
  112. /*
  113. * Already in use is an error
  114. * when called from attach or clone (walk
  115. * in 9P2000). The console uses FID[12] and
  116. * never clunks them so catch that case.
  117. */
  118. if(flag == 0 || cp == cons.chan)
  119. goto out;
  120. unlock(&flock);
  121. return 0;
  122. }
  123. if(flag) {
  124. f = newfp();
  125. if(f) {
  126. f->fid = fid;
  127. f->cp = cp;
  128. f->wpath = 0;
  129. f->tlock = 0;
  130. f->doffset = 0;
  131. f->dslot = 0;
  132. f->auth = 0;
  133. f->next = flist[h];
  134. flist[h] = f;
  135. goto out;
  136. }
  137. }
  138. unlock(&flock);
  139. return 0;
  140. out:
  141. unlock(&flock);
  142. qlock(f);
  143. if(f->fid == fid && f->cp == cp)
  144. return f;
  145. qunlock(f);
  146. goto loop;
  147. }
  148. /*
  149. * always called with flock locked
  150. */
  151. File*
  152. newfp(void)
  153. {
  154. static int first;
  155. File *f;
  156. int start, i;
  157. i = first;
  158. start = i;
  159. do {
  160. f = &files[i];
  161. i++;
  162. if(i >= conf.nfile)
  163. i = 0;
  164. if(f->cp)
  165. continue;
  166. first = i;
  167. return f;
  168. } while(i != start);
  169. print("out of files\n");
  170. return 0;
  171. }
  172. void
  173. freefp(File *fp)
  174. {
  175. Chan *cp;
  176. File *f, *prev;
  177. int h;
  178. if(!fp || !(cp = fp->cp))
  179. return;
  180. h = (long)cp + fp->fid;
  181. if(h < 0)
  182. h = ~h;
  183. h %= nelem(flist);
  184. lock(&flock);
  185. for(prev=0,f=flist[h]; f; prev=f,f=f->next)
  186. if(f == fp) {
  187. if(prev)
  188. prev->next = f->next;
  189. else
  190. flist[h] = f->next;
  191. break;
  192. }
  193. fp->cp = 0;
  194. unlock(&flock);
  195. }
  196. int
  197. iaccess(File *f, Dentry *d, int m)
  198. {
  199. /* uid none gets only other permissions */
  200. if(f->uid != 0) {
  201. /*
  202. * owner
  203. */
  204. if(f->uid == d->uid)
  205. if((m<<6) & d->mode)
  206. return 0;
  207. /*
  208. * group membership
  209. */
  210. if(ingroup(f->uid, d->gid))
  211. if((m<<3) & d->mode)
  212. return 0;
  213. }
  214. /*
  215. * other
  216. */
  217. if(m & d->mode) {
  218. if((d->mode & DDIR) && (m == DEXEC))
  219. return 0;
  220. if(!ingroup(f->uid, 9999))
  221. return 0;
  222. }
  223. /*
  224. * various forms of superuser
  225. */
  226. if(wstatallow)
  227. return 0;
  228. if(duallow != 0 && duallow == f->uid)
  229. if((d->mode & DDIR) && (m == DREAD || m == DEXEC))
  230. return 0;
  231. return 1;
  232. }
  233. Tlock*
  234. tlocked(Iobuf *p, Dentry *d)
  235. {
  236. Tlock *t, *t1;
  237. Off qpath;
  238. Timet tim;
  239. Device *dev;
  240. tim = toytime();
  241. qpath = d->qid.path;
  242. dev = p->dev;
  243. again:
  244. t1 = 0;
  245. for(t=tlocks+NTLOCK-1; t>=tlocks; t--) {
  246. if(t->qpath == qpath)
  247. if(t->time >= tim)
  248. if(t->dev == dev)
  249. return nil; /* its locked */
  250. if(t1 != nil && t->time == 0)
  251. t1 = t; /* remember free lock */
  252. }
  253. if(t1 == 0) {
  254. // reclaim old locks
  255. lock(&tlocklock);
  256. for(t=tlocks+NTLOCK-1; t>=tlocks; t--)
  257. if(t->time < tim) {
  258. t->time = 0;
  259. t1 = t;
  260. }
  261. unlock(&tlocklock);
  262. }
  263. if(t1) {
  264. lock(&tlocklock);
  265. if(t1->time != 0) {
  266. unlock(&tlocklock);
  267. goto again;
  268. }
  269. t1->dev = dev;
  270. t1->qpath = qpath;
  271. t1->time = tim + TLOCK;
  272. unlock(&tlocklock);
  273. }
  274. /* botch
  275. * out of tlock nodes simulates
  276. * a locked file
  277. */
  278. return t1;
  279. }
  280. Wpath*
  281. newwp(void)
  282. {
  283. static int si = 0;
  284. int i;
  285. Wpath *w, *sw, *ew;
  286. i = si + 1;
  287. if(i < 0 || i >= conf.nwpath)
  288. i = 0;
  289. si = i;
  290. sw = &wpaths[i];
  291. ew = &wpaths[conf.nwpath];
  292. for(w=sw;;) {
  293. w++;
  294. if(w >= ew)
  295. w = &wpaths[0];
  296. if(w == sw) {
  297. print("out of wpaths\n");
  298. return 0;
  299. }
  300. if(w->refs)
  301. continue;
  302. lock(&wpathlock);
  303. if(w->refs) {
  304. unlock(&wpathlock);
  305. continue;
  306. }
  307. w->refs = 1;
  308. w->up = 0;
  309. unlock(&wpathlock);
  310. return w;
  311. }
  312. }
  313. void
  314. freewp(Wpath *w)
  315. {
  316. lock(&wpathlock);
  317. for(; w; w=w->up)
  318. w->refs--;
  319. unlock(&wpathlock);
  320. }
  321. Off
  322. qidpathgen(Device *dev)
  323. {
  324. Iobuf *p;
  325. Superb *sb;
  326. Off path;
  327. p = getbuf(dev, superaddr(dev), Brd|Bmod);
  328. if(!p || checktag(p, Tsuper, QPSUPER))
  329. panic("newqid: super block");
  330. sb = (Superb*)p->iobuf;
  331. sb->qidgen++;
  332. path = sb->qidgen;
  333. putbuf(p);
  334. return path;
  335. }
  336. /* truncating to length > 0 */
  337. static void
  338. truncfree(Truncstate *ts, Device *dev, int d, Iobuf *p, int i)
  339. {
  340. int pastlast;
  341. Off a;
  342. pastlast = ts->pastlast;
  343. a = ((Off *)p->iobuf)[i];
  344. if (d > 0 || pastlast)
  345. buffree(dev, a, d, ts);
  346. if (pastlast) {
  347. ((Off *)p->iobuf)[i] = 0;
  348. p->flags |= Bmod|Bimm;
  349. } else if (d == 0 && ts->relblk == ts->lastblk)
  350. ts->pastlast = 1;
  351. if (d == 0)
  352. ts->relblk++;
  353. }
  354. /*
  355. * free the block at `addr' on dev.
  356. * if it's an indirect block (d [depth] > 0),
  357. * first recursively free all the blocks it names.
  358. *
  359. * ts->relblk is the block number within the file of this
  360. * block (or the first data block eventually pointed to via
  361. * this indirect block).
  362. */
  363. void
  364. buffree(Device *dev, Off addr, int d, Truncstate *ts)
  365. {
  366. Iobuf *p;
  367. Off a;
  368. int i, pastlast;
  369. if(!addr)
  370. return;
  371. pastlast = (ts == nil? 1: ts->pastlast);
  372. /*
  373. * if this is an indirect block, recurse and free any
  374. * suitable blocks within it (possibly via further indirect blocks).
  375. */
  376. if(d > 0) {
  377. d--;
  378. p = getbuf(dev, addr, Brd);
  379. if(p) {
  380. if (ts == nil) /* common case: create */
  381. for(i=INDPERBUF-1; i>=0; i--) {
  382. a = ((Off *)p->iobuf)[i];
  383. buffree(dev, a, d, nil);
  384. }
  385. else /* wstat truncation */
  386. for (i = 0; i < INDPERBUF; i++)
  387. truncfree(ts, dev, d, p, i);
  388. putbuf(p);
  389. }
  390. }
  391. if (!pastlast)
  392. return;
  393. /*
  394. * having zeroed the pointer to this block, add it to the free list.
  395. * stop outstanding i/o
  396. */
  397. p = getbuf(dev, addr, Bprobe);
  398. if(p) {
  399. p->flags &= ~(Bmod|Bimm);
  400. putbuf(p);
  401. }
  402. /*
  403. * dont put written worm
  404. * blocks into free list
  405. */
  406. if(dev->type == Devcw) {
  407. i = cwfree(dev, addr);
  408. if(i)
  409. return;
  410. }
  411. p = getbuf(dev, superaddr(dev), Brd|Bmod);
  412. if(!p || checktag(p, Tsuper, QPSUPER))
  413. panic("buffree: super block");
  414. addfree(dev, addr, (Superb*)p->iobuf);
  415. putbuf(p);
  416. }
  417. Off
  418. bufalloc(Device *dev, int tag, long qid, int uid)
  419. {
  420. Iobuf *bp, *p;
  421. Superb *sb;
  422. Off a, n;
  423. p = getbuf(dev, superaddr(dev), Brd|Bmod);
  424. if(!p || checktag(p, Tsuper, QPSUPER)) {
  425. print("bufalloc: super block\n");
  426. if(p)
  427. putbuf(p);
  428. return 0;
  429. }
  430. sb = (Superb*)p->iobuf;
  431. loop:
  432. n = --sb->fbuf.nfree;
  433. sb->tfree--;
  434. if(n < 0 || n >= FEPERBUF) {
  435. print("bufalloc: %Z: bad freelist\n", dev);
  436. n = 0;
  437. sb->fbuf.free[0] = 0;
  438. }
  439. a = sb->fbuf.free[n];
  440. if(n <= 0) {
  441. if(a == 0) {
  442. sb->tfree = 0;
  443. sb->fbuf.nfree = 1;
  444. if(dev->type == Devcw) {
  445. n = uid;
  446. if(n < 0 || n >= nelem(growacct))
  447. n = 0;
  448. growacct[n]++;
  449. if(cwgrow(dev, sb, uid))
  450. goto loop;
  451. }
  452. putbuf(p);
  453. print("fs %Z full uid=%d\n", dev, uid);
  454. return 0;
  455. }
  456. bp = getbuf(dev, a, Brd);
  457. if(!bp || checktag(bp, Tfree, QPNONE)) {
  458. if(bp)
  459. putbuf(bp);
  460. putbuf(p);
  461. return 0;
  462. }
  463. sb->fbuf = *(Fbuf*)bp->iobuf;
  464. putbuf(bp);
  465. }
  466. bp = getbuf(dev, a, Bmod);
  467. memset(bp->iobuf, 0, RBUFSIZE);
  468. settag(bp, tag, qid);
  469. if(tag == Tind1 || tag == Tind2 || tag == Tdir)
  470. bp->flags |= Bimm;
  471. putbuf(bp);
  472. putbuf(p);
  473. return a;
  474. }
  475. /*
  476. * what are legal characters in a name?
  477. * only disallow control characters.
  478. * a) utf avoids control characters.
  479. * b) '/' may not be the separator
  480. */
  481. int
  482. checkname(char *n)
  483. {
  484. int i, c;
  485. for(i=0; i<NAMELEN; i++) {
  486. c = *n & 0xff;
  487. if(c == 0) {
  488. if(i == 0)
  489. return 1;
  490. memset(n, 0, NAMELEN-i);
  491. return 0;
  492. }
  493. if(c <= 040)
  494. return 1;
  495. n++;
  496. }
  497. return 1; /* too long */
  498. }
  499. void
  500. addfree(Device *dev, Off addr, Superb *sb)
  501. {
  502. int n;
  503. Iobuf *p;
  504. n = sb->fbuf.nfree;
  505. if(n < 0 || n > FEPERBUF)
  506. panic("addfree: bad freelist");
  507. if(n >= FEPERBUF) {
  508. p = getbuf(dev, addr, Bmod|Bimm);
  509. if(p == 0)
  510. panic("addfree: getbuf");
  511. *(Fbuf*)p->iobuf = sb->fbuf;
  512. settag(p, Tfree, QPNONE);
  513. putbuf(p);
  514. n = 0;
  515. }
  516. sb->fbuf.free[n++] = addr;
  517. sb->fbuf.nfree = n;
  518. sb->tfree++;
  519. if(addr >= sb->fsize)
  520. sb->fsize = addr+1;
  521. }
  522. /*
  523. static int
  524. Yfmt(Fmt* fmt)
  525. {
  526. Chan *cp;
  527. char s[20];
  528. cp = va_arg(fmt->args, Chan*);
  529. sprint(s, "C%d.%.3d", cp->type, cp->chan);
  530. return fmtstrcpy(fmt, s);
  531. }
  532. */
  533. static int
  534. Zfmt(Fmt* fmt)
  535. {
  536. Device *d;
  537. int c, c1;
  538. char s[100];
  539. d = va_arg(fmt->args, Device*);
  540. if(d == nil) {
  541. sprint(s, "Z***");
  542. goto out;
  543. }
  544. c = c1 = '\0';
  545. switch(d->type) {
  546. default:
  547. sprint(s, "D%d", d->type);
  548. break;
  549. case Devwren:
  550. c = 'w';
  551. /* fallthrough */
  552. case Devworm:
  553. if (c == '\0')
  554. c = 'r';
  555. /* fallthrough */
  556. case Devlworm:
  557. if (c == '\0')
  558. c = 'l';
  559. if(d->wren.ctrl == 0 && d->wren.lun == 0)
  560. sprint(s, "%c%d", c, d->wren.targ);
  561. else
  562. sprint(s, "%c%d.%d.%d", c, d->wren.ctrl, d->wren.targ,
  563. d->wren.lun);
  564. break;
  565. case Devmcat:
  566. c = '(';
  567. c1 = ')';
  568. /* fallthrough */
  569. case Devmlev:
  570. if (c == '\0') {
  571. c = '[';
  572. c1 = ']';
  573. }
  574. /* fallthrough */
  575. case Devmirr:
  576. if (c == '\0') {
  577. c = '{';
  578. c1 = '}';
  579. }
  580. if(d->cat.first == d->cat.last)
  581. sprint(s, "%c%Z%c", c, d->cat.first, c1);
  582. else if(d->cat.first->link == d->cat.last)
  583. sprint(s, "%c%Z%Z%c", c, d->cat.first, d->cat.last, c1);
  584. else
  585. sprint(s, "%c%Z-%Z%c", c, d->cat.first, d->cat.last, c1);
  586. break;
  587. case Devro:
  588. sprint(s, "o%Z%Z", d->ro.parent->cw.c, d->ro.parent->cw.w);
  589. break;
  590. case Devcw:
  591. sprint(s, "c%Z%Z", d->cw.c, d->cw.w);
  592. break;
  593. case Devjuke:
  594. sprint(s, "j%Z%Z", d->j.j, d->j.m);
  595. break;
  596. case Devfworm:
  597. sprint(s, "f%Z", d->fw.fw);
  598. break;
  599. case Devpart:
  600. sprint(s, "p(%Z)%ld.%ld", d->part.d, d->part.base, d->part.size);
  601. break;
  602. case Devswab:
  603. sprint(s, "x%Z", d->swab.d);
  604. break;
  605. case Devnone:
  606. sprint(s, "n");
  607. break;
  608. }
  609. out:
  610. return fmtstrcpy(fmt, s);
  611. }
  612. static int
  613. Gfmt(Fmt* fmt)
  614. {
  615. int t;
  616. char *s;
  617. t = va_arg(fmt->args, int);
  618. s = "<badtag>";
  619. if(t >= 0 && t < MAXTAG)
  620. s = tagnames[t];
  621. return fmtstrcpy(fmt, s);
  622. }
  623. void
  624. formatinit(void)
  625. {
  626. quotefmtinstall();
  627. // fmtinstall('Y', Yfmt); /* print channels */
  628. fmtinstall('Z', Zfmt); /* print devices */
  629. fmtinstall('G', Gfmt); /* print tags */
  630. fmtinstall('T', Tfmt); /* print times */
  631. // fmtinstall('E', eipfmt); /* print ether addresses */
  632. fmtinstall('I', eipfmt); /* print ip addresses */
  633. }
  634. void
  635. rootream(Device *dev, Off addr)
  636. {
  637. Iobuf *p;
  638. Dentry *d;
  639. p = getbuf(dev, addr, Bmod|Bimm);
  640. memset(p->iobuf, 0, RBUFSIZE);
  641. settag(p, Tdir, QPROOT);
  642. d = getdir(p, 0);
  643. strcpy(d->name, "/");
  644. d->uid = -1;
  645. d->gid = -1;
  646. d->mode = DALLOC | DDIR |
  647. ((DREAD|DEXEC) << 6) |
  648. ((DREAD|DEXEC) << 3) |
  649. ((DREAD|DEXEC) << 0);
  650. d->qid = QID9P1(QPROOT|QPDIR,0);
  651. d->atime = time(nil);
  652. d->mtime = d->atime;
  653. d->muid = 0;
  654. putbuf(p);
  655. }
  656. void
  657. superream(Device *dev, Off addr)
  658. {
  659. Iobuf *p;
  660. Superb *s;
  661. Off i;
  662. p = getbuf(dev, addr, Bmod|Bimm);
  663. memset(p->iobuf, 0, RBUFSIZE);
  664. settag(p, Tsuper, QPSUPER);
  665. s = (Superb*)p->iobuf;
  666. s->fstart = 2;
  667. s->fsize = devsize(dev);
  668. s->fbuf.nfree = 1;
  669. s->qidgen = 10;
  670. for(i = s->fsize-1; i >= addr+2; i--)
  671. addfree(dev, i, s);
  672. putbuf(p);
  673. }
  674. struct
  675. {
  676. Lock;
  677. Msgbuf *smsgbuf;
  678. Msgbuf *lmsgbuf;
  679. } msgalloc;
  680. /*
  681. * pre-allocate some message buffers at boot time.
  682. * if this supply is exhausted, more will be allocated as needed.
  683. */
  684. void
  685. mbinit(void)
  686. {
  687. Msgbuf *mb;
  688. Rabuf *rb;
  689. int i;
  690. lock(&msgalloc);
  691. unlock(&msgalloc);
  692. msgalloc.lmsgbuf = 0;
  693. msgalloc.smsgbuf = 0;
  694. for(i=0; i<conf.nlgmsg; i++) {
  695. mb = malloc(sizeof(Msgbuf));
  696. mb->magic = Mbmagic;
  697. mb->xdata = malloc(LARGEBUF+Slop);
  698. mb->flags = LARGE;
  699. mbfree(mb);
  700. cons.nlarge++;
  701. }
  702. for(i=0; i<conf.nsmmsg; i++) {
  703. mb = malloc(sizeof(Msgbuf));
  704. mb->magic = Mbmagic;
  705. mb->xdata = malloc(SMALLBUF+Slop);
  706. mb->flags = 0;
  707. mbfree(mb);
  708. cons.nsmall++;
  709. }
  710. memset(mballocs, 0, sizeof(mballocs));
  711. lock(&rabuflock);
  712. unlock(&rabuflock);
  713. rabuffree = 0;
  714. for(i=0; i<1000; i++) {
  715. rb = malloc(sizeof(*rb));
  716. rb->link = rabuffree;
  717. rabuffree = rb;
  718. }
  719. }
  720. Msgbuf*
  721. mballoc(int count, Chan *cp, int category)
  722. {
  723. Msgbuf *mb;
  724. lock(&msgalloc);
  725. if(count > SMALLBUF) {
  726. if(count > LARGEBUF)
  727. panic("msgbuf count");
  728. mb = msgalloc.lmsgbuf;
  729. if(mb == nil) {
  730. mb = malloc(sizeof(Msgbuf));
  731. mb->xdata = malloc(LARGEBUF+Slop);
  732. cons.nlarge++;
  733. } else
  734. msgalloc.lmsgbuf = mb->next;
  735. mb->flags = LARGE;
  736. } else {
  737. mb = msgalloc.smsgbuf;
  738. if(mb == nil) {
  739. mb = malloc(sizeof(Msgbuf));
  740. mb->xdata = malloc(SMALLBUF+Slop);
  741. cons.nsmall++;
  742. } else
  743. msgalloc.smsgbuf = mb->next;
  744. mb->flags = 0;
  745. }
  746. mballocs[category]++;
  747. unlock(&msgalloc);
  748. mb->magic = Mbmagic;
  749. mb->count = count;
  750. mb->chan = cp;
  751. mb->next = 0;
  752. mb->param = 0;
  753. mb->category = category;
  754. mb->data = mb->xdata+Slop;
  755. return mb;
  756. }
  757. void
  758. mbfree(Msgbuf *mb)
  759. {
  760. if(mb == nil)
  761. return;
  762. assert(mb->magic == Mbmagic);
  763. if (mb->magic != Mbmagic)
  764. panic("mbfree: bad magic 0x%lux", mb->magic);
  765. if(mb->flags & BTRACE)
  766. print("mbfree: BTRACE cat=%d flags=%ux, caller %#p\n",
  767. mb->category, mb->flags, getcallerpc(&mb));
  768. if(mb->flags & FREE)
  769. panic("mbfree already free");
  770. lock(&msgalloc);
  771. mballocs[mb->category]--;
  772. mb->flags |= FREE;
  773. if(mb->flags & LARGE) {
  774. mb->next = msgalloc.lmsgbuf;
  775. msgalloc.lmsgbuf = mb;
  776. } else {
  777. mb->next = msgalloc.smsgbuf;
  778. msgalloc.smsgbuf = mb;
  779. }
  780. mb->data = 0;
  781. mb->magic = 0;
  782. unlock(&msgalloc);
  783. }
  784. /*
  785. * returns 1 if n is prime
  786. * used for adjusting lengths
  787. * of hashing things.
  788. * there is no need to be clever
  789. */
  790. int
  791. prime(vlong n)
  792. {
  793. long i;
  794. if((n%2) == 0)
  795. return 0;
  796. for(i=3;; i+=2) {
  797. if((n%i) == 0)
  798. return 0;
  799. if((vlong)i*i >= n)
  800. return 1;
  801. }
  802. }
  803. char*
  804. getwrd(char *word, char *line)
  805. {
  806. int c, n;
  807. while(isascii(*line) && isspace(*line) && *line != '\n')
  808. line++;
  809. for(n = 0; n < Maxword; n++) {
  810. c = *line;
  811. if(c == '\0' || isascii(c) && isspace(c))
  812. break;
  813. line++;
  814. *word++ = c;
  815. }
  816. *word = 0;
  817. return line;
  818. }
  819. void
  820. hexdump(void *a, int n)
  821. {
  822. char s1[30], s2[4];
  823. uchar *p;
  824. int i;
  825. p = a;
  826. s1[0] = 0;
  827. for(i = 0; i < n; i++) {
  828. sprint(s2, " %.2ux", p[i]);
  829. strcat(s1, s2);
  830. if((i&7) == 7) {
  831. print("%s\n", s1);
  832. s1[0] = 0;
  833. }
  834. }
  835. if(s1[0])
  836. print("%s\n", s1);
  837. }
  838. void*
  839. fs_recv(Queue *q, int)
  840. {
  841. void *a;
  842. int i, c;
  843. if(q == nil)
  844. panic("recv null q");
  845. qlock(q);
  846. q->waitedfor = 1;
  847. while((c = q->count) <= 0)
  848. rsleep(&q->empty);
  849. i = q->loc;
  850. a = q->args[i];
  851. i++;
  852. if(i >= q->size)
  853. i = 0;
  854. q->loc = i;
  855. q->count = c-1;
  856. rwakeup(&q->full); /* no longer full */
  857. qunlock(q);
  858. return a;
  859. }
  860. void
  861. fs_send(Queue *q, void *a)
  862. {
  863. int i, c;
  864. if(q == nil)
  865. panic("send null q");
  866. if(!q->waitedfor) {
  867. for (i = 0; i < 5 && !q->waitedfor; i++)
  868. sleep(1000);
  869. if(!q->waitedfor) {
  870. /* likely a bug; don't wait forever */
  871. print("no readers yet for %s q\n", q->name);
  872. abort();
  873. }
  874. }
  875. qlock(q);
  876. while((c = q->count) >= q->size)
  877. rsleep(&q->full);
  878. i = q->loc + c;
  879. if(i >= q->size)
  880. i -= q->size;
  881. q->args[i] = a;
  882. q->count = c+1;
  883. rwakeup(&q->empty); /* no longer empty */
  884. qunlock(q);
  885. }
  886. Queue*
  887. newqueue(int size, char *name)
  888. {
  889. Queue *q;
  890. q = malloc(sizeof(Queue) + (size-1)*sizeof(void*));
  891. q->size = size;
  892. q->full.l = q->empty.l = &q->QLock;
  893. q->name = name;
  894. return q;
  895. }
  896. int
  897. devread(Device *d, Off b, void *c)
  898. {
  899. int e;
  900. for (;;)
  901. switch(d->type) {
  902. case Devcw:
  903. return cwread(d, b, c);
  904. case Devjuke:
  905. d = d->j.m;
  906. break;
  907. case Devro:
  908. return roread(d, b, c);
  909. case Devwren:
  910. return wrenread(d, b, c);
  911. case Devworm:
  912. case Devlworm:
  913. return wormread(d, b, c);
  914. case Devfworm:
  915. return fwormread(d, b, c);
  916. case Devmcat:
  917. return mcatread(d, b, c);
  918. case Devmlev:
  919. return mlevread(d, b, c);
  920. case Devmirr:
  921. return mirrread(d, b, c);
  922. case Devpart:
  923. return partread(d, b, c);
  924. case Devswab:
  925. e = devread(d->swab.d, b, c);
  926. if(e == 0)
  927. swab(c, 0);
  928. return e;
  929. case Devnone:
  930. print("read from device none(%lld)\n", (Wideoff)b);
  931. return 1;
  932. default:
  933. panic("illegal device in devread: %Z %lld",
  934. d, (Wideoff)b);
  935. return 1;
  936. }
  937. }
  938. int
  939. devwrite(Device *d, Off b, void *c)
  940. {
  941. int e;
  942. /*
  943. * set readonly to non-0 to prevent all writes;
  944. * mainly for trying dangerous experiments.
  945. */
  946. if (readonly)
  947. return 0;
  948. for (;;)
  949. switch(d->type) {
  950. case Devcw:
  951. return cwwrite(d, b, c);
  952. case Devjuke:
  953. d = d->j.m;
  954. break;
  955. case Devro:
  956. print("write to ro device %Z(%lld)\n", d, (Wideoff)b);
  957. return 1;
  958. case Devwren:
  959. return wrenwrite(d, b, c);
  960. case Devworm:
  961. case Devlworm:
  962. return wormwrite(d, b, c);
  963. case Devfworm:
  964. return fwormwrite(d, b, c);
  965. case Devmcat:
  966. return mcatwrite(d, b, c);
  967. case Devmlev:
  968. return mlevwrite(d, b, c);
  969. case Devmirr:
  970. return mirrwrite(d, b, c);
  971. case Devpart:
  972. return partwrite(d, b, c);
  973. case Devswab:
  974. swab(c, 1);
  975. e = devwrite(d->swab.d, b, c);
  976. swab(c, 0);
  977. return e;
  978. case Devnone:
  979. /* checktag() can generate blocks with type devnone */
  980. return 0;
  981. default:
  982. panic("illegal device in devwrite: %Z %lld",
  983. d, (Wideoff)b);
  984. return 1;
  985. }
  986. }
  987. Devsize
  988. devsize(Device *d)
  989. {
  990. for (;;)
  991. switch(d->type) {
  992. case Devcw:
  993. case Devro:
  994. return cwsize(d);
  995. case Devjuke:
  996. d = d->j.m;
  997. break;
  998. case Devwren:
  999. return wrensize(d);
  1000. case Devworm:
  1001. case Devlworm:
  1002. return wormsize(d);
  1003. case Devfworm:
  1004. return fwormsize(d);
  1005. case Devmcat:
  1006. return mcatsize(d);
  1007. case Devmlev:
  1008. return mlevsize(d);
  1009. case Devmirr:
  1010. return mirrsize(d);
  1011. case Devpart:
  1012. return partsize(d);
  1013. case Devswab:
  1014. d = d->swab.d;
  1015. break;
  1016. default:
  1017. panic("illegal device in devsize: %Z", d);
  1018. return 0;
  1019. }
  1020. }
  1021. /* result is malloced */
  1022. char *
  1023. sdof(Device *d)
  1024. {
  1025. static char name[256];
  1026. for (;;)
  1027. switch(d->type) {
  1028. case Devjuke:
  1029. d = d->j.j; /* robotics */
  1030. break;
  1031. case Devwren:
  1032. snprint(name, sizeof name, "/dev/sd%d%d", d->wren.ctrl,
  1033. d->wren.targ);
  1034. return strdup(name);
  1035. case Devswab:
  1036. d = d->swab.d;
  1037. break;
  1038. default:
  1039. panic("illegal device in sdof: %Z", d);
  1040. return nil;
  1041. }
  1042. }
  1043. Off
  1044. superaddr(Device *d)
  1045. {
  1046. for (;;)
  1047. switch(d->type) {
  1048. default:
  1049. return SUPER_ADDR;
  1050. case Devcw:
  1051. case Devro:
  1052. return cwsaddr(d);
  1053. case Devswab:
  1054. d = d->swab.d;
  1055. break;
  1056. }
  1057. }
  1058. Off
  1059. getraddr(Device *d)
  1060. {
  1061. for (;;)
  1062. switch(d->type) {
  1063. default:
  1064. return ROOT_ADDR;
  1065. case Devcw:
  1066. case Devro:
  1067. return cwraddr(d);
  1068. case Devswab:
  1069. d = d->swab.d;
  1070. break;
  1071. }
  1072. }
  1073. void
  1074. devream(Device *d, int top)
  1075. {
  1076. Device *l;
  1077. loop:
  1078. print("\tdevream: %Z %d\n", d, top);
  1079. switch(d->type) {
  1080. default:
  1081. print("ream: unknown dev type %Z\n", d);
  1082. return;
  1083. case Devcw:
  1084. devream(d->cw.w, 0);
  1085. devream(d->cw.c, 0);
  1086. if(top) {
  1087. wlock(&mainlock);
  1088. cwream(d);
  1089. wunlock(&mainlock);
  1090. }
  1091. devinit(d);
  1092. return;
  1093. case Devfworm:
  1094. devream(d->fw.fw, 0);
  1095. fwormream(d);
  1096. break;
  1097. case Devpart:
  1098. devream(d->part.d, 0);
  1099. break;
  1100. case Devmlev:
  1101. case Devmcat:
  1102. case Devmirr:
  1103. for(l=d->cat.first; l; l=l->link)
  1104. devream(l, 0);
  1105. break;
  1106. case Devjuke:
  1107. case Devworm:
  1108. case Devlworm:
  1109. case Devwren:
  1110. break;
  1111. case Devswab:
  1112. d = d->swab.d;
  1113. goto loop;
  1114. }
  1115. devinit(d);
  1116. if(top) {
  1117. wlock(&mainlock);
  1118. rootream(d, ROOT_ADDR);
  1119. superream(d, SUPER_ADDR);
  1120. wunlock(&mainlock);
  1121. }
  1122. }
  1123. void
  1124. devrecover(Device *d)
  1125. {
  1126. for (;;) {
  1127. print("recover: %Z\n", d);
  1128. switch(d->type) {
  1129. default:
  1130. print("recover: unknown dev type %Z\n", d);
  1131. return;
  1132. case Devcw:
  1133. wlock(&mainlock); /* recover */
  1134. cwrecover(d);
  1135. wunlock(&mainlock);
  1136. return;
  1137. case Devswab:
  1138. d = d->swab.d;
  1139. break;
  1140. }
  1141. }
  1142. }
  1143. void
  1144. devinit(Device *d)
  1145. {
  1146. for (;;) {
  1147. if(d->init)
  1148. return;
  1149. d->init = 1;
  1150. print("\tdevinit %Z\n", d);
  1151. switch(d->type) {
  1152. default:
  1153. print("devinit unknown device %Z\n", d);
  1154. return;
  1155. case Devro:
  1156. cwinit(d->ro.parent);
  1157. return;
  1158. case Devcw:
  1159. cwinit(d);
  1160. return;
  1161. case Devjuke:
  1162. jukeinit(d);
  1163. return;
  1164. case Devwren:
  1165. wreninit(d);
  1166. return;
  1167. case Devworm:
  1168. case Devlworm:
  1169. return;
  1170. case Devfworm:
  1171. fworminit(d);
  1172. return;
  1173. case Devmcat:
  1174. mcatinit(d);
  1175. return;
  1176. case Devmlev:
  1177. mlevinit(d);
  1178. return;
  1179. case Devmirr:
  1180. mirrinit(d);
  1181. return;
  1182. case Devpart:
  1183. partinit(d);
  1184. return;
  1185. case Devswab:
  1186. d = d->swab.d;
  1187. break;
  1188. case Devnone:
  1189. print("devinit of Devnone\n");
  1190. return;
  1191. }
  1192. }
  1193. }
  1194. void
  1195. swab2(void *c)
  1196. {
  1197. uchar *p;
  1198. int t;
  1199. p = c;
  1200. t = p[0];
  1201. p[0] = p[1];
  1202. p[1] = t;
  1203. }
  1204. void
  1205. swab4(void *c)
  1206. {
  1207. uchar *p;
  1208. int t;
  1209. p = c;
  1210. t = p[0];
  1211. p[0] = p[3];
  1212. p[3] = t;
  1213. t = p[1];
  1214. p[1] = p[2];
  1215. p[2] = t;
  1216. }
  1217. void
  1218. swab8(void *c)
  1219. {
  1220. uchar *p;
  1221. int t;
  1222. p = c;
  1223. t = p[0];
  1224. p[0] = p[7];
  1225. p[7] = t;
  1226. t = p[1];
  1227. p[1] = p[6];
  1228. p[6] = t;
  1229. t = p[2];
  1230. p[2] = p[5];
  1231. p[5] = t;
  1232. t = p[3];
  1233. p[3] = p[4];
  1234. p[4] = t;
  1235. }
  1236. /*
  1237. * swab a block
  1238. * flag = 0 -- convert from foreign to native
  1239. * flag = 1 -- convert from native to foreign
  1240. */
  1241. void
  1242. swab(void *c, int flag)
  1243. {
  1244. uchar *p;
  1245. Tag *t;
  1246. int i, j;
  1247. Dentry *d;
  1248. Cache *h;
  1249. Bucket *b;
  1250. Superb *s;
  1251. Fbuf *f;
  1252. Off *l;
  1253. /* swab the tag */
  1254. p = (uchar*)c;
  1255. t = (Tag*)(p + BUFSIZE);
  1256. if(!flag) {
  1257. swab2(&t->pad);
  1258. swab2(&t->tag);
  1259. swaboff(&t->path);
  1260. }
  1261. /* swab each block type */
  1262. switch(t->tag) {
  1263. default:
  1264. print("no swab for tag=%G rw=%d\n", t->tag, flag);
  1265. for(j=0; j<16; j++)
  1266. print(" %.2x", p[BUFSIZE+j]);
  1267. print("\n");
  1268. for(i=0; i<16; i++) {
  1269. print("%.4x", i*16);
  1270. for(j=0; j<16; j++)
  1271. print(" %.2x", p[i*16+j]);
  1272. print("\n");
  1273. }
  1274. panic("swab");
  1275. break;
  1276. case Tsuper:
  1277. s = (Superb*)p;
  1278. swaboff(&s->fbuf.nfree);
  1279. for(i=0; i<FEPERBUF; i++)
  1280. swaboff(&s->fbuf.free[i]);
  1281. swaboff(&s->fstart);
  1282. swaboff(&s->fsize);
  1283. swaboff(&s->tfree);
  1284. swaboff(&s->qidgen);
  1285. swaboff(&s->cwraddr);
  1286. swaboff(&s->roraddr);
  1287. swaboff(&s->last);
  1288. swaboff(&s->next);
  1289. break;
  1290. case Tdir:
  1291. for(i=0; i<DIRPERBUF; i++) {
  1292. d = (Dentry*)p + i;
  1293. swab2(&d->uid);
  1294. swab2(&d->gid);
  1295. swab2(&d->mode);
  1296. swab2(&d->muid);
  1297. swaboff(&d->qid.path);
  1298. swab4(&d->qid.version);
  1299. swaboff(&d->size);
  1300. for(j=0; j<NDBLOCK; j++)
  1301. swaboff(&d->dblock[j]);
  1302. for (j = 0; j < NIBLOCK; j++)
  1303. swaboff(&d->iblocks[j]);
  1304. swab4(&d->atime);
  1305. swab4(&d->mtime);
  1306. }
  1307. break;
  1308. case Tind1:
  1309. case Tind2:
  1310. #ifndef COMPAT32
  1311. case Tind3:
  1312. case Tind4:
  1313. /* add more Tind tags here ... */
  1314. #endif
  1315. l = (Off *)p;
  1316. for(i=0; i<INDPERBUF; i++) {
  1317. swaboff(l);
  1318. l++;
  1319. }
  1320. break;
  1321. case Tfree:
  1322. f = (Fbuf*)p;
  1323. swaboff(&f->nfree);
  1324. for(i=0; i<FEPERBUF; i++)
  1325. swaboff(&f->free[i]);
  1326. break;
  1327. case Tbuck:
  1328. for(i=0; i<BKPERBLK; i++) {
  1329. b = (Bucket*)p + i;
  1330. swab4(&b->agegen);
  1331. for(j=0; j<CEPERBK; j++) {
  1332. swab2(&b->entry[j].age);
  1333. swab2(&b->entry[j].state);
  1334. swaboff(&b->entry[j].waddr);
  1335. }
  1336. }
  1337. break;
  1338. case Tcache:
  1339. h = (Cache*)p;
  1340. swaboff(&h->maddr);
  1341. swaboff(&h->msize);
  1342. swaboff(&h->caddr);
  1343. swaboff(&h->csize);
  1344. swaboff(&h->fsize);
  1345. swaboff(&h->wsize);
  1346. swaboff(&h->wmax);
  1347. swaboff(&h->sbaddr);
  1348. swaboff(&h->cwraddr);
  1349. swaboff(&h->roraddr);
  1350. swab4(&h->toytime);
  1351. swab4(&h->time);
  1352. break;
  1353. case Tnone: // unitialized
  1354. case Tfile: // someone elses problem
  1355. case Tvirgo: // bit map -- all bytes
  1356. case Tconfig: // configuration string -- all bytes
  1357. break;
  1358. }
  1359. /* swab the tag */
  1360. if(flag) {
  1361. swab2(&t->pad);
  1362. swab2(&t->tag);
  1363. swaboff(&t->path);
  1364. }
  1365. }