inode.c 6.8 KB

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