request.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <auth.h>
  4. #include <fcall.h>
  5. #include <thread.h>
  6. #include <9p.h>
  7. #include "flashfs.h"
  8. static Srv flashsrv;
  9. typedef struct State State;
  10. struct State
  11. {
  12. Entry *e;
  13. Dirr *r;
  14. };
  15. #define writeable(e) ((e)->mode & 0222)
  16. static State *
  17. state(Entry *e)
  18. {
  19. State *s;
  20. s = emalloc9p(sizeof(State));
  21. s->e = e;
  22. s->r = nil;
  23. return s;
  24. }
  25. static void
  26. destroy(Fid *f)
  27. {
  28. State *s;
  29. s = f->aux;
  30. if(s == nil) /* Tauth fids have no state */
  31. return;
  32. f->aux = nil;
  33. if(s->e)
  34. edestroy(s->e);
  35. if(s->r)
  36. edirclose(s->r);
  37. free(s);
  38. }
  39. static void
  40. trace(Req *)
  41. {
  42. edump();
  43. }
  44. /** T_ **/
  45. static void
  46. flattach(Req *r)
  47. {
  48. root->ref++;
  49. r->ofcall.qid = eqid(root);
  50. r->fid->qid = r->ofcall.qid;
  51. r->fid->aux = state(root);
  52. respond(r, nil);
  53. }
  54. static void
  55. flopen(Req *r)
  56. {
  57. Jrec j;
  58. int m, p;
  59. Entry *e;
  60. State *s;
  61. char *err;
  62. s = r->fid->aux;
  63. e = s->e;
  64. m = e->mode;
  65. m = (m | (m >> 3) | (m >> 6)) & 7;
  66. switch(r->ifcall.mode & 3) {
  67. case OREAD:
  68. p = AREAD;
  69. break;
  70. case OWRITE:
  71. p = AWRITE;
  72. break;
  73. case ORDWR:
  74. p = AREAD|AWRITE;
  75. break;
  76. case OEXEC:
  77. p = AEXEC;
  78. break;
  79. default:
  80. p = 0;
  81. break;
  82. }
  83. if((p & m) != p) {
  84. respond(r, Eperm);
  85. return;
  86. }
  87. if(readonly && (p & AWRITE) != 0) {
  88. respond(r, Erofs);
  89. return;
  90. }
  91. r->ofcall.qid = eqid(e);
  92. if(r->ofcall.qid.type & QTDIR) {
  93. if((p & AWRITE) != 0) {
  94. respond(r, Eisdir);
  95. return;
  96. }
  97. s->r = ediropen(s->e);
  98. }
  99. else if(r->ifcall.mode & OTRUNC) {
  100. err = need(Ntrunc);
  101. if(err != nil) {
  102. respond(r, err);
  103. return;
  104. }
  105. j.type = FT_trunc;
  106. j.tnum = e->fnum;
  107. j.mtime = now();
  108. etrunc(e, 0, j.mtime);
  109. j.fnum = e->fnum;
  110. j.parent = e->parent->fnum;
  111. j.mode = e->mode;
  112. strcpy(j.name, e->name);
  113. put(&j, 1);
  114. }
  115. respond(r, nil);
  116. }
  117. static void
  118. flcreate(Req *r)
  119. {
  120. Jrec j;
  121. State *s;
  122. char *err;
  123. Entry *e, *f;
  124. if(readonly) {
  125. respond(r, Erofs);
  126. return;
  127. }
  128. s = r->fid->aux;
  129. e = s->e;
  130. if((e->mode & DMDIR) == 0) {
  131. respond(r, Eisdir);
  132. return;
  133. }
  134. if(!writeable(e)) {
  135. respond(r, Eperm);
  136. return;
  137. }
  138. if(strlen(r->ifcall.name) > MAXNSIZE) {
  139. respond(r, "filename too long");
  140. return;
  141. }
  142. err = need(Ncreate);
  143. if(err != nil) {
  144. respond(r, err);
  145. return;
  146. }
  147. j.type = FT_create;
  148. j.mtime = now();
  149. j.parent = e->fnum;
  150. j.mode = r->ifcall.perm;
  151. strcpy(j.name, r->ifcall.name);
  152. f = ecreate(e, r->ifcall.name, 0, r->ifcall.perm, j.mtime, &err);
  153. if(f == nil) {
  154. respond(r, err);
  155. return;
  156. }
  157. j.fnum = f->fnum;
  158. put(&j, 1);
  159. s->e = f;
  160. r->ofcall.qid = eqid(f);
  161. respond(r, nil);
  162. }
  163. static void
  164. flread(Req *r)
  165. {
  166. Entry *e;
  167. State *s;
  168. s = r->fid->aux;
  169. e = s->e;
  170. if(e->mode & DMDIR)
  171. r->ofcall.count = edirread(s->r, r->ofcall.data, r->ifcall.count);
  172. else
  173. r->ofcall.count = eread(e, eparity, r->ofcall.data, r->ifcall.count, r->ifcall.offset);
  174. respond(r, nil);
  175. }
  176. static void
  177. flwrite(Req *r)
  178. {
  179. Jrec j;
  180. uchar *a;
  181. Entry *e;
  182. State *s;
  183. Extent *x;
  184. char *err;
  185. ulong c, n, o, mtime;
  186. c = r->ifcall.count;
  187. o = r->ifcall.offset;
  188. a = (uchar *)r->ifcall.data;
  189. if(c == 0) {
  190. respond(r, nil);
  191. return;
  192. }
  193. if(o + c >= MAXFSIZE) {
  194. respond(r, "file too big");
  195. return;
  196. }
  197. if(used + c > limit) {
  198. respond(r, "filesystem full");
  199. return;
  200. }
  201. r->ofcall.count = c;
  202. s = r->fid->aux;
  203. e = s->e;
  204. mtime = now();
  205. for(;;) {
  206. n = c;
  207. if(n > maxwrite)
  208. n = maxwrite;
  209. err = need(Nwrite + n);
  210. if(err != nil) {
  211. respond(r, err);
  212. return;
  213. }
  214. x = emalloc9p(sizeof(Extent));
  215. x->size = n;
  216. x->off = o;
  217. ewrite(e, x, eparity, mtime);
  218. j.type = FT_WRITE;
  219. j.fnum = e->fnum;
  220. j.size = n;
  221. j.offset = o;
  222. j.mtime = mtime;
  223. putw(&j, 1, x, a);
  224. c -= n;
  225. if(c == 0)
  226. break;
  227. o += n;
  228. a += n;
  229. }
  230. respond(r, nil);
  231. }
  232. static void
  233. flremove(Req *r)
  234. {
  235. Jrec j;
  236. State *s;
  237. Entry *e;
  238. char *d, *err;
  239. if(readonly) {
  240. respond(r, Erofs);
  241. return;
  242. }
  243. s = r->fid->aux;
  244. e = s->e;
  245. if(writeable(e->parent)) {
  246. err = need(Nremove);
  247. if(err != nil) {
  248. respond(r, err);
  249. return;
  250. }
  251. d = eremove(e);
  252. if(d == nil) {
  253. j.type = FT_REMOVE;
  254. j.fnum = e->fnum;
  255. put(&j, 0);
  256. }
  257. respond(r, d);
  258. }
  259. else
  260. respond(r, Eperm);
  261. }
  262. static void
  263. flstat(Req *r)
  264. {
  265. State *s;
  266. s = r->fid->aux;
  267. estat(s->e, &r->d, 1);
  268. respond(r, nil);
  269. }
  270. static void
  271. flwstat(Req *r)
  272. {
  273. int m;
  274. Jrec j;
  275. State *s;
  276. Entry *e;
  277. char *err;
  278. s = r->fid->aux;
  279. e = s->e;
  280. if(readonly) {
  281. respond(r, Erofs);
  282. return;
  283. }
  284. if(e->fnum == 0) {
  285. respond(r, Eperm);
  286. return;
  287. }
  288. m = r->d.mode & 0777;
  289. if(m != (e->mode & 0777)) {
  290. err = need(Nchmod);
  291. if(err != nil) {
  292. respond(r, err);
  293. return;
  294. }
  295. echmod(e, m, 0);
  296. j.type = FT_chmod;
  297. j.mode = m;
  298. j.fnum = e->fnum;
  299. j.mnum = e->mnum;
  300. put(&j, 0);
  301. }
  302. respond(r, nil);
  303. }
  304. static void
  305. flwalk(Req *r)
  306. {
  307. int i;
  308. State *s;
  309. char *err;
  310. Entry *e, *f;
  311. if(r->ifcall.fid != r->ifcall.newfid)
  312. r->newfid->aux = state(nil);
  313. s = r->fid->aux;
  314. e = s->e;
  315. f = e;
  316. e->ref++;
  317. err = nil;
  318. for(i = 0; i < r->ifcall.nwname; i++) {
  319. f = ewalk(e, r->ifcall.wname[i], &err);
  320. if(f) {
  321. r->ofcall.wqid[i] = eqid(f);
  322. e = f;
  323. }
  324. else {
  325. e->ref--;
  326. break;
  327. }
  328. }
  329. r->ofcall.nwqid = i;
  330. if (i) err = nil;
  331. if(f) {
  332. if(r->ifcall.fid != r->ifcall.newfid) {
  333. s = r->newfid->aux;
  334. s->e = f;
  335. r->newfid->qid = eqid(f);
  336. }
  337. else {
  338. s = r->fid->aux;
  339. s->e->ref--;
  340. s->e = f;
  341. r->fid->qid = eqid(f);
  342. }
  343. }
  344. respond(r, err);
  345. }
  346. void
  347. serve(char *mount)
  348. {
  349. flashsrv.attach = flattach;
  350. flashsrv.open = flopen;
  351. flashsrv.create = flcreate;
  352. flashsrv.read = flread;
  353. flashsrv.write = flwrite;
  354. flashsrv.remove = flremove;
  355. flashsrv.stat = flstat;
  356. flashsrv.wstat = flwstat;
  357. flashsrv.walk = flwalk;
  358. flashsrv.destroyfid = destroy;
  359. flashsrv.destroyreq = trace;
  360. postmountsrv(&flashsrv, "brzr", mount, MREPL|MCREATE);
  361. }