1 #include "all.h" 2 3 void 4 p9fcall(Chan *cp, Fcall *in, Fcall *ou) 5 { 6 int t; 7 8 rlock(&mainlock); 9 t = in->type; 10 if(t < 0 || t >= MAXSYSCALL || (t&1) || !p9call[t]) { 11 print("bad message type %d\n", t); 12 panic(""); 13 } 14 ou->type = t+1; 15 ou->err = 0; 16 17 rlock(&cp->reflock); 18 19 (*p9call[t])(cp, in, ou); 20 21 runlock(&cp->reflock); 22 23 cons.work.count++; 24 runlock(&mainlock); 25 } 26 27 int 28 con_session(void) 29 { 30 Fcall in, ou; 31 32 in.type = Tsession; 33 p9fcall(cons.chan, &in, &ou); 34 return ou.err; 35 } 36 37 int 38 con_attach(int fid, char *uid, char *arg) 39 { 40 Fcall in, ou; 41 42 in.type = Tattach; 43 in.fid = fid; 44 strncpy(in.uname, uid, NAMELEN); 45 strncpy(in.aname, arg, NAMELEN); 46 p9fcall(cons.chan, &in, &ou); 47 return ou.err; 48 } 49 50 int 51 con_clone(int fid1, int fid2) 52 { 53 Fcall in, ou; 54 55 in.type = Tclone; 56 in.fid = fid1; 57 in.newfid = fid2; 58 p9fcall(cons.chan, &in, &ou); 59 return ou.err; 60 } 61 62 int 63 con_path(int fid, char *path) 64 { 65 Fcall in, ou; 66 char *p; 67 68 in.type = Twalk; 69 in.fid = fid; 70 71 loop: 72 if(*path == 0) 73 return 0; 74 strncpy(in.name, path, NAMELEN); 75 if(p = strchr(path, '/')) { 76 path = p+1; 77 if(p = strchr(in.name, '/')) 78 *p = 0; 79 } else 80 path = strchr(path, 0); 81 if(in.name[0]) { 82 p9fcall(cons.chan, &in, &ou); 83 if(ou.err) 84 return ou.err; 85 } 86 goto loop; 87 } 88 89 int 90 con_walk(int fid, char *name) 91 { 92 Fcall in, ou; 93 94 in.type = Twalk; 95 in.fid = fid; 96 strncpy(in.name, name, NAMELEN); 97 p9fcall(cons.chan, &in, &ou); 98 return ou.err; 99 } 100 101 int 102 con_stat(int fid, char *data) 103 { 104 Fcall in, ou; 105 106 in.type = Tstat; 107 in.fid = fid; 108 p9fcall(cons.chan, &in, &ou); 109 if(ou.err == 0) 110 memmove(data, ou.stat, sizeof ou.stat); 111 return ou.err; 112 } 113 114 int 115 con_wstat(int fid, char *data) 116 { 117 Fcall in, ou; 118 119 in.type = Twstat; 120 in.fid = fid; 121 memmove(in.stat, data, sizeof in.stat); 122 p9fcall(cons.chan, &in, &ou); 123 return ou.err; 124 } 125 126 int 127 con_open(int fid, int mode) 128 { 129 Fcall in, ou; 130 131 in.type = Topen; 132 in.fid = fid; 133 in.mode = mode; 134 p9fcall(cons.chan, &in, &ou); 135 return ou.err; 136 } 137 138 int 139 con_read(int fid, char *data, long offset, int count) 140 { 141 Fcall in, ou; 142 143 in.type = Tread; 144 in.fid = fid; 145 in.offset = offset; 146 in.count = count; 147 ou.data = data; 148 p9fcall(cons.chan, &in, &ou); 149 if(ou.err) 150 return 0; 151 return ou.count; 152 } 153 154 int 155 con_write(int fid, char *data, long offset, int count) 156 { 157 Fcall in, ou; 158 159 in.type = Twrite; 160 in.fid = fid; 161 in.data = data; 162 in.offset = offset; 163 in.count = count; 164 p9fcall(cons.chan, &in, &ou); 165 if(ou.err) 166 return 0; 167 return ou.count; 168 } 169 170 int 171 con_remove(int fid) 172 { 173 Fcall in, ou; 174 175 in.type = Tremove; 176 in.fid = fid; 177 p9fcall(cons.chan, &in, &ou); 178 return ou.err; 179 } 180 181 int 182 con_create(int fid, char *name, int uid, int gid, long perm, int mode) 183 { 184 Fcall in, ou; 185 186 in.type = Tcreate; 187 in.fid = fid; 188 strncpy(in.name, name, NAMELEN); 189 in.perm = perm; 190 in.mode = mode; 191 cons.uid = uid; /* beyond ugly */ 192 cons.gid = gid; 193 p9fcall(cons.chan, &in, &ou); 194 return ou.err; 195 } 196 197 int 198 doclri(File *f) 199 { 200 Iobuf *p, *p1; 201 Dentry *d, *d1; 202 int err; 203 204 err = 0; 205 p = 0; 206 p1 = 0; 207 if(isro(f->fs->dev)) { 208 err = Eronly; 209 goto out; 210 } 211 /* 212 * check on parent directory of file to be deleted 213 */ 214 if(f->wpath == 0 || f->wpath->addr == f->addr) { 215 err = Ephase; 216 goto out; 217 } 218 p1 = getbuf(f->fs->dev, f->wpath->addr, Bread); 219 d1 = getdir(p1, f->wpath->slot); 220 if(!d1 || checktag(p1, Tdir, QPNONE) || !(d1->mode & DALLOC)) { 221 err = Ephase; 222 goto out; 223 } 224 225 accessdir(p1, d1, FWRITE); 226 putbuf(p1); 227 p1 = 0; 228 229 /* 230 * check on file to be deleted 231 */ 232 p = getbuf(f->fs->dev, f->addr, Bread); 233 d = getdir(p, f->slot); 234 235 236 /* 237 * do it 238 */ 239 memset(d, 0, sizeof(Dentry)); 240 settag(p, Tdir, QPNONE); 241 freewp(f->wpath); 242 freefp(f); 243 244 out: 245 if(p1) 246 putbuf(p1); 247 if(p) 248 putbuf(p); 249 return err; 250 } 251 252 void 253 f_clri(Chan *cp, Fcall *in, Fcall *ou) 254 { 255 File *f; 256 257 if(CHAT(cp)) { 258 print("c_clri %d\n", cp->chan); 259 print(" fid = %d\n", in->fid); 260 } 261 262 f = filep(cp, in->fid, 0); 263 if(!f) { 264 ou->err = Efid; 265 goto out; 266 } 267 ou->err = doclri(f); 268 269 out: 270 ou->fid = in->fid; 271 if(f) 272 qunlock(f); 273 } 274 275 int 276 con_clri(int fid) 277 { 278 Fcall in, ou; 279 Chan *cp; 280 281 in.type = Tremove; 282 in.fid = fid; 283 cp = cons.chan; 284 285 rlock(&mainlock); 286 ou.type = Tremove+1; 287 ou.err = 0; 288 289 rlock(&cp->reflock); 290 291 f_clri(cp, &in, &ou); 292 293 runlock(&cp->reflock); 294 295 cons.work.count++; 296 runlock(&mainlock); 297 return ou.err; 298 } 299