v10fs.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. /*
  10. * 10th edition 4K file system
  11. */
  12. #include <u.h>
  13. #include <libc.h>
  14. #include <auth.h>
  15. #include <fcall.h>
  16. #include "tapefs.h"
  17. /*
  18. * v10 disk inode
  19. */
  20. #define VNADDR 13
  21. #define VFMT 0160000
  22. #define VIFREG 0100000
  23. #define VIFDIR 0040000
  24. #define VIFCHR 0120000
  25. #define VIFBLK 0160000
  26. #define VMODE 0777
  27. #define VSUPERB 1
  28. #define VROOT 2 /* root inode */
  29. #define VNAMELEN 14
  30. #define BLSIZE 4096
  31. #define LINOPB (BLSIZE/sizeof(struct v10dinode))
  32. #define LNINDIR (BLSIZE/sizeof(unsigned long))
  33. struct v10dinode {
  34. unsigned char flags[2];
  35. unsigned char nlinks[2];
  36. unsigned char uid[2];
  37. unsigned char gid[2];
  38. unsigned char size[4];
  39. unsigned char addr[40];
  40. unsigned char atime[4];
  41. unsigned char mtime[4];
  42. unsigned char ctime[4];
  43. };
  44. struct v10dir {
  45. uint8_t ino[2];
  46. char name[VNAMELEN];
  47. };
  48. int tapefile;
  49. int64_t tapelen;
  50. Fileinf iget(int ino);
  51. int32_t bmap(Ram *r, int32_t bno);
  52. void getblk(Ram *r, int32_t bno, char *buf);
  53. void
  54. populate(char *name)
  55. {
  56. Fileinf f;
  57. Dir *d;
  58. replete = 0;
  59. tapefile = open(name, OREAD);
  60. if (tapefile<0)
  61. error("Can't open argument file");
  62. if ((d=dirfstat(tapefile)) == nil)
  63. error("dirfstat");
  64. tapelen = d->length;
  65. free(d);
  66. f = iget(VROOT);
  67. ram->perm = f.mode;
  68. ram->mtime = f.mdate;
  69. ram->addr = f.addr;
  70. ram->data = f.data;
  71. ram->ndata = f.size;
  72. }
  73. void
  74. popdir(Ram *r)
  75. {
  76. int i, ino;
  77. char *cp;
  78. struct v10dir *dp;
  79. Fileinf f;
  80. char name[VNAMELEN+1];
  81. cp = 0;
  82. for (i=0; i<r->ndata; i+=sizeof(struct v10dir)) {
  83. if (i%BLSIZE==0)
  84. cp = doread(r, i, BLSIZE);
  85. dp = (struct v10dir *)(cp+i%BLSIZE);
  86. ino = g2byte(dp->ino);
  87. if (strcmp(dp->name, ".")==0 || strcmp(dp->name, "..")==0)
  88. continue;
  89. if (ino==0)
  90. continue;
  91. f = iget(ino);
  92. strncpy(name, dp->name, VNAMELEN);
  93. name[VNAMELEN] = '\0';
  94. f.name = name;
  95. popfile(r, f);
  96. }
  97. r->replete = 1;
  98. }
  99. void
  100. dotrunc(Ram *r)
  101. {
  102. USED(r);
  103. }
  104. void
  105. docreate(Ram *r)
  106. {
  107. USED(r);
  108. }
  109. char *
  110. doread(Ram *r, int64_t off, int32_t cnt)
  111. {
  112. static char buf[Maxbuf+BLSIZE];
  113. int bno, i;
  114. bno = off/BLSIZE;
  115. off -= bno*BLSIZE;
  116. if (cnt>Maxbuf)
  117. error("count too large");
  118. if (off)
  119. cnt += off;
  120. i = 0;
  121. while (cnt>0) {
  122. getblk(r, bno, &buf[i*BLSIZE]);
  123. cnt -= BLSIZE;
  124. bno++;
  125. i++;
  126. }
  127. return buf+off;
  128. }
  129. void
  130. dowrite(Ram *r, char *buf, int32_t off, int32_t cnt)
  131. {
  132. USED(r); USED(buf); USED(off); USED(cnt);
  133. }
  134. int
  135. dopermw(Ram *r)
  136. {
  137. USED(r);
  138. return 0;
  139. }
  140. /*
  141. * fetch an i-node
  142. * -- no sanity check for now
  143. * -- magic inode-to-disk-block stuff here
  144. */
  145. Fileinf
  146. iget(int ino)
  147. {
  148. char buf[BLSIZE];
  149. struct v10dinode *dp;
  150. int32_t flags, i;
  151. Fileinf f;
  152. seek(tapefile, BLSIZE*((ino-1)/LINOPB + VSUPERB + 1), 0);
  153. if (read(tapefile, buf, BLSIZE) != BLSIZE)
  154. error("Can't read inode");
  155. dp = ((struct v10dinode *)buf) + ((ino-1)%LINOPB);
  156. flags = g2byte(dp->flags);
  157. f.size = g4byte(dp->size);
  158. if ((flags&VFMT)==VIFCHR || (flags&VFMT)==VIFBLK)
  159. f.size = 0;
  160. f.data = emalloc(VNADDR*sizeof(int32_t));
  161. for (i = 0; i < VNADDR; i++)
  162. ((int32_t*)f.data)[i] = g3byte(dp->addr+3*i);
  163. f.mode = flags & VMODE;
  164. if ((flags&VFMT)==VIFDIR)
  165. f.mode |= DMDIR;
  166. f.uid = g2byte(dp->uid);
  167. f.gid = g2byte(dp->gid);
  168. f.mdate = g4byte(dp->mtime);
  169. return f;
  170. }
  171. void
  172. getblk(Ram *r, int32_t bno, char *buf)
  173. {
  174. int32_t dbno;
  175. if ((dbno = bmap(r, bno)) == 0) {
  176. memset(buf, 0, BLSIZE);
  177. return;
  178. }
  179. if ((int64_t)(dbno+1)*BLSIZE > tapelen) {
  180. fprint(2, "read past end of tape: %lld\n",
  181. (int64_t)dbno*BLSIZE);
  182. memset(buf, 0, BLSIZE);
  183. return;
  184. }
  185. seek(tapefile, dbno*BLSIZE, 0);
  186. if (readn(tapefile, buf, BLSIZE) != BLSIZE){
  187. fprint(2, "readn at %lld: %r\n", (int64_t)dbno*BLSIZE);
  188. error("bad read");
  189. }
  190. }
  191. /*
  192. * logical to physical block
  193. * only singly-indirect files for now
  194. */
  195. int32_t
  196. bmap(Ram *r, int32_t bno)
  197. {
  198. unsigned char indbuf[LNINDIR][sizeof(int32_t)];
  199. if (bno < VNADDR-3)
  200. return ((int32_t*)r->data)[bno];
  201. if (bno < VNADDR*LNINDIR) {
  202. seek(tapefile,
  203. ((int32_t *)r->data)[(bno-(VNADDR-3))/LNINDIR+(VNADDR-3)]*BLSIZE,
  204. 0);
  205. if (read(tapefile, (char *)indbuf, BLSIZE) != BLSIZE)
  206. return 0;
  207. return ((indbuf[(bno-(VNADDR-3))%LNINDIR][2]<<16) + (indbuf[(bno-(VNADDR-3))%LNINDIR][1]<<8)
  208. + indbuf[(bno-(VNADDR-3))%LNINDIR][0]);
  209. }
  210. return 0;
  211. }