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