v6fs.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * old (V6 and before) PDP-11 Unix filesystem
  3. */
  4. #include <u.h>
  5. #include <libc.h>
  6. #include <auth.h>
  7. #include <fcall.h>
  8. #include "tapefs.h"
  9. /*
  10. * v6 disk inode
  11. */
  12. #define V6NADDR 8
  13. #define V6FMT 0160000
  14. #define V6IFREG 0100000
  15. #define V6IFDIR 0140000
  16. #define V6IFCHR 0120000
  17. #define V6IFBLK 0160000
  18. #define V6MODE 0777
  19. #define V6LARGE 010000
  20. #define V6SUPERB 1
  21. #define V6ROOT 1 /* root inode */
  22. #define V6NAMELEN 14
  23. #define BLSIZE 512
  24. #define LINOPB (BLSIZE/sizeof(struct v6dinode))
  25. #define LNINDIR (BLSIZE/sizeof(unsigned short))
  26. struct v6dinode {
  27. unsigned char flags[2];
  28. unsigned char nlinks;
  29. unsigned char uid;
  30. unsigned char gid;
  31. unsigned char hisize;
  32. unsigned char losize[2];
  33. unsigned char addr[V6NADDR][2];
  34. unsigned char atime[4]; /* pdp-11 order */
  35. unsigned char mtime[4]; /* pdp-11 order */
  36. };
  37. struct v6dir {
  38. uchar ino[2];
  39. char name[V6NAMELEN];
  40. };
  41. int tapefile;
  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. replete = 0;
  50. tapefile = open(name, OREAD);
  51. if (tapefile<0)
  52. error("Can't open argument file");
  53. f = iget(V6ROOT);
  54. ram->perm = f.mode;
  55. ram->mtime = f.mdate;
  56. ram->addr = f.addr;
  57. ram->data = f.data;
  58. ram->ndata = f.size;
  59. }
  60. void
  61. popdir(Ram *r)
  62. {
  63. int i, ino;
  64. char *cp;
  65. struct v6dir *dp;
  66. Fileinf f;
  67. char name[V6NAMELEN+1];
  68. cp = 0;
  69. for (i=0; i<r->ndata; i+=sizeof(struct v6dir)) {
  70. if (i%BLSIZE==0)
  71. cp = doread(r, i, BLSIZE);
  72. dp = (struct v6dir *)(cp+i%BLSIZE);
  73. ino = dp->ino[0] + (dp->ino[1]<<8);
  74. if (strcmp(dp->name, ".")==0 || strcmp(dp->name, "..")==0)
  75. continue;
  76. if (ino==0)
  77. continue;
  78. f = iget(ino);
  79. strncpy(name, dp->name, V6NAMELEN);
  80. name[V6NAMELEN] = '\0';
  81. f.name = name;
  82. popfile(r, f);
  83. }
  84. r->replete = 1;
  85. }
  86. void
  87. dotrunc(Ram *r)
  88. {
  89. USED(r);
  90. }
  91. void
  92. docreate(Ram *r)
  93. {
  94. USED(r);
  95. }
  96. char *
  97. doread(Ram *r, vlong off, long cnt)
  98. {
  99. static char buf[Maxbuf+BLSIZE];
  100. int bno, i;
  101. bno = off/BLSIZE;
  102. off -= bno*BLSIZE;
  103. if (cnt>Maxbuf)
  104. error("count too large");
  105. if (off)
  106. cnt += off;
  107. i = 0;
  108. while (cnt>0) {
  109. getblk(r, bno, &buf[i*BLSIZE]);
  110. cnt -= BLSIZE;
  111. bno++;
  112. i++;
  113. }
  114. return buf;
  115. }
  116. void
  117. dowrite(Ram *r, char *buf, long off, long cnt)
  118. {
  119. USED(r); USED(buf); USED(off); USED(cnt);
  120. }
  121. int
  122. dopermw(Ram *r)
  123. {
  124. USED(r);
  125. return 0;
  126. }
  127. /*
  128. * fetch an i-node
  129. * -- no sanity check for now
  130. * -- magic inode-to-disk-block stuff here
  131. */
  132. Fileinf
  133. iget(int ino)
  134. {
  135. char buf[BLSIZE];
  136. struct v6dinode *dp;
  137. long flags, i;
  138. Fileinf f;
  139. seek(tapefile, BLSIZE*((ino-1)/LINOPB + V6SUPERB + 1), 0);
  140. if (read(tapefile, buf, BLSIZE) != BLSIZE)
  141. error("Can't read inode");
  142. dp = ((struct v6dinode *)buf) + ((ino-1)%LINOPB);
  143. flags = (dp->flags[1]<<8) + dp->flags[0];
  144. f.size = (dp->hisize << 16) + (dp->losize[1]<<8) + dp->losize[0];
  145. if ((flags&V6FMT)==V6IFCHR || (flags&V6FMT)==V6IFBLK)
  146. f.size = 0;
  147. f.data = emalloc(V6NADDR*sizeof(ushort));
  148. for (i = 0; i < V6NADDR; i++)
  149. ((ushort*)f.data)[i] = (dp->addr[i][1]<<8) + dp->addr[i][0];
  150. f.mode = flags & V6MODE;
  151. if ((flags&V6FMT)==V6IFDIR)
  152. f.mode |= DMDIR;
  153. f.uid = dp->uid;
  154. f.gid = dp->gid;
  155. f.mdate = (dp->mtime[2]<<0) + (dp->mtime[3]<<8)
  156. +(dp->mtime[0]<<16) + (dp->mtime[1]<<24);
  157. return f;
  158. }
  159. void
  160. getblk(Ram *r, long bno, char *buf)
  161. {
  162. long dbno;
  163. if ((dbno = bmap(r, bno)) == 0) {
  164. memset(buf, 0, BLSIZE);
  165. return;
  166. }
  167. seek(tapefile, dbno*BLSIZE, 0);
  168. if (read(tapefile, buf, BLSIZE) != BLSIZE)
  169. error("bad read");
  170. }
  171. /*
  172. * logical to physical block
  173. * only singly-indirect files for now
  174. */
  175. long
  176. bmap(Ram *r, long bno)
  177. {
  178. unsigned char indbuf[LNINDIR][2];
  179. if (r->ndata <= V6NADDR*BLSIZE) { /* assume size predicts largeness of file */
  180. if (bno < V6NADDR)
  181. return ((ushort*)r->data)[bno];
  182. return 0;
  183. }
  184. if (bno < V6NADDR*LNINDIR) {
  185. seek(tapefile, ((ushort *)r->data)[bno/LNINDIR]*BLSIZE, 0);
  186. if (read(tapefile, (char *)indbuf, BLSIZE) != BLSIZE)
  187. return 0;
  188. return ((indbuf[bno%LNINDIR][1]<<8) + indbuf[bno%LNINDIR][0]);
  189. }
  190. return 0;
  191. }