]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/9nfs/9p.c
9bootfat: rename open() to fileinit and make it static as its really a internal funct...
[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                 clog("xmesg read error: %r\n");
45                 return -1;
46         }
47         if(convM2S(s->data, n, &s->f) <= 0){
48                 clog("xmesg bad convM2S %d %.2x %.2x %.2x %.2x\n",
49                         n, ((uchar*)s->data)[0], ((uchar*)s->data)[1],
50                         ((uchar*)s->data)[2], ((uchar*)s->data)[3]);
51                 return -1;
52         }
53         if(p9debug)
54                 fprint(2, "\trecv %F\n", &s->f);
55         if(s->f.tag != s->tag){
56                 clog("xmesg tag %d for %d\n", s->f.tag, s->tag);
57                 goto again;
58         }
59         if(s->f.type == Rerror){
60                 if(t == Tclunk)
61                         clog("xmesg clunk: %s", s->f.ename);
62                 chat("xmesg %d error %s...", t, s->f.ename);
63                 return -1;
64         }
65         if(s->f.type != t+1){
66                 clog("xmesg type mismatch: %d, expected %d\n", s->f.type, t+1);
67                 return -1;
68         }
69         return 0;
70 }
71
72 int
73 clunkfid(Session *s, Fid *f)
74 {
75         putfid(s, f);
76         if(s == 0 || f == 0)
77                 return 0;
78         s->f.fid = f - s->fids;
79         return xmesg(s, Tclunk);
80 }
81
82 #define UNLINK(p)       ((p)->prev->next = (p)->next, (p)->next->prev = (p)->prev)
83
84 #define LINK(h, p)      ((p)->next = (h)->next, (p)->prev = (h), \
85                          (h)->next->prev = (p), (h)->next = (p))
86
87 #define TOFRONT(h, p)   ((h)->next != (p) ? (UNLINK(p), LINK(h,p)) : 0)
88
89 Fid *
90 newfid(Session *s)
91 {
92         Fid *f, *fN;
93
94         chat("newfid..");
95         if(s->list.prev == 0){
96                 chat("init..");
97                 s->list.prev = &s->list;
98                 s->list.next = &s->list;
99                 s->free = s->fids;
100                 if(0 && chatty)
101                         fN = &s->fids[25];
102                 else
103                         fN = &s->fids[nelem(s->fids)];
104                 for(f=s->fids; f<fN; f++){
105                         f->owner = 0;
106                         f->prev = 0;
107                         f->next = f+1;
108                 }
109                 (f-1)->next = 0;
110         }
111         if(s->free){
112                 f = s->free;
113                 s->free = f->next;
114                 LINK(&s->list, f);
115         }else{
116                 for(f=s->list.prev; f!=&s->list; f=f->prev)
117                         if(f->owner)
118                                 break;
119                 if(f == &s->list){
120                         clog("fid leak");
121                         return 0;
122                 }
123                 setfid(s, f);
124                 if(xmesg(s, Tclunk) < 0){
125                         clog("clunk failed, no fids?");
126                         /*return 0;*/
127                 }
128                 *(f->owner) = 0;
129                 f->owner = 0;
130         }
131         chat("%ld...", f - s->fids);
132         f->tstale = nfstime + staletime;
133         return f;
134 }
135
136 void
137 setfid(Session *s, Fid *f)
138 {
139         /*
140          * TOFRONT(&s->list, f);
141          */
142         if(s->list.next != f){
143                 UNLINK(f);
144                 LINK(&s->list, f);
145         }
146
147         f->tstale = nfstime + staletime;
148         s->f.fid = f - s->fids;
149 }
150
151 void
152 putfid(Session *s, Fid *f)
153 {
154         chat("putfid %ld...", f-s->fids);
155         if(s == 0 || f == 0){
156                 clog("putfid(0x%p, 0x%p) %s", s, f, (s ? s->service : "?"));
157                 return;
158         }
159         UNLINK(f);
160         if(f->owner)
161                 *(f->owner) = 0;
162         f->owner = 0;
163         f->prev = 0;
164         f->next = s->free;
165         s->free = f;
166 }
167
168 void
169 fidtimer(Session *s, long now)
170 {
171         Fid *f, *t;
172         int n;
173
174         f = s->list.next;
175         n = 0;
176         while(f != &s->list){
177                 t = f;
178                 f = f->next;
179                 if(t->owner && now >= t->tstale)
180                         ++n, clunkfid(s, t);
181         }
182         if(n > 0)
183                 chat("fidtimer %s\n", s->service);
184 }