sub.c 24 KB

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