1 #include "all.h" 2 #include "9p1.h" 3 4 void 5 fcall9p1(Chan *cp, Oldfcall *in, Oldfcall *ou) 6 { 7 int t; 8 9 rlock(&mainlock); 10 t = in->type; 11 if(t < 0 || t >= MAXSYSCALL || (t&1) || !call9p1[t]) { 12 print("bad message type %d\n", t); 13 panic(""); 14 } 15 ou->type = t+1; 16 ou->err = 0; 17 18 rlock(&cp->reflock); 19 (*call9p1[t])(cp, in, ou); 20 runlock(&cp->reflock); 21 22 if(ou->err) 23 if(CHAT(cp)) 24 print(" error: %s\n", errstring[ou->err]); 25 cons.work.count++; 26 runlock(&mainlock); 27 } 28 29 int 30 con_session(void) 31 { 32 Oldfcall in, ou; 33 34 in.type = Tsession9p1; 35 fcall9p1(cons.chan, &in, &ou); 36 return ou.err; 37 } 38 39 int 40 con_attach(int fid, char *uid, char *arg) 41 { 42 Oldfcall in, ou; 43 44 in.type = Tattach9p1; 45 in.fid = fid; 46 strncpy(in.uname, uid, NAMELEN); 47 strncpy(in.aname, arg, NAMELEN); 48 fcall9p1(cons.chan, &in, &ou); 49 return ou.err; 50 } 51 52 int 53 con_clone(int fid1, int fid2) 54 { 55 Oldfcall in, ou; 56 57 in.type = Tclone9p1; 58 in.fid = fid1; 59 in.newfid = fid2; 60 fcall9p1(cons.chan, &in, &ou); 61 return ou.err; 62 } 63 64 int 65 con_path(int fid, char *path) 66 { 67 Oldfcall in, ou; 68 char *p; 69 70 in.type = Twalk9p1; 71 in.fid = fid; 72 73 loop: 74 if(*path == 0) 75 return 0; 76 strncpy(in.name, path, NAMELEN); 77 if(p = strchr(path, '/')) { 78 path = p+1; 79 if(p = strchr(in.name, '/')) 80 *p = 0; 81 } else 82 path = strchr(path, 0); 83 if(in.name[0]) { 84 fcall9p1(cons.chan, &in, &ou); 85 if(ou.err) 86 return ou.err; 87 } 88 goto loop; 89 } 90 91 int 92 con_walk(int fid, char *name) 93 { 94 Oldfcall in, ou; 95 96 in.type = Twalk9p1; 97 in.fid = fid; 98 strncpy(in.name, name, NAMELEN); 99 fcall9p1(cons.chan, &in, &ou); 100 return ou.err; 101 } 102 103 int 104 con_stat(int fid, char *data) 105 { 106 Oldfcall in, ou; 107 108 in.type = Tstat9p1; 109 in.fid = fid; 110 fcall9p1(cons.chan, &in, &ou); 111 if(ou.err == 0) 112 memmove(data, ou.stat, sizeof ou.stat); 113 return ou.err; 114 } 115 116 int 117 con_wstat(int fid, char *data) 118 { 119 Oldfcall in, ou; 120 121 in.type = Twstat9p1; 122 in.fid = fid; 123 memmove(in.stat, data, sizeof in.stat); 124 fcall9p1(cons.chan, &in, &ou); 125 return ou.err; 126 } 127 128 int 129 con_open(int fid, int mode) 130 { 131 Oldfcall in, ou; 132 133 in.type = Topen9p1; 134 in.fid = fid; 135 in.mode = mode; 136 fcall9p1(cons.chan, &in, &ou); 137 return ou.err; 138 } 139 140 int 141 con_read(int fid, char *data, long offset, int count) 142 { 143 Oldfcall in, ou; 144 145 in.type = Tread9p1; 146 in.fid = fid; 147 in.offset = offset; 148 in.count = count; 149 ou.data = data; 150 fcall9p1(cons.chan, &in, &ou); 151 if(ou.err) 152 return 0; 153 return ou.count; 154 } 155 156 int 157 con_write(int fid, char *data, long offset, int count) 158 { 159 Oldfcall in, ou; 160 161 in.type = Twrite9p1; 162 in.fid = fid; 163 in.data = data; 164 in.offset = offset; 165 in.count = count; 166 fcall9p1(cons.chan, &in, &ou); 167 if(ou.err) 168 return 0; 169 return ou.count; 170 } 171 172 int 173 con_remove(int fid) 174 { 175 Oldfcall in, ou; 176 177 in.type = Tremove9p1; 178 in.fid = fid; 179 fcall9p1(cons.chan, &in, &ou); 180 return ou.err; 181 } 182 183 int 184 con_create(int fid, char *name, int uid, int gid, long perm, int mode) 185 { 186 Oldfcall in, ou; 187 188 in.type = Tcreate9p1; 189 in.fid = fid; 190 strncpy(in.name, name, NAMELEN); 191 in.perm = perm; 192 in.mode = mode; 193 cons.uid = uid; /* beyond ugly */ 194 cons.gid = gid; 195 fcall9p1(cons.chan, &in, &ou); 196 return ou.err; 197 } 198 199 int 200 doclri(File *f) 201 { 202 Iobuf *p, *p1; 203 Dentry *d, *d1; 204 int err; 205 206 err = 0; 207 p = 0; 208 p1 = 0; 209 if(isro(f->fs->dev)) { 210 err = Eronly; 211 goto out; 212 } 213 /* 214 * check on parent directory of file to be deleted 215 */ 216 if(f->wpath == 0 || f->wpath->addr == f->addr) { 217 err = Ephase; 218 goto out; 219 } 220 p1 = getbuf(f->fs->dev, f->wpath->addr, Bread); 221 d1 = getdir(p1, f->wpath->slot); 222 if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) { 223 err = Ephase; 224 goto out; 225 } 226 227 accessdir(p1, d1, FWRITE); 228 putbuf(p1); 229 p1 = 0; 230 231 /* 232 * check on file to be deleted 233 */ 234 p = getbuf(f->fs->dev, f->addr, Bread); 235 d = getdir(p, f->slot); 236 237 238 /* 239 * do it 240 */ 241 memset(d, 0, sizeof(Dentry)); 242 settag(p, Tdir, QPNONE); 243 freewp(f->wpath); 244 freefp(f); 245 246 out: 247 if(p1) 248 putbuf(p1); 249 if(p) 250 putbuf(p); 251 return err; 252 } 253 254 void 255 f_clri(Chan *cp, Oldfcall *in, Oldfcall *ou) 256 { 257 File *f; 258 259 if(CHAT(cp)) { 260 print("c_clri %d\n", cp->chan); 261 print(" fid = %d\n", in->fid); 262 } 263 264 f = filep(cp, in->fid, 0); 265 if(!f) { 266 ou->err = Efid; 267 goto out; 268 } 269 ou->err = doclri(f); 270 271 out: 272 ou->fid = in->fid; 273 if(f) 274 qunlock(f); 275 } 276 277 int 278 con_clri(int fid) 279 { 280 Oldfcall in, ou; 281 Chan *cp; 282 283 in.type = Tremove9p1; 284 in.fid = fid; 285 cp = cons.chan; 286 287 rlock(&mainlock); 288 ou.type = Tremove9p1+1; 289 ou.err = 0; 290 291 rlock(&cp->reflock); 292 293 f_clri(cp, &in, &ou); 294 295 runlock(&cp->reflock); 296 297 cons.work.count++; 298 runlock(&mainlock); 299 return ou.err; 300 } 301 302 int 303 con_swap(int fid1, int fid2) 304 { 305 int err; 306 Iobuf *p1, *p2; 307 File *f1, *f2; 308 Dentry *d1, *d2; 309 Dentry dt1, dt2; 310 Chan *cp; 311 312 cp = cons.chan; 313 err = 0; 314 rlock(&mainlock); 315 rlock(&cp->reflock); 316 317 f2 = nil; 318 p1 = p2 = nil; 319 f1 = filep(cp, fid1, 0); 320 if(!f1){ 321 err = Efid; 322 goto out; 323 } 324 p1 = getbuf(f1->fs->dev, f1->addr, Bread|Bmod); 325 d1 = getdir(p1, f1->slot); 326 if(!d1 || !(d1->mode&DALLOC)){ 327 err = Ealloc; 328 goto out; 329 } 330 331 f2 = filep(cp, fid2, 0); 332 if(!f2){ 333 err = Efid; 334 goto out; 335 } 336 if(memcmp(&f1->fs->dev, &f2->fs->dev, 4)==0 337 && f2->addr == f1->addr) 338 p2 = p1; 339 else 340 p2 = getbuf(f2->fs->dev, f2->addr, Bread|Bmod); 341 d2 = getdir(p2, f2->slot); 342 if(!d2 || !(d2->mode&DALLOC)){ 343 err = Ealloc; 344 goto out; 345 } 346 347 dt1 = *d1; 348 dt2 = *d2; 349 *d1 = dt2; 350 *d2 = dt1; 351 memmove(d1->name, dt1.name, NAMELEN); 352 memmove(d2->name, dt2.name, NAMELEN); 353 354 mkqid(&f1->qid, d1, 1); 355 mkqid(&f2->qid, d2, 1); 356 out: 357 if(f1) 358 qunlock(f1); 359 if(f2) 360 qunlock(f2); 361 if(p1) 362 putbuf(p1); 363 if(p2 && p2!=p1) 364 putbuf(p2); 365 366 runlock(&cp->reflock); 367 cons.work.count++; 368 runlock(&mainlock); 369 370 return err; 371 } 372