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