inode.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  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, char* name)
  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, name) < 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. int nib;
  101. ulong bno, i2b, i;
  102. Bbuf *bb;
  103. Dinode *bi;
  104. /*
  105. * first format disk allocation
  106. */
  107. if(dformat(ic, f, name, bsize, psize) < 0)
  108. return -1;
  109. fprint(2, "formatting inodes\n");
  110. i2b = (bsize - sizeof(Dihdr))/sizeof(Inode);
  111. nib = (nino + i2b - 1)/i2b;
  112. for(bno = ic->nab; bno < ic->nab + nib; bno++){
  113. if(dalloc(ic, 0) == Notabno){
  114. fprint(2, "iformat: balloc failed\n");
  115. return -1;
  116. }
  117. bb = bcalloc(ic, bno);
  118. if(bb == 0){
  119. fprint(2, "iformat: bcalloc failed\n");
  120. return -1;
  121. }
  122. bi = (Dinode*)bb->data;
  123. bi->magic = Imagic;
  124. bi->nino = nino;
  125. for(i = 0; i < i2b; i++)
  126. bi->inode[i].inuse = 0;
  127. bcmark(ic, bb);
  128. }
  129. bcsync(ic);
  130. return iinit(ic, f, psize, name);
  131. }
  132. /*
  133. * allocate a cache buffer, use least recently used
  134. */
  135. Ibuf*
  136. ialloc(Icache *ic, ulong ino)
  137. {
  138. Imap *m;
  139. Ibuf *b;
  140. b = (Ibuf*)ic->blru.lnext;
  141. if(b->inuse)
  142. ic->map[b->ino].b = 0;
  143. b->ino = ino;
  144. b->inuse = 1;
  145. m = &ic->map[ino];
  146. m->b = b;
  147. return b;
  148. }
  149. /*
  150. * free a cache buffer
  151. */
  152. void
  153. ifree(Icache *ic, Ibuf *b)
  154. {
  155. b->inuse = 0;
  156. if(b->inuse)
  157. ic->map[b->ino].b = 0;
  158. lruderef(&ic->blru, b);
  159. }
  160. /*
  161. * get an inode into the cache. if no inode exists for this qid, create one
  162. * from an unused qid/inode map.
  163. */
  164. Ibuf *
  165. iget(Icache *ic, Qid qid)
  166. {
  167. Imap *m, *me;
  168. Ibuf *b;
  169. /*
  170. * find map entry with same qid.path
  171. */
  172. for(m = ic->map, me = &ic->map[ic->nino]; m < me; m++)
  173. if(m->inuse && m->qid.path==qid.path){
  174. if(m->qid.vers != qid.vers){
  175. /*
  176. * our info is old, forget it
  177. */
  178. DPRINT(2, "updating old file %llud.%lud\n",
  179. qid.path, qid.vers);
  180. m->qid = qid;
  181. iupdate(ic, m - ic->map, qid);
  182. }
  183. break;
  184. }
  185. /*
  186. * if an already existing inode, just get it
  187. */
  188. if(m != me)
  189. return iread(ic, m - ic->map);
  190. /*
  191. * create a new inode, throw out the least recently used inode
  192. * if necessary
  193. */
  194. m = (Imap*)ic->mlru.lnext;
  195. if(m->inuse){
  196. DPRINT(2, "superceding file %llud.%ld by %llud.%ld\n",
  197. m->qid.path, m->qid.vers, qid.path, qid.vers);
  198. if(iremove(ic, m - ic->map) < 0)
  199. return 0;
  200. }
  201. if(statson)
  202. cfsstat.ninsert++;
  203. /*
  204. * init inode and write to disk
  205. */
  206. DPRINT(2, "new file %llud.%ld ino %ld\n",
  207. qid.path, qid.vers, m - ic->map);
  208. b = ialloc(ic, m - ic->map);
  209. b->inode.inuse = m->inuse = 1;
  210. b->inode.qid = qid;
  211. b->inode.length = 0x7fffffffffffffffLL;
  212. m->qid = qid;
  213. b->inode.ptr.bno = Notabno;
  214. iwrite(ic, b);
  215. return b;
  216. }
  217. /*
  218. * read an inode into the cache
  219. *
  220. * ASSUMPTION: the inode is valid
  221. */
  222. Ibuf*
  223. iread(Icache *ic, ulong ino)
  224. {
  225. Ibuf *b;
  226. Imap *m;
  227. ulong bno;
  228. Bbuf *bb;
  229. Dinode *bi;
  230. /*
  231. * first see if we already have it in a cache entry
  232. */
  233. m = &ic->map[ino];
  234. if(m->inuse && m->b){
  235. b = m->b;
  236. goto out;
  237. }
  238. /*
  239. * read it
  240. */
  241. b = ialloc(ic, ino);
  242. bno = ic->nab + ino/ic->i2b;
  243. bb = bcread(ic, bno);
  244. if(bb == 0){
  245. ifree(ic, b);
  246. return 0;
  247. }
  248. bi = (Dinode*)bb->data;
  249. b->inode = bi->inode[ino % ic->i2b];
  250. /*
  251. * consistency check
  252. */
  253. if(bi->nino!=ic->nino || bi->magic!=Imagic){
  254. fprint(2, "iread: inconsistent inode block\n");
  255. ifree(ic, b);
  256. return 0;
  257. }
  258. out:
  259. b->inuse = 1;
  260. m->b = b;
  261. if(b->inode.inuse)
  262. lruref(&ic->mlru, m);
  263. lruref(&ic->blru, b);
  264. return b;
  265. }
  266. /*
  267. * write an inode back to disk
  268. */
  269. int
  270. iwrite(Icache *ic, Ibuf *b)
  271. {
  272. ulong bno;
  273. Bbuf *bb;
  274. Dinode *bi;
  275. bno = ic->nab + b->ino/ic->i2b;
  276. bb = bcread(ic, bno);
  277. if(bb == 0)
  278. return 0;
  279. bi = (Dinode*)bb->data;
  280. bi->inode[b->ino % ic->i2b] = b->inode;
  281. bcmark(ic, bb);
  282. lruref(&ic->mlru, &ic->map[b->ino]);
  283. lruref(&ic->blru, b);
  284. return 0;
  285. }
  286. /*
  287. * Forget what we know about an inode without removing it
  288. *
  289. * N.B: ordering of iwrite and dfree is important
  290. */
  291. int
  292. iupdate(Icache *ic, ulong ino, Qid qid)
  293. {
  294. Ibuf *b;
  295. Imap *m;
  296. Dptr d;
  297. if(statson)
  298. cfsstat.nupdate++;
  299. b = iread(ic, ino);
  300. if(b == 0)
  301. return -1;
  302. /*
  303. * update inode and map
  304. */
  305. b->inode.qid = qid;
  306. b->inode.length = 0x7fffffffffffffffLL; /* Set to maximum */
  307. m = &ic->map[ino];
  308. m->qid = qid;
  309. /*
  310. * the free is not done if the write fails!
  311. * this is important
  312. */
  313. d = b->inode.ptr;
  314. b->inode.ptr.bno = Notabno;
  315. if(iwrite(ic, b) < 0)
  316. return -1;
  317. dfree(ic, &d);
  318. return 0;
  319. }
  320. /*
  321. * remove an inode
  322. *
  323. * N.B: ordering of iwrite and dfree is important
  324. */
  325. int
  326. iremove(Icache *ic, ulong ino)
  327. {
  328. Ibuf *b;
  329. Imap *m;
  330. if(statson)
  331. cfsstat.ndelete++;
  332. m = &ic->map[ino];
  333. /*
  334. * read in inode
  335. */
  336. b = iread(ic, ino);
  337. if(b == 0)
  338. return -1;
  339. /*
  340. * mark it unused on disk
  341. */
  342. b->inode.inuse = 0;
  343. if(iwrite(ic, b) < 0)
  344. return -1;
  345. /*
  346. * throw out it's data pages
  347. */
  348. dfree(ic, &b->inode.ptr);
  349. /*
  350. * free the inode buffer
  351. */
  352. ifree(ic, b);
  353. /*
  354. * make map entry least recently used
  355. */
  356. lruderef(&ic->mlru, m);
  357. return 0;
  358. }
  359. /*
  360. * increment our version number
  361. */
  362. void
  363. iinc(Icache *ic, Ibuf *b)
  364. {
  365. b->inode.qid.vers++;
  366. ic->map[b->ino].qid = b->inode.qid;
  367. iwrite(ic, b);
  368. }