inode.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  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 <u.h>
  10. #include <libc.h>
  11. #include "cformat.h"
  12. #include "lru.h"
  13. #include "bcache.h"
  14. #include "disk.h"
  15. #include "inode.h"
  16. #include "stats.h"
  17. /*
  18. * read the inode blocks and make sure they
  19. * haven't been trashed.
  20. *
  21. * make the in-core table of qid to inode mappings.
  22. * N.B. this is just an array. we need a linear search to find
  23. * a particular inode. this could be done faster.
  24. *
  25. * nab is the first inode block.
  26. */
  27. int
  28. iinit(Icache *ic, int f, int psize, char* name)
  29. {
  30. Ibuf *b;
  31. Imap *m;
  32. uint32_t ino;
  33. Bbuf *bb;
  34. Dinode *bi;
  35. /*
  36. * get basic sizes and allocation info from disk
  37. */
  38. if(dinit(ic, f, psize, name) < 0)
  39. return -1;
  40. /*
  41. * read first inode block to get number of inodes
  42. */
  43. bb = bcread(ic, ic->nab);
  44. if(bb == 0){
  45. fprint(2, "iinit: can't read disk\n");
  46. return -1;
  47. }
  48. bi = (Dinode*)bb->data;
  49. if(bi->nino==0 || bi->nino>2048){
  50. fprint(2, "iinit: bad nino\n");
  51. return -1;
  52. }
  53. ic->nino = bi->nino;
  54. /*
  55. * set up sizing constants
  56. */
  57. ic->i2b = (ic->bsize - sizeof(Dihdr))/sizeof(Inode);
  58. ic->nib = (ic->nino + ic->i2b - 1)/ic->i2b;
  59. /*
  60. * allocate the in-core qid/inode map, build it's lru
  61. */
  62. if(ic->map)
  63. free(ic->map);
  64. ic->map = malloc(sizeof(Imap)*ic->nino);
  65. if(ic->map == 0){
  66. fprint(2, "iinit: can't alloc map\n");
  67. return -1;
  68. }
  69. lruinit(&ic->mlru);
  70. for(m = ic->map; m < &ic->map[ic->nino]; m++){
  71. m->inuse = 0;
  72. m->b = 0;
  73. lruadd(&ic->mlru, m);
  74. }
  75. /*
  76. * mark all cache buffers as empty, put them on the lru list
  77. */
  78. lruinit(&ic->blru);
  79. for(b = ic->ib; b < &ic->ib[Nicache]; b++){
  80. b->inuse = 0;
  81. lruadd(&ic->blru, b);
  82. }
  83. /*
  84. * Read all inodes and
  85. * build the in-core qid/inode map
  86. */
  87. for(ino = 0; ino < ic->nino; ino++){
  88. b = iread(ic, ino);
  89. if(b == 0){
  90. fprint(2, "iinit: can't read inode %ld\n", ino);
  91. return -1;
  92. }
  93. if(b->inode.inuse){
  94. m = &ic->map[ino];
  95. m->inuse = 1;
  96. m->qid = b->inode.qid;
  97. lruref(&ic->mlru, m);
  98. }
  99. }
  100. return 0;
  101. }
  102. /*
  103. * format the inode blocks
  104. */
  105. int
  106. iformat(Icache *ic, int f, uint32_t nino, char *name, int bsize,
  107. int psize)
  108. {
  109. int nib;
  110. uint32_t bno, i2b, i;
  111. Bbuf *bb;
  112. Dinode *bi;
  113. /*
  114. * first format disk allocation
  115. */
  116. if(dformat(ic, f, name, bsize, psize) < 0)
  117. return -1;
  118. fprint(2, "formatting inodes\n");
  119. i2b = (bsize - sizeof(Dihdr))/sizeof(Inode);
  120. nib = (nino + i2b - 1)/i2b;
  121. for(bno = ic->nab; bno < ic->nab + nib; bno++){
  122. if(dalloc(ic, 0) == Notabno){
  123. fprint(2, "iformat: balloc failed\n");
  124. return -1;
  125. }
  126. bb = bcalloc(ic, bno);
  127. if(bb == 0){
  128. fprint(2, "iformat: bcalloc failed\n");
  129. return -1;
  130. }
  131. bi = (Dinode*)bb->data;
  132. bi->magic = Imagic;
  133. bi->nino = nino;
  134. for(i = 0; i < i2b; i++)
  135. bi->inode[i].inuse = 0;
  136. bcmark(ic, bb);
  137. }
  138. bcsync(ic);
  139. return iinit(ic, f, psize, name);
  140. }
  141. /*
  142. * allocate a cache buffer, use least recently used
  143. */
  144. Ibuf*
  145. ialloc(Icache *ic, uint32_t ino)
  146. {
  147. Imap *m;
  148. Ibuf *b;
  149. b = (Ibuf*)ic->blru.lnext;
  150. if(b->inuse)
  151. ic->map[b->ino].b = 0;
  152. b->ino = ino;
  153. b->inuse = 1;
  154. m = &ic->map[ino];
  155. m->b = b;
  156. return b;
  157. }
  158. /*
  159. * free a cache buffer
  160. */
  161. void
  162. ifree(Icache *ic, Ibuf *b)
  163. {
  164. b->inuse = 0;
  165. if(b->inuse)
  166. ic->map[b->ino].b = 0;
  167. lruderef(&ic->blru, b);
  168. }
  169. /*
  170. * get an inode into the cache. if no inode exists for this qid, create one
  171. * from an unused qid/inode map.
  172. */
  173. Ibuf *
  174. iget(Icache *ic, Qid qid)
  175. {
  176. Imap *m, *me;
  177. Ibuf *b;
  178. /*
  179. * find map entry with same qid.path
  180. */
  181. for(m = ic->map, me = &ic->map[ic->nino]; m < me; m++)
  182. if(m->inuse && m->qid.path==qid.path){
  183. if(m->qid.vers != qid.vers){
  184. /*
  185. * our info is old, forget it
  186. */
  187. DPRINT(2, "updating old file %llu.%lu\n",
  188. qid.path, qid.vers);
  189. m->qid = qid;
  190. iupdate(ic, m - ic->map, qid);
  191. }
  192. break;
  193. }
  194. /*
  195. * if an already existing inode, just get it
  196. */
  197. if(m != me)
  198. return iread(ic, m - ic->map);
  199. /*
  200. * create a new inode, throw out the least recently used inode
  201. * if necessary
  202. */
  203. m = (Imap*)ic->mlru.lnext;
  204. if(m->inuse){
  205. DPRINT(2, "superceding file %llu.%ld by %llu.%ld\n",
  206. m->qid.path, m->qid.vers, qid.path, qid.vers);
  207. if(iremove(ic, m - ic->map) < 0)
  208. return 0;
  209. }
  210. if(statson)
  211. cfsstat.ninsert++;
  212. /*
  213. * init inode and write to disk
  214. */
  215. DPRINT(2, "new file %llu.%ld ino %ld\n",
  216. qid.path, qid.vers, m - ic->map);
  217. b = ialloc(ic, m - ic->map);
  218. b->inode.inuse = m->inuse = 1;
  219. b->inode.qid = qid;
  220. b->inode.length = 0x7fffffffffffffffLL;
  221. m->qid = qid;
  222. b->inode.ptr.bno = Notabno;
  223. iwrite(ic, b);
  224. return b;
  225. }
  226. /*
  227. * read an inode into the cache
  228. *
  229. * ASSUMPTION: the inode is valid
  230. */
  231. Ibuf*
  232. iread(Icache *ic, uint32_t ino)
  233. {
  234. Ibuf *b;
  235. Imap *m;
  236. uint32_t bno;
  237. Bbuf *bb;
  238. Dinode *bi;
  239. /*
  240. * first see if we already have it in a cache entry
  241. */
  242. m = &ic->map[ino];
  243. if(m->inuse && m->b){
  244. b = m->b;
  245. goto out;
  246. }
  247. /*
  248. * read it
  249. */
  250. b = ialloc(ic, ino);
  251. bno = ic->nab + ino/ic->i2b;
  252. bb = bcread(ic, bno);
  253. if(bb == 0){
  254. ifree(ic, b);
  255. return 0;
  256. }
  257. bi = (Dinode*)bb->data;
  258. b->inode = bi->inode[ino % ic->i2b];
  259. /*
  260. * consistency check
  261. */
  262. if(bi->nino!=ic->nino || bi->magic!=Imagic){
  263. fprint(2, "iread: inconsistent inode block\n");
  264. ifree(ic, b);
  265. return 0;
  266. }
  267. out:
  268. b->inuse = 1;
  269. m->b = b;
  270. if(b->inode.inuse)
  271. lruref(&ic->mlru, m);
  272. lruref(&ic->blru, b);
  273. return b;
  274. }
  275. /*
  276. * write an inode back to disk
  277. */
  278. int
  279. iwrite(Icache *ic, Ibuf *b)
  280. {
  281. uint32_t bno;
  282. Bbuf *bb;
  283. Dinode *bi;
  284. bno = ic->nab + b->ino/ic->i2b;
  285. bb = bcread(ic, bno);
  286. if(bb == 0)
  287. return 0;
  288. bi = (Dinode*)bb->data;
  289. bi->inode[b->ino % ic->i2b] = b->inode;
  290. bcmark(ic, bb);
  291. lruref(&ic->mlru, &ic->map[b->ino]);
  292. lruref(&ic->blru, b);
  293. return 0;
  294. }
  295. /*
  296. * Forget what we know about an inode without removing it
  297. *
  298. * N.B: ordering of iwrite and dfree is important
  299. */
  300. int
  301. iupdate(Icache *ic, uint32_t ino, Qid qid)
  302. {
  303. Ibuf *b;
  304. Imap *m;
  305. Dptr d;
  306. if(statson)
  307. cfsstat.nupdate++;
  308. b = iread(ic, ino);
  309. if(b == 0)
  310. return -1;
  311. /*
  312. * update inode and map
  313. */
  314. b->inode.qid = qid;
  315. b->inode.length = 0x7fffffffffffffffLL; /* Set to maximum */
  316. m = &ic->map[ino];
  317. m->qid = qid;
  318. /*
  319. * the free is not done if the write fails!
  320. * this is important
  321. */
  322. d = b->inode.ptr;
  323. b->inode.ptr.bno = Notabno;
  324. if(iwrite(ic, b) < 0)
  325. return -1;
  326. dfree(ic, &d);
  327. return 0;
  328. }
  329. /*
  330. * remove an inode
  331. *
  332. * N.B: ordering of iwrite and dfree is important
  333. */
  334. int
  335. iremove(Icache *ic, uint32_t ino)
  336. {
  337. Ibuf *b;
  338. Imap *m;
  339. if(statson)
  340. cfsstat.ndelete++;
  341. m = &ic->map[ino];
  342. /*
  343. * read in inode
  344. */
  345. b = iread(ic, ino);
  346. if(b == 0)
  347. return -1;
  348. /*
  349. * mark it unused on disk
  350. */
  351. b->inode.inuse = 0;
  352. if(iwrite(ic, b) < 0)
  353. return -1;
  354. /*
  355. * throw out it's data pages
  356. */
  357. dfree(ic, &b->inode.ptr);
  358. /*
  359. * free the inode buffer
  360. */
  361. ifree(ic, b);
  362. /*
  363. * make map entry least recently used
  364. */
  365. lruderef(&ic->mlru, m);
  366. return 0;
  367. }
  368. /*
  369. * increment our version number
  370. */
  371. void
  372. iinc(Icache *ic, Ibuf *b)
  373. {
  374. b->inode.qid.vers++;
  375. ic->map[b->ino].qid = b->inode.qid;
  376. iwrite(ic, b);
  377. }