32vfs.c 3.8 KB

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