dentry.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #include "all.h"
  2. Dentry*
  3. getdir(Iobuf *p, int slot)
  4. {
  5. Dentry *d;
  6. if(!p)
  7. return 0;
  8. d = (Dentry*)p->iobuf + slot%DIRPERBUF;
  9. return d;
  10. }
  11. void
  12. accessdir(Iobuf *p, Dentry *d, int f)
  13. {
  14. long t;
  15. if(p && !isro(p->dev)) {
  16. if(!(f & (FWRITE|FWSTAT)) && noatime)
  17. return;
  18. t = time(nil);
  19. if(f & (FREAD|FWRITE|FWSTAT)){
  20. d->atime = t;
  21. p->flags |= Bmod;
  22. }
  23. if(f & FWRITE) {
  24. d->mtime = t;
  25. d->qid.version++;
  26. p->flags |= Bmod;
  27. }
  28. }
  29. }
  30. void
  31. dbufread(Iobuf *p, Dentry *d, long a)
  32. {
  33. USED(p, d, a);
  34. }
  35. long
  36. rel2abs(Iobuf *p, Dentry *d, long a, int tag, int putb)
  37. {
  38. long addr, qpath;
  39. Device dev;
  40. if(a < 0) {
  41. print("dnodebuf: neg\n");
  42. return 0;
  43. }
  44. qpath = d->qid.path;
  45. dev = p->dev;
  46. if(a < NDBLOCK) {
  47. addr = d->dblock[a];
  48. if(!addr && tag) {
  49. addr = balloc(dev, tag, qpath);
  50. d->dblock[a] = addr;
  51. p->flags |= Bmod|Bimm;
  52. }
  53. if(putb)
  54. putbuf(p);
  55. return addr;
  56. }
  57. a -= NDBLOCK;
  58. if(a < INDPERBUF) {
  59. addr = d->iblock;
  60. if(!addr && tag) {
  61. addr = balloc(dev, Tind1, qpath);
  62. d->iblock = addr;
  63. p->flags |= Bmod|Bimm;
  64. }
  65. if(putb)
  66. putbuf(p);
  67. addr = indfetch(p, d, addr, a, Tind1, tag);
  68. return addr;
  69. }
  70. a -= INDPERBUF;
  71. if(a < INDPERBUF2) {
  72. addr = d->diblock;
  73. if(!addr && tag) {
  74. addr = balloc(dev, Tind2, qpath);
  75. d->diblock = addr;
  76. p->flags |= Bmod|Bimm;
  77. }
  78. if(putb)
  79. putbuf(p);
  80. addr = indfetch(p, d, addr, a/INDPERBUF, Tind2, Tind1);
  81. addr = indfetch(p, d, addr, a%INDPERBUF, Tind1, tag);
  82. return addr;
  83. }
  84. if(putb)
  85. putbuf(p);
  86. print("dnodebuf: trip indirect\n");
  87. return 0;
  88. }
  89. Iobuf*
  90. dnodebuf(Iobuf *p, Dentry *d, long a, int tag)
  91. {
  92. long addr;
  93. addr = rel2abs(p, d, a, tag, 0);
  94. if(addr)
  95. return getbuf(p->dev, addr, Bread);
  96. return 0;
  97. }
  98. /*
  99. * same as dnodebuf but it calls putpuf(p)
  100. * to reduce interference.
  101. */
  102. Iobuf*
  103. dnodebuf1(Iobuf *p, Dentry *d, long a, int tag)
  104. {
  105. long addr;
  106. Device dev;
  107. dev = p->dev;
  108. addr = rel2abs(p, d, a, tag, 1);
  109. if(addr)
  110. return getbuf(dev, addr, Bread);
  111. return 0;
  112. }
  113. long
  114. indfetch(Iobuf *p, Dentry *d, long addr, long a, int itag, int tag)
  115. {
  116. Iobuf *bp;
  117. if(!addr)
  118. return 0;
  119. bp = getbuf(p->dev, addr, Bread);
  120. if(!bp || checktag(bp, itag, d->qid.path)) {
  121. if(!bp) {
  122. print("ind fetch bp = 0\n");
  123. return 0;
  124. }
  125. print("ind fetch tag\n");
  126. putbuf(bp);
  127. return 0;
  128. }
  129. addr = ((long*)bp->iobuf)[a];
  130. if(!addr && tag) {
  131. addr = balloc(p->dev, tag, d->qid.path);
  132. if(addr) {
  133. ((long*)bp->iobuf)[a] = addr;
  134. bp->flags |= Bmod;
  135. if(localfs || tag == Tdir)
  136. bp->flags |= Bimm;
  137. settag(bp, itag, d->qid.path);
  138. }
  139. }
  140. putbuf(bp);
  141. return addr;
  142. }
  143. void
  144. dtrunc(Iobuf *p, Dentry *d)
  145. {
  146. int i;
  147. bfree(p->dev, d->diblock, 2);
  148. d->diblock = 0;
  149. bfree(p->dev, d->iblock, 1);
  150. d->iblock = 0;
  151. for(i=NDBLOCK-1; i>=0; i--) {
  152. bfree(p->dev, d->dblock[i], 0);
  153. d->dblock[i] = 0;
  154. }
  155. d->size = 0;
  156. p->flags |= Bmod|Bimm;
  157. accessdir(p, d, FWRITE);
  158. }