32vfs.c 3.6 KB

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