32vfs.c 4.3 KB

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