ext2fs.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <fcall.h>
  12. #include <thread.h>
  13. #include <9p.h>
  14. #include "dat.h"
  15. #include "fns.h"
  16. #define thdr r->ifcall
  17. #define rhdr r->ofcall
  18. extern int errno;
  19. static void
  20. response(Req *r)
  21. {
  22. char *err;
  23. if (errno) {
  24. err = xerrstr(errno);
  25. chat("%s\n", err);
  26. respond(r, err);
  27. } else {
  28. chat("OK\n");
  29. respond(r, nil);
  30. }
  31. }
  32. static void
  33. rattach(Req *r)
  34. {
  35. Xfs *xf;
  36. Xfile *root;
  37. chat("attach(fid=%d,uname=\"%s\",aname=\"%s\",afid=\"%d\")...",
  38. thdr.fid, thdr.uname, thdr.aname, thdr.afid);
  39. errno = 0;
  40. root = xfile(r->fid, Clean);
  41. if(!root){
  42. errno = Enomem;
  43. goto error;
  44. }
  45. root->xf = xf = getxfs(thdr.aname);
  46. if(!xf)
  47. goto error;
  48. /* now attach root inode */
  49. if( get_inode(root, EXT2_ROOT_INODE) < 0 )
  50. goto error;
  51. r->fid->qid.type = QTDIR;
  52. r->fid->qid.vers = 0;
  53. root->xf->rootqid = r->fid->qid;
  54. root->pinbr = EXT2_ROOT_INODE;
  55. root->root = 1;
  56. rhdr.qid = r->fid->qid;
  57. error:
  58. response(r);
  59. }
  60. static char *
  61. rclone(Fid *fid, Fid *newfid)
  62. {
  63. Xfile *of = xfile(fid, Asis);
  64. Xfile *nf = xfile(newfid, Clean);
  65. chat("clone(fid=%d,newfid=%d)...", fid->fid, newfid->fid);
  66. errno = 0;
  67. if(!of)
  68. errno = Eio;
  69. else if(!nf)
  70. errno = Enomem;
  71. else{
  72. Xfile *next = nf->next;
  73. *nf = *of;
  74. nf->next = next;
  75. nf->fid = newfid->fid;
  76. nf->root = 0;
  77. }
  78. chat("%s\n", errno? xerrstr(errno) : "OK");
  79. return errno ? xerrstr(errno) : 0;
  80. }
  81. static char *
  82. rwalk1(Fid *fid, char *name, Qid *qid)
  83. {
  84. Xfile *f=xfile(fid, Asis);
  85. int nr, sinbr = 0;
  86. chat("walk1(fid=%d,name=\"%s\")...", fid->fid, name);
  87. errno = 0;
  88. if( !f ){
  89. chat("no xfile...");
  90. goto error;
  91. }
  92. if( !(fid->qid.type & QTDIR) ){
  93. chat("qid.type=0x%x...", fid->qid.type);
  94. goto error;
  95. }
  96. sinbr = f->pinbr;
  97. if( name == 0 || name[0] == 0 || !strcmp(name, ".") ){
  98. *qid = fid->qid;
  99. goto ok;
  100. }else if( !strcmp(name, "..") ){
  101. if( fid->qid.path == f->xf->rootqid.path ){
  102. chat("walkup from root...");
  103. *qid = fid->qid;
  104. goto ok;
  105. }
  106. if( get_inode(f, f->pinbr) < 0 )
  107. goto error;
  108. if( f->pinbr == EXT2_ROOT_INODE ){
  109. *qid = f->xf->rootqid;
  110. f->pinbr = EXT2_ROOT_INODE;
  111. } else {
  112. *qid = (Qid){f->pinbr,0,QTDIR};
  113. f->inbr = f->pinbr;
  114. if( (nr = get_file(f, "..")) < 0 )
  115. goto error;
  116. f->pinbr = nr;
  117. }
  118. }else{
  119. f->pinbr = f->inbr;
  120. if( (nr = get_file(f, name)) < 0 )
  121. goto error;
  122. if( get_inode(f, nr) < 0 )
  123. goto error;
  124. *qid = (Qid){nr,0,0};
  125. if( nr == EXT2_ROOT_INODE )
  126. *qid = f->xf->rootqid;
  127. else if( S_ISDIR(getmode(f)) )
  128. qid->type = QTDIR;
  129. /*strcpy(f->name, thdr.name);*/
  130. }
  131. ok:
  132. chat("OK\n");
  133. return 0;
  134. error:
  135. f->pinbr = sinbr;
  136. chat("%s\n", xerrstr(Enonexist));
  137. return xerrstr(Enonexist);
  138. }
  139. static void
  140. rstat(Req *r)
  141. {
  142. Xfile *f=xfile(r->fid, Asis);
  143. chat("stat(fid=%d)...", thdr.fid);
  144. errno = 0;
  145. if( !f )
  146. errno = Eio;
  147. else{
  148. dostat(r->fid->qid, f, &r->d);
  149. }
  150. response(r);
  151. }
  152. static void
  153. rwstat(Req *r)
  154. {
  155. Xfile *f=xfile(r->fid, Asis);
  156. chat("wstat(fid=%d)...", thdr.fid);
  157. errno = 0;
  158. if( !f )
  159. errno = Eio;
  160. else
  161. dowstat(f, &r->d);
  162. response(r);
  163. }
  164. static void
  165. rread(Req *r)
  166. {
  167. Xfile *f;
  168. int nr;
  169. chat("read(fid=%d,offset=%lld,count=%d)...",
  170. thdr.fid, thdr.offset, thdr.count);
  171. errno = 0;
  172. if ( !(f=xfile(r->fid, Asis)) )
  173. goto error;
  174. if( r->fid->qid.type & QTDIR ){
  175. nr = readdir(f, r->rbuf, thdr.offset, thdr.count);
  176. }else
  177. nr = readfile(f, r->rbuf, thdr.offset, thdr.count);
  178. if(nr >= 0){
  179. rhdr.count = nr;
  180. chat("rcnt=%d...OK\n", nr);
  181. respond(r, nil);
  182. return;
  183. }
  184. error:
  185. errno = Eio;
  186. response(r);
  187. }
  188. static void
  189. rwrite(Req *r)
  190. {
  191. Xfile *f; int nr;
  192. chat("write(fid=%d,offset=%lld,count=%d)...",
  193. thdr.fid, thdr.offset, thdr.count);
  194. errno = 0;
  195. if (!(f=xfile(r->fid, Asis)) ){
  196. errno = Eio;
  197. goto error;
  198. }
  199. if( !S_ISREG(getmode(f)) ){
  200. errno = Elink;
  201. goto error;
  202. }
  203. nr = writefile(f, thdr.data, thdr.offset, thdr.count);
  204. if(nr >= 0){
  205. rhdr.count = nr;
  206. chat("rcnt=%d...OK\n", nr);
  207. respond(r, nil);
  208. return;
  209. }
  210. errno = Eio;
  211. error:
  212. response(r);
  213. }
  214. static void
  215. destroyfid(Fid *fid)
  216. {
  217. chat("destroy(fid=%d)\n", fid->fid);
  218. xfile(fid, Clunk);
  219. /*syncbuf(xf);*/
  220. }
  221. static void
  222. ropen(Req *r)
  223. {
  224. Xfile *f;
  225. chat("open(fid=%d,mode=%d)...", thdr.fid, thdr.mode);
  226. errno = 0;
  227. f = xfile(r->fid, Asis);
  228. if( !f ){
  229. errno = Eio;
  230. goto error;
  231. }
  232. if(thdr.mode & OTRUNC){
  233. if( !S_ISREG(getmode(f)) ){
  234. errno = Eperm;
  235. goto error;
  236. }
  237. if(truncfile(f) < 0){
  238. goto error;
  239. }
  240. }
  241. chat("f->qid=0x%8.8lux...", r->fid->qid.path);
  242. rhdr.qid = r->fid->qid;
  243. error:
  244. response(r);
  245. }
  246. static void
  247. rcreate(Req *r)
  248. {
  249. Xfile *f;
  250. int inr, perm;
  251. chat("create(fid=%d,name=\"%s\",perm=%uo,mode=%d)...",
  252. thdr.fid, thdr.name, thdr.perm, thdr.mode);
  253. errno = 0;
  254. if(strcmp(thdr.name, ".") == 0 || strcmp(thdr.name, "..") == 0){
  255. errno = Eperm;
  256. goto error;
  257. }
  258. f = xfile(r->fid, Asis);
  259. if( !f ){
  260. errno = Eio;
  261. goto error;
  262. }
  263. if( strlen(thdr.name) > EXT2_NAME_LEN ){
  264. chat("name too long ...");
  265. errno = Elongname;
  266. goto error;
  267. }
  268. /* create */
  269. errno = 0;
  270. if( thdr.perm & DMDIR ){
  271. perm = (thdr.perm & ~0777) |
  272. (getmode(f) & thdr.perm & 0777);
  273. perm |= S_IFDIR;
  274. inr = create_dir(f, thdr.name, perm);
  275. }else{
  276. perm = (thdr.perm & (~0777|0111)) |
  277. (getmode(f) & thdr.perm & 0666);
  278. perm |= S_IFREG;
  279. inr = create_file(f, thdr.name, perm);
  280. }
  281. if( inr < 0 )
  282. goto error;
  283. /* fill with new inode */
  284. f->pinbr = f->inbr;
  285. if( get_inode(f, inr) < 0 ){
  286. errno = Eio;
  287. goto error;
  288. }
  289. r->fid->qid = (Qid){inr, 0, 0};
  290. if( S_ISDIR(getmode(f)) )
  291. r->fid->qid.type |= QTDIR;
  292. chat("f->qid=0x%8.8lux...", r->fid->qid.path);
  293. rhdr.qid = r->fid->qid;
  294. error:
  295. response(r);
  296. }
  297. static void
  298. rremove(Req *r)
  299. {
  300. Xfile *f=xfile(r->fid, Asis);
  301. chat("remove(fid=%d) ...", thdr.fid);
  302. errno = 0;
  303. if(!f){
  304. errno = Eio;
  305. goto error;
  306. }
  307. /* check permission here !!!!*/
  308. unlink(f);
  309. error:
  310. response(r);
  311. }
  312. Srv ext2srv = {
  313. .destroyfid = destroyfid,
  314. .attach = rattach,
  315. .stat = rstat,
  316. .wstat = rwstat,
  317. .clone = rclone,
  318. .walk1 = rwalk1,
  319. .open = ropen,
  320. .read = rread,
  321. .write = rwrite,
  322. .create = rcreate,
  323. .remove = rremove,
  324. };