sub.c 23 KB

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