v10fs.c 4.0 KB

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