sub.c 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541
  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)(uintptr)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)(uintptr)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 ||
  470. #ifndef COMPAT32
  471. tag == Tind3 || tag == Tind4 || /* add more Tind tags here ... */
  472. #endif
  473. tag == Tdir)
  474. bp->flags |= Bimm;
  475. putbuf(bp);
  476. putbuf(p);
  477. return a;
  478. }
  479. /*
  480. * what are legal characters in a name?
  481. * only disallow control characters.
  482. * a) utf avoids control characters.
  483. * b) '/' may not be the separator
  484. */
  485. int
  486. checkname(char *n)
  487. {
  488. int i, c;
  489. for(i=0; i<NAMELEN; i++) {
  490. c = *n & 0xff;
  491. if(c == 0) {
  492. if(i == 0)
  493. return 1;
  494. memset(n, 0, NAMELEN-i);
  495. return 0;
  496. }
  497. if(c <= 040)
  498. return 1;
  499. n++;
  500. }
  501. return 1; /* too long */
  502. }
  503. void
  504. addfree(Device *dev, Off addr, Superb *sb)
  505. {
  506. int n;
  507. Iobuf *p;
  508. n = sb->fbuf.nfree;
  509. if(n < 0 || n > FEPERBUF)
  510. panic("addfree: bad freelist");
  511. if(n >= FEPERBUF) {
  512. p = getbuf(dev, addr, Bmod|Bimm);
  513. if(p == 0)
  514. panic("addfree: getbuf");
  515. *(Fbuf*)p->iobuf = sb->fbuf;
  516. settag(p, Tfree, QPNONE);
  517. putbuf(p);
  518. n = 0;
  519. }
  520. sb->fbuf.free[n++] = addr;
  521. sb->fbuf.nfree = n;
  522. sb->tfree++;
  523. if(addr >= sb->fsize)
  524. sb->fsize = addr+1;
  525. }
  526. /*
  527. static int
  528. Yfmt(Fmt* fmt)
  529. {
  530. Chan *cp;
  531. char s[20];
  532. cp = va_arg(fmt->args, Chan*);
  533. sprint(s, "C%d.%.3d", cp->type, cp->chan);
  534. return fmtstrcpy(fmt, s);
  535. }
  536. */
  537. static int
  538. Zfmt(Fmt* fmt)
  539. {
  540. Device *d;
  541. int c, c1;
  542. char s[100];
  543. d = va_arg(fmt->args, Device*);
  544. if(d == nil) {
  545. sprint(s, "Z***");
  546. goto out;
  547. }
  548. c = c1 = '\0';
  549. switch(d->type) {
  550. default:
  551. sprint(s, "D%d", d->type);
  552. break;
  553. case Devwren:
  554. c = 'w';
  555. /* fallthrough */
  556. case Devworm:
  557. if (c == '\0')
  558. c = 'r';
  559. /* fallthrough */
  560. case Devlworm:
  561. if (c == '\0')
  562. c = 'l';
  563. if(d->wren.ctrl == 0 && d->wren.lun == 0)
  564. sprint(s, "%c%d", c, d->wren.targ);
  565. else
  566. sprint(s, "%c%d.%d.%d", c, d->wren.ctrl, d->wren.targ,
  567. d->wren.lun);
  568. break;
  569. case Devmcat:
  570. c = '(';
  571. c1 = ')';
  572. /* fallthrough */
  573. case Devmlev:
  574. if (c == '\0') {
  575. c = '[';
  576. c1 = ']';
  577. }
  578. /* fallthrough */
  579. case Devmirr:
  580. if (c == '\0') {
  581. c = '{';
  582. c1 = '}';
  583. }
  584. if(d->cat.first == d->cat.last)
  585. sprint(s, "%c%Z%c", c, d->cat.first, c1);
  586. else if(d->cat.first->link == d->cat.last)
  587. sprint(s, "%c%Z%Z%c", c, d->cat.first, d->cat.last, c1);
  588. else
  589. sprint(s, "%c%Z-%Z%c", c, d->cat.first, d->cat.last, c1);
  590. break;
  591. case Devro:
  592. sprint(s, "o%Z%Z", d->ro.parent->cw.c, d->ro.parent->cw.w);
  593. break;
  594. case Devcw:
  595. sprint(s, "c%Z%Z", d->cw.c, d->cw.w);
  596. break;
  597. case Devjuke:
  598. sprint(s, "j%Z%Z", d->j.j, d->j.m);
  599. break;
  600. case Devfworm:
  601. sprint(s, "f%Z", d->fw.fw);
  602. break;
  603. case Devpart:
  604. sprint(s, "p(%Z)%ld.%ld", d->part.d, d->part.base, d->part.size);
  605. break;
  606. case Devswab:
  607. sprint(s, "x%Z", d->swab.d);
  608. break;
  609. case Devnone:
  610. sprint(s, "n");
  611. break;
  612. }
  613. out:
  614. return fmtstrcpy(fmt, s);
  615. }
  616. static int
  617. Gfmt(Fmt* fmt)
  618. {
  619. int t;
  620. char *s;
  621. t = va_arg(fmt->args, int);
  622. s = "<badtag>";
  623. if(t >= 0 && t < MAXTAG)
  624. s = tagnames[t];
  625. return fmtstrcpy(fmt, s);
  626. }
  627. void
  628. formatinit(void)
  629. {
  630. quotefmtinstall();
  631. // fmtinstall('Y', Yfmt); /* print channels */
  632. fmtinstall('Z', Zfmt); /* print devices */
  633. fmtinstall('G', Gfmt); /* print tags */
  634. fmtinstall('T', Tfmt); /* print times */
  635. // fmtinstall('E', eipfmt); /* print ether addresses */
  636. fmtinstall('I', eipfmt); /* print ip addresses */
  637. }
  638. void
  639. rootream(Device *dev, Off addr)
  640. {
  641. Iobuf *p;
  642. Dentry *d;
  643. p = getbuf(dev, addr, Bmod|Bimm);
  644. memset(p->iobuf, 0, RBUFSIZE);
  645. settag(p, Tdir, QPROOT);
  646. d = getdir(p, 0);
  647. strcpy(d->name, "/");
  648. d->uid = -1;
  649. d->gid = -1;
  650. d->mode = DALLOC | DDIR |
  651. ((DREAD|DEXEC) << 6) |
  652. ((DREAD|DEXEC) << 3) |
  653. ((DREAD|DEXEC) << 0);
  654. d->qid = QID9P1(QPROOT|QPDIR,0);
  655. d->atime = time(nil);
  656. d->mtime = d->atime;
  657. d->muid = 0;
  658. putbuf(p);
  659. }
  660. void
  661. superream(Device *dev, Off addr)
  662. {
  663. Iobuf *p;
  664. Superb *s;
  665. Off i;
  666. p = getbuf(dev, addr, Bmod|Bimm);
  667. memset(p->iobuf, 0, RBUFSIZE);
  668. settag(p, Tsuper, QPSUPER);
  669. s = (Superb*)p->iobuf;
  670. s->fstart = 2;
  671. s->fsize = devsize(dev);
  672. s->fbuf.nfree = 1;
  673. s->qidgen = 10;
  674. for(i = s->fsize-1; i >= addr+2; i--)
  675. addfree(dev, i, s);
  676. putbuf(p);
  677. }
  678. struct
  679. {
  680. Lock;
  681. Msgbuf *smsgbuf;
  682. Msgbuf *lmsgbuf;
  683. } msgalloc;
  684. /*
  685. * pre-allocate some message buffers at boot time.
  686. * if this supply is exhausted, more will be allocated as needed.
  687. */
  688. void
  689. mbinit(void)
  690. {
  691. Msgbuf *mb;
  692. Rabuf *rb;
  693. int i;
  694. lock(&msgalloc);
  695. unlock(&msgalloc);
  696. msgalloc.lmsgbuf = 0;
  697. msgalloc.smsgbuf = 0;
  698. for(i=0; i<conf.nlgmsg; i++) {
  699. mb = malloc(sizeof(Msgbuf));
  700. mb->magic = Mbmagic;
  701. mb->xdata = malloc(LARGEBUF+Slop);
  702. mb->flags = LARGE;
  703. mbfree(mb);
  704. cons.nlarge++;
  705. }
  706. for(i=0; i<conf.nsmmsg; i++) {
  707. mb = malloc(sizeof(Msgbuf));
  708. mb->magic = Mbmagic;
  709. mb->xdata = malloc(SMALLBUF+Slop);
  710. mb->flags = 0;
  711. mbfree(mb);
  712. cons.nsmall++;
  713. }
  714. memset(mballocs, 0, sizeof(mballocs));
  715. lock(&rabuflock);
  716. unlock(&rabuflock);
  717. rabuffree = 0;
  718. for(i=0; i<1000; i++) {
  719. rb = malloc(sizeof(*rb));
  720. rb->link = rabuffree;
  721. rabuffree = rb;
  722. }
  723. }
  724. Msgbuf*
  725. mballoc(int count, Chan *cp, int category)
  726. {
  727. Msgbuf *mb;
  728. lock(&msgalloc);
  729. if(count > SMALLBUF) {
  730. if(count > LARGEBUF)
  731. panic("msgbuf count");
  732. mb = msgalloc.lmsgbuf;
  733. if(mb == nil) {
  734. mb = malloc(sizeof(Msgbuf));
  735. mb->xdata = malloc(LARGEBUF+Slop);
  736. cons.nlarge++;
  737. } else
  738. msgalloc.lmsgbuf = mb->next;
  739. mb->flags = LARGE;
  740. } else {
  741. mb = msgalloc.smsgbuf;
  742. if(mb == nil) {
  743. mb = malloc(sizeof(Msgbuf));
  744. mb->xdata = malloc(SMALLBUF+Slop);
  745. cons.nsmall++;
  746. } else
  747. msgalloc.smsgbuf = mb->next;
  748. mb->flags = 0;
  749. }
  750. mballocs[category]++;
  751. unlock(&msgalloc);
  752. mb->magic = Mbmagic;
  753. mb->count = count;
  754. mb->chan = cp;
  755. mb->next = 0;
  756. mb->param = 0;
  757. mb->category = category;
  758. mb->data = mb->xdata+Slop;
  759. return mb;
  760. }
  761. void
  762. mbfree(Msgbuf *mb)
  763. {
  764. if(mb == nil)
  765. return;
  766. assert(mb->magic == Mbmagic);
  767. if (mb->magic != Mbmagic)
  768. panic("mbfree: bad magic 0x%lux", mb->magic);
  769. if(mb->flags & BTRACE)
  770. print("mbfree: BTRACE cat=%d flags=%ux, caller %#p\n",
  771. mb->category, mb->flags, getcallerpc(&mb));
  772. if(mb->flags & FREE)
  773. panic("mbfree already free");
  774. lock(&msgalloc);
  775. mballocs[mb->category]--;
  776. mb->flags |= FREE;
  777. if(mb->flags & LARGE) {
  778. mb->next = msgalloc.lmsgbuf;
  779. msgalloc.lmsgbuf = mb;
  780. } else {
  781. mb->next = msgalloc.smsgbuf;
  782. msgalloc.smsgbuf = mb;
  783. }
  784. mb->data = 0;
  785. mb->magic = 0;
  786. unlock(&msgalloc);
  787. }
  788. /*
  789. * returns 1 if n is prime
  790. * used for adjusting lengths
  791. * of hashing things.
  792. * there is no need to be clever
  793. */
  794. int
  795. prime(vlong n)
  796. {
  797. long i;
  798. if((n%2) == 0)
  799. return 0;
  800. for(i=3;; i+=2) {
  801. if((n%i) == 0)
  802. return 0;
  803. if((vlong)i*i >= n)
  804. return 1;
  805. }
  806. }
  807. char*
  808. getwrd(char *word, char *line)
  809. {
  810. int c, n;
  811. while(isascii(*line) && isspace(*line) && *line != '\n')
  812. line++;
  813. for(n = 0; n < Maxword; n++) {
  814. c = *line;
  815. if(c == '\0' || isascii(c) && isspace(c))
  816. break;
  817. line++;
  818. *word++ = c;
  819. }
  820. *word = 0;
  821. return line;
  822. }
  823. void
  824. hexdump(void *a, int n)
  825. {
  826. char s1[30], s2[4];
  827. uchar *p;
  828. int i;
  829. p = a;
  830. s1[0] = 0;
  831. for(i = 0; i < n; i++) {
  832. sprint(s2, " %.2ux", p[i]);
  833. strcat(s1, s2);
  834. if((i&7) == 7) {
  835. print("%s\n", s1);
  836. s1[0] = 0;
  837. }
  838. }
  839. if(s1[0])
  840. print("%s\n", s1);
  841. }
  842. void*
  843. fs_recv(Queue *q, int)
  844. {
  845. void *a;
  846. int i, c;
  847. if(q == nil)
  848. panic("recv null q");
  849. qlock(q);
  850. q->waitedfor = 1;
  851. while((c = q->count) <= 0)
  852. rsleep(&q->empty);
  853. i = q->loc;
  854. a = q->args[i];
  855. i++;
  856. if(i >= q->size)
  857. i = 0;
  858. q->loc = i;
  859. q->count = c-1;
  860. rwakeup(&q->full); /* no longer full */
  861. qunlock(q);
  862. return a;
  863. }
  864. void
  865. fs_send(Queue *q, void *a)
  866. {
  867. int i, c;
  868. if(q == nil)
  869. panic("send null q");
  870. if(!q->waitedfor) {
  871. for (i = 0; i < 5 && !q->waitedfor; i++)
  872. sleep(1000);
  873. if(!q->waitedfor) {
  874. /* likely a bug; don't wait forever */
  875. print("no readers yet for %s q\n", q->name);
  876. abort();
  877. }
  878. }
  879. qlock(q);
  880. while((c = q->count) >= q->size)
  881. rsleep(&q->full);
  882. i = q->loc + c;
  883. if(i >= q->size)
  884. i -= q->size;
  885. q->args[i] = a;
  886. q->count = c+1;
  887. rwakeup(&q->empty); /* no longer empty */
  888. qunlock(q);
  889. }
  890. Queue*
  891. newqueue(int size, char *name)
  892. {
  893. Queue *q;
  894. q = malloc(sizeof(Queue) + (size-1)*sizeof(void*));
  895. q->size = size;
  896. q->full.l = q->empty.l = &q->QLock;
  897. q->name = name;
  898. return q;
  899. }
  900. int
  901. devread(Device *d, Off b, void *c)
  902. {
  903. int e;
  904. for (;;)
  905. switch(d->type) {
  906. case Devcw:
  907. return cwread(d, b, c);
  908. case Devjuke:
  909. d = d->j.m;
  910. break;
  911. case Devro:
  912. return roread(d, b, c);
  913. case Devwren:
  914. return wrenread(d, b, c);
  915. case Devworm:
  916. case Devlworm:
  917. return wormread(d, b, c);
  918. case Devfworm:
  919. return fwormread(d, b, c);
  920. case Devmcat:
  921. return mcatread(d, b, c);
  922. case Devmlev:
  923. return mlevread(d, b, c);
  924. case Devmirr:
  925. return mirrread(d, b, c);
  926. case Devpart:
  927. return partread(d, b, c);
  928. case Devswab:
  929. e = devread(d->swab.d, b, c);
  930. if(e == 0)
  931. swab(c, 0);
  932. return e;
  933. case Devnone:
  934. print("read from device none(%lld)\n", (Wideoff)b);
  935. return 1;
  936. default:
  937. panic("illegal device in devread: %Z %lld",
  938. d, (Wideoff)b);
  939. return 1;
  940. }
  941. }
  942. int
  943. devwrite(Device *d, Off b, void *c)
  944. {
  945. int e;
  946. /*
  947. * set readonly to non-0 to prevent all writes;
  948. * mainly for trying dangerous experiments.
  949. */
  950. if (readonly)
  951. return 0;
  952. for (;;)
  953. switch(d->type) {
  954. case Devcw:
  955. return cwwrite(d, b, c);
  956. case Devjuke:
  957. d = d->j.m;
  958. break;
  959. case Devro:
  960. print("write to ro device %Z(%lld)\n", d, (Wideoff)b);
  961. return 1;
  962. case Devwren:
  963. return wrenwrite(d, b, c);
  964. case Devworm:
  965. case Devlworm:
  966. return wormwrite(d, b, c);
  967. case Devfworm:
  968. return fwormwrite(d, b, c);
  969. case Devmcat:
  970. return mcatwrite(d, b, c);
  971. case Devmlev:
  972. return mlevwrite(d, b, c);
  973. case Devmirr:
  974. return mirrwrite(d, b, c);
  975. case Devpart:
  976. return partwrite(d, b, c);
  977. case Devswab:
  978. swab(c, 1);
  979. e = devwrite(d->swab.d, b, c);
  980. swab(c, 0);
  981. return e;
  982. case Devnone:
  983. /* checktag() can generate blocks with type devnone */
  984. return 0;
  985. default:
  986. panic("illegal device in devwrite: %Z %lld",
  987. d, (Wideoff)b);
  988. return 1;
  989. }
  990. }
  991. Devsize
  992. devsize(Device *d)
  993. {
  994. for (;;)
  995. switch(d->type) {
  996. case Devcw:
  997. case Devro:
  998. return cwsize(d);
  999. case Devjuke:
  1000. d = d->j.m;
  1001. break;
  1002. case Devwren:
  1003. return wrensize(d);
  1004. case Devworm:
  1005. case Devlworm:
  1006. return wormsize(d);
  1007. case Devfworm:
  1008. return fwormsize(d);
  1009. case Devmcat:
  1010. return mcatsize(d);
  1011. case Devmlev:
  1012. return mlevsize(d);
  1013. case Devmirr:
  1014. return mirrsize(d);
  1015. case Devpart:
  1016. return partsize(d);
  1017. case Devswab:
  1018. d = d->swab.d;
  1019. break;
  1020. default:
  1021. panic("illegal device in devsize: %Z", d);
  1022. return 0;
  1023. }
  1024. }
  1025. /* result is malloced */
  1026. char *
  1027. sdof(Device *d)
  1028. {
  1029. static char name[256];
  1030. for (;;)
  1031. switch(d->type) {
  1032. case Devjuke:
  1033. d = d->j.j; /* robotics */
  1034. break;
  1035. case Devwren:
  1036. snprint(name, sizeof name, "/dev/sd%d%d", d->wren.ctrl,
  1037. d->wren.targ);
  1038. return strdup(name);
  1039. case Devswab:
  1040. d = d->swab.d;
  1041. break;
  1042. default:
  1043. panic("illegal device in sdof: %Z", d);
  1044. return nil;
  1045. }
  1046. }
  1047. Off
  1048. superaddr(Device *d)
  1049. {
  1050. for (;;)
  1051. switch(d->type) {
  1052. default:
  1053. return SUPER_ADDR;
  1054. case Devcw:
  1055. case Devro:
  1056. return cwsaddr(d);
  1057. case Devswab:
  1058. d = d->swab.d;
  1059. break;
  1060. }
  1061. }
  1062. Off
  1063. getraddr(Device *d)
  1064. {
  1065. for (;;)
  1066. switch(d->type) {
  1067. default:
  1068. return ROOT_ADDR;
  1069. case Devcw:
  1070. case Devro:
  1071. return cwraddr(d);
  1072. case Devswab:
  1073. d = d->swab.d;
  1074. break;
  1075. }
  1076. }
  1077. void
  1078. devream(Device *d, int top)
  1079. {
  1080. Device *l;
  1081. loop:
  1082. print("\tdevream: %Z %d\n", d, top);
  1083. switch(d->type) {
  1084. default:
  1085. print("ream: unknown dev type %Z\n", d);
  1086. return;
  1087. case Devcw:
  1088. devream(d->cw.w, 0);
  1089. devream(d->cw.c, 0);
  1090. if(top) {
  1091. wlock(&mainlock);
  1092. cwream(d);
  1093. wunlock(&mainlock);
  1094. }
  1095. devinit(d);
  1096. return;
  1097. case Devfworm:
  1098. devream(d->fw.fw, 0);
  1099. fwormream(d);
  1100. break;
  1101. case Devpart:
  1102. devream(d->part.d, 0);
  1103. break;
  1104. case Devmlev:
  1105. case Devmcat:
  1106. case Devmirr:
  1107. for(l=d->cat.first; l; l=l->link)
  1108. devream(l, 0);
  1109. break;
  1110. case Devjuke:
  1111. case Devworm:
  1112. case Devlworm:
  1113. case Devwren:
  1114. break;
  1115. case Devswab:
  1116. d = d->swab.d;
  1117. goto loop;
  1118. }
  1119. devinit(d);
  1120. if(top) {
  1121. wlock(&mainlock);
  1122. rootream(d, ROOT_ADDR);
  1123. superream(d, SUPER_ADDR);
  1124. wunlock(&mainlock);
  1125. }
  1126. }
  1127. void
  1128. devrecover(Device *d)
  1129. {
  1130. for (;;) {
  1131. print("recover: %Z\n", d);
  1132. switch(d->type) {
  1133. default:
  1134. print("recover: unknown dev type %Z\n", d);
  1135. return;
  1136. case Devcw:
  1137. wlock(&mainlock); /* recover */
  1138. cwrecover(d);
  1139. wunlock(&mainlock);
  1140. return;
  1141. case Devswab:
  1142. d = d->swab.d;
  1143. break;
  1144. }
  1145. }
  1146. }
  1147. void
  1148. devinit(Device *d)
  1149. {
  1150. for (;;) {
  1151. if(d->init)
  1152. return;
  1153. d->init = 1;
  1154. print("\tdevinit %Z\n", d);
  1155. switch(d->type) {
  1156. default:
  1157. print("devinit unknown device %Z\n", d);
  1158. return;
  1159. case Devro:
  1160. cwinit(d->ro.parent);
  1161. return;
  1162. case Devcw:
  1163. cwinit(d);
  1164. return;
  1165. case Devjuke:
  1166. jukeinit(d);
  1167. return;
  1168. case Devwren:
  1169. wreninit(d);
  1170. return;
  1171. case Devworm:
  1172. case Devlworm:
  1173. return;
  1174. case Devfworm:
  1175. fworminit(d);
  1176. return;
  1177. case Devmcat:
  1178. mcatinit(d);
  1179. return;
  1180. case Devmlev:
  1181. mlevinit(d);
  1182. return;
  1183. case Devmirr:
  1184. mirrinit(d);
  1185. return;
  1186. case Devpart:
  1187. partinit(d);
  1188. return;
  1189. case Devswab:
  1190. d = d->swab.d;
  1191. break;
  1192. case Devnone:
  1193. print("devinit of Devnone\n");
  1194. return;
  1195. }
  1196. }
  1197. }
  1198. void
  1199. swab2(void *c)
  1200. {
  1201. uchar *p;
  1202. int t;
  1203. p = c;
  1204. t = p[0];
  1205. p[0] = p[1];
  1206. p[1] = t;
  1207. }
  1208. void
  1209. swab4(void *c)
  1210. {
  1211. uchar *p;
  1212. int t;
  1213. p = c;
  1214. t = p[0];
  1215. p[0] = p[3];
  1216. p[3] = t;
  1217. t = p[1];
  1218. p[1] = p[2];
  1219. p[2] = t;
  1220. }
  1221. void
  1222. swab8(void *c)
  1223. {
  1224. uchar *p;
  1225. int t;
  1226. p = c;
  1227. t = p[0];
  1228. p[0] = p[7];
  1229. p[7] = t;
  1230. t = p[1];
  1231. p[1] = p[6];
  1232. p[6] = t;
  1233. t = p[2];
  1234. p[2] = p[5];
  1235. p[5] = t;
  1236. t = p[3];
  1237. p[3] = p[4];
  1238. p[4] = t;
  1239. }
  1240. /*
  1241. * swab a block
  1242. * flag = 0 -- convert from foreign to native
  1243. * flag = 1 -- convert from native to foreign
  1244. */
  1245. void
  1246. swab(void *c, int flag)
  1247. {
  1248. uchar *p;
  1249. Tag *t;
  1250. int i, j;
  1251. Dentry *d;
  1252. Cache *h;
  1253. Bucket *b;
  1254. Superb *s;
  1255. Fbuf *f;
  1256. Off *l;
  1257. /* swab the tag */
  1258. p = (uchar*)c;
  1259. t = (Tag*)(p + BUFSIZE);
  1260. if(!flag) {
  1261. swab2(&t->pad);
  1262. swab2(&t->tag);
  1263. swaboff(&t->path);
  1264. }
  1265. /* swab each block type */
  1266. switch(t->tag) {
  1267. default:
  1268. print("no swab for tag=%G rw=%d\n", t->tag, flag);
  1269. for(j=0; j<16; j++)
  1270. print(" %.2x", p[BUFSIZE+j]);
  1271. print("\n");
  1272. for(i=0; i<16; i++) {
  1273. print("%.4x", i*16);
  1274. for(j=0; j<16; j++)
  1275. print(" %.2x", p[i*16+j]);
  1276. print("\n");
  1277. }
  1278. panic("swab");
  1279. break;
  1280. case Tsuper:
  1281. s = (Superb*)p;
  1282. swaboff(&s->fbuf.nfree);
  1283. for(i=0; i<FEPERBUF; i++)
  1284. swaboff(&s->fbuf.free[i]);
  1285. swaboff(&s->fstart);
  1286. swaboff(&s->fsize);
  1287. swaboff(&s->tfree);
  1288. swaboff(&s->qidgen);
  1289. swaboff(&s->cwraddr);
  1290. swaboff(&s->roraddr);
  1291. swaboff(&s->last);
  1292. swaboff(&s->next);
  1293. break;
  1294. case Tdir:
  1295. for(i=0; i<DIRPERBUF; i++) {
  1296. d = (Dentry*)p + i;
  1297. swab2(&d->uid);
  1298. swab2(&d->gid);
  1299. swab2(&d->mode);
  1300. swab2(&d->muid);
  1301. swaboff(&d->qid.path);
  1302. swab4(&d->qid.version);
  1303. swaboff(&d->size);
  1304. for(j=0; j<NDBLOCK; j++)
  1305. swaboff(&d->dblock[j]);
  1306. for (j = 0; j < NIBLOCK; j++)
  1307. swaboff(&d->iblocks[j]);
  1308. swab4(&d->atime);
  1309. swab4(&d->mtime);
  1310. }
  1311. break;
  1312. case Tind1:
  1313. case Tind2:
  1314. #ifndef COMPAT32
  1315. case Tind3:
  1316. case Tind4:
  1317. /* add more Tind tags here ... */
  1318. #endif
  1319. l = (Off *)p;
  1320. for(i=0; i<INDPERBUF; i++) {
  1321. swaboff(l);
  1322. l++;
  1323. }
  1324. break;
  1325. case Tfree:
  1326. f = (Fbuf*)p;
  1327. swaboff(&f->nfree);
  1328. for(i=0; i<FEPERBUF; i++)
  1329. swaboff(&f->free[i]);
  1330. break;
  1331. case Tbuck:
  1332. for(i=0; i<BKPERBLK; i++) {
  1333. b = (Bucket*)p + i;
  1334. swab4(&b->agegen);
  1335. for(j=0; j<CEPERBK; j++) {
  1336. swab2(&b->entry[j].age);
  1337. swab2(&b->entry[j].state);
  1338. swaboff(&b->entry[j].waddr);
  1339. }
  1340. }
  1341. break;
  1342. case Tcache:
  1343. h = (Cache*)p;
  1344. swaboff(&h->maddr);
  1345. swaboff(&h->msize);
  1346. swaboff(&h->caddr);
  1347. swaboff(&h->csize);
  1348. swaboff(&h->fsize);
  1349. swaboff(&h->wsize);
  1350. swaboff(&h->wmax);
  1351. swaboff(&h->sbaddr);
  1352. swaboff(&h->cwraddr);
  1353. swaboff(&h->roraddr);
  1354. swab4(&h->toytime);
  1355. swab4(&h->time);
  1356. break;
  1357. case Tnone: // unitialized
  1358. case Tfile: // someone elses problem
  1359. case Tvirgo: // bit map -- all bytes
  1360. case Tconfig: // configuration string -- all bytes
  1361. break;
  1362. }
  1363. /* swab the tag */
  1364. if(flag) {
  1365. swab2(&t->pad);
  1366. swab2(&t->tag);
  1367. swaboff(&t->path);
  1368. }
  1369. }