9p.c 3.3 KB

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