v10fs.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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. Fileinf iget(int ino);
  42. long bmap(Ram *r, long bno);
  43. void getblk(Ram *r, long bno, char *buf);
  44. void
  45. populate(char *name)
  46. {
  47. Fileinf f;
  48. replete = 0;
  49. tapefile = open(name, OREAD);
  50. if (tapefile<0)
  51. error("Can't open argument file");
  52. f = iget(VROOT);
  53. ram->perm = f.mode;
  54. ram->mtime = f.mdate;
  55. ram->addr = f.addr;
  56. ram->data = f.data;
  57. ram->ndata = f.size;
  58. }
  59. void
  60. popdir(Ram *r)
  61. {
  62. int i, ino;
  63. char *cp;
  64. struct v10dir *dp;
  65. Fileinf f;
  66. char name[VNAMELEN+1];
  67. cp = 0;
  68. for (i=0; i<r->ndata; i+=sizeof(struct v10dir)) {
  69. if (i%BLSIZE==0)
  70. cp = doread(r, i, BLSIZE);
  71. dp = (struct v10dir *)(cp+i%BLSIZE);
  72. ino = g2byte(dp->ino);
  73. if (strcmp(dp->name, ".")==0 || strcmp(dp->name, "..")==0)
  74. continue;
  75. if (ino==0)
  76. continue;
  77. f = iget(ino);
  78. strncpy(name, dp->name, VNAMELEN);
  79. name[VNAMELEN+1] = '\0';
  80. f.name = name;
  81. popfile(r, f);
  82. }
  83. r->replete = 1;
  84. }
  85. void
  86. dotrunc(Ram *r)
  87. {
  88. USED(r);
  89. }
  90. void
  91. docreate(Ram *r)
  92. {
  93. USED(r);
  94. }
  95. char *
  96. doread(Ram *r, vlong off, long cnt)
  97. {
  98. static char buf[Maxbuf+BLSIZE];
  99. int bno, i;
  100. bno = off/BLSIZE;
  101. off -= bno*BLSIZE;
  102. if (cnt>Maxbuf)
  103. error("count too large");
  104. if (off)
  105. cnt += off;
  106. i = 0;
  107. while (cnt>0) {
  108. getblk(r, bno, &buf[i*BLSIZE]);
  109. cnt -= BLSIZE;
  110. bno++;
  111. i++;
  112. }
  113. return buf+off;
  114. }
  115. void
  116. dowrite(Ram *r, char *buf, long off, long cnt)
  117. {
  118. USED(r); USED(buf); USED(off); USED(cnt);
  119. }
  120. int
  121. dopermw(Ram *r)
  122. {
  123. USED(r);
  124. return 0;
  125. }
  126. /*
  127. * fetch an i-node
  128. * -- no sanity check for now
  129. * -- magic inode-to-disk-block stuff here
  130. */
  131. Fileinf
  132. iget(int ino)
  133. {
  134. char buf[BLSIZE];
  135. struct v10dinode *dp;
  136. long flags, i;
  137. Fileinf f;
  138. seek(tapefile, BLSIZE*((ino-1)/LINOPB + VSUPERB + 1), 0);
  139. if (read(tapefile, buf, BLSIZE) != BLSIZE)
  140. error("Can't read inode");
  141. dp = ((struct v10dinode *)buf) + ((ino-1)%LINOPB);
  142. flags = g2byte(dp->flags);
  143. f.size = g4byte(dp->size);
  144. if ((flags&VFMT)==VIFCHR || (flags&VFMT)==VIFBLK)
  145. f.size = 0;
  146. f.data = emalloc(VNADDR*sizeof(long));
  147. for (i = 0; i < VNADDR; i++)
  148. ((long*)f.data)[i] = g3byte(dp->addr+3*i);
  149. f.mode = flags & VMODE;
  150. if ((flags&VFMT)==VIFDIR)
  151. f.mode |= DMDIR;
  152. f.uid = g2byte(dp->uid);
  153. f.gid = g2byte(dp->gid);
  154. f.mdate = g4byte(dp->mtime);
  155. return f;
  156. }
  157. void
  158. getblk(Ram *r, long bno, char *buf)
  159. {
  160. long dbno;
  161. if ((dbno = bmap(r, bno)) == 0) {
  162. memset(buf, 0, BLSIZE);
  163. return;
  164. }
  165. seek(tapefile, dbno*BLSIZE, 0);
  166. if (read(tapefile, buf, BLSIZE) != BLSIZE)
  167. error("bad read");
  168. }
  169. /*
  170. * logical to physical block
  171. * only singly-indirect files for now
  172. */
  173. long
  174. bmap(Ram *r, long bno)
  175. {
  176. unsigned char indbuf[LNINDIR][sizeof(long)];
  177. if (bno < VNADDR-3)
  178. return ((long*)r->data)[bno];
  179. if (bno < VNADDR*LNINDIR) {
  180. seek(tapefile, ((long *)r->data)[(bno-(VNADDR-3))/LNINDIR+(VNADDR-3)]*BLSIZE, 0);
  181. if (read(tapefile, (char *)indbuf, BLSIZE) != BLSIZE)
  182. return 0;
  183. return ((indbuf[(bno-(VNADDR-3))%LNINDIR][2]<<16) + (indbuf[(bno-(VNADDR-3))%LNINDIR][1]<<8)
  184. + indbuf[(bno-(VNADDR-3))%LNINDIR][0]);
  185. }
  186. return 0;
  187. }