9p.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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. static char *tnames[] = {
  11. [Tversion] "version",
  12. [Tauth] "auth",
  13. [Tattach] "attach",
  14. [Tflush] "flush",
  15. [Twalk] "walk",
  16. [Topen] "open",
  17. [Tcreate] "create",
  18. [Tread] "read",
  19. [Twrite] "write",
  20. [Tclunk] "clunk",
  21. [Tremove] "remove",
  22. [Tstat] "stat",
  23. [Twstat] "wstat",
  24. };
  25. int messagesize = IOHDRSZ+Maxfdata;
  26. int
  27. xmesg(Session *s, int t)
  28. {
  29. int n;
  30. if(chatty){
  31. if(0 <= t && t < nelem(tnames) && tnames[t])
  32. chat("T%s...", tnames[t]);
  33. else
  34. chat("T%d...", t);
  35. }
  36. s->f.type = t;
  37. s->f.tag = ++s->tag;
  38. if(p9debug)
  39. fprint(2, "xmseg\tsend %F\n", &s->f);
  40. n = convS2M(&s->f, s->data, messagesize);
  41. if(niwrite(s->fd, s->data, n) != n){
  42. clog("xmesg write error on %d: %r\n", s->fd);
  43. return -1;
  44. }
  45. again:
  46. n = read9pmsg(s->fd, s->data, messagesize);
  47. if(n < 0){
  48. clog("xmesg read error: %r\n");
  49. return -1;
  50. }
  51. if(convM2S(s->data, n, &s->f) <= 0){
  52. clog("xmesg bad convM2S %d %.2x %.2x %.2x %.2x\n",
  53. n, ((uint8_t*)s->data)[0], ((uint8_t*)s->data)[1],
  54. ((uint8_t*)s->data)[2], ((uint8_t*)s->data)[3]);
  55. return -1;
  56. }
  57. if(p9debug)
  58. fprint(2, "\trecv %F\n", &s->f);
  59. if(s->f.tag != s->tag){
  60. clog("xmesg tag %d for %d\n", s->f.tag, s->tag);
  61. goto again;
  62. }
  63. if(s->f.type == Rerror){
  64. if(t == Tclunk)
  65. clog("xmesg clunk: %s", s->f.ename);
  66. chat("xmesg %d error %s...", t, s->f.ename);
  67. return -1;
  68. }
  69. if(s->f.type != t+1){
  70. clog("xmesg type mismatch: %d, expected %d\n", s->f.type, t+1);
  71. return -1;
  72. }
  73. return 0;
  74. }
  75. int
  76. clunkfid(Session *s, Fid *f)
  77. {
  78. putfid(s, f);
  79. if(s == 0 || f == 0)
  80. return 0;
  81. s->f.fid = f - s->fids;
  82. return xmesg(s, Tclunk);
  83. }
  84. #define UNLINK(p) ((p)->prev->next = (p)->next, (p)->next->prev = (p)->prev)
  85. #define LINK(h, p) ((p)->next = (h)->next, (p)->prev = (h), \
  86. (h)->next->prev = (p), (h)->next = (p))
  87. #define TOFRONT(h, p) ((h)->next != (p) ? (UNLINK(p), LINK(h,p)) : 0)
  88. Fid *
  89. newfid(Session *s)
  90. {
  91. Fid *f, *fN;
  92. chat("newfid..");
  93. if(s->list.prev == 0){
  94. chat("init..");
  95. s->list.prev = &s->list;
  96. s->list.next = &s->list;
  97. s->free = s->fids;
  98. if(0 && chatty)
  99. fN = &s->fids[25];
  100. else
  101. fN = &s->fids[nelem(s->fids)];
  102. for(f=s->fids; f<fN; f++){
  103. f->owner = 0;
  104. f->prev = 0;
  105. f->next = f+1;
  106. }
  107. (f-1)->next = 0;
  108. }
  109. if(s->free){
  110. f = s->free;
  111. s->free = f->next;
  112. LINK(&s->list, f);
  113. }else{
  114. for(f=s->list.prev; f!=&s->list; f=f->prev)
  115. if(f->owner)
  116. break;
  117. if(f == &s->list){
  118. clog("fid leak");
  119. return 0;
  120. }
  121. setfid(s, f);
  122. if(xmesg(s, Tclunk) < 0){
  123. clog("clunk failed, no fids?");
  124. /*return 0;*/
  125. }
  126. *(f->owner) = 0;
  127. f->owner = 0;
  128. }
  129. chat("%ld...", f - s->fids);
  130. f->tstale = nfstime + staletime;
  131. return f;
  132. }
  133. void
  134. setfid(Session *s, Fid *f)
  135. {
  136. /*
  137. * TOFRONT(&s->list, f);
  138. */
  139. if(s->list.next != f){
  140. UNLINK(f);
  141. LINK(&s->list, f);
  142. }
  143. f->tstale = nfstime + staletime;
  144. s->f.fid = f - s->fids;
  145. }
  146. void
  147. putfid(Session *s, Fid *f)
  148. {
  149. chat("putfid %ld...", f-s->fids);
  150. if(s == 0 || f == 0){
  151. clog("putfid(0x%p, 0x%p) %s", s, f, (s ? s->service : "?"));
  152. return;
  153. }
  154. UNLINK(f);
  155. if(f->owner)
  156. *(f->owner) = 0;
  157. f->owner = 0;
  158. f->prev = 0;
  159. f->next = s->free;
  160. s->free = f;
  161. }
  162. void
  163. fidtimer(Session *s, int32_t now)
  164. {
  165. Fid *f, *t;
  166. int n;
  167. f = s->list.next;
  168. n = 0;
  169. while(f != &s->list){
  170. t = f;
  171. f = f->next;
  172. if(t->owner && now >= t->tstale)
  173. ++n, clunkfid(s, t);
  174. }
  175. if(n > 0)
  176. chat("fidtimer %s\n", s->service);
  177. }