v6fs.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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->data = f.addr;
  57. ram->ndata = f.size;
  58. }
  59. void
  60. popdir(Ram *r)
  61. {
  62. int i, ino;
  63. char *cp;
  64. struct v6dir *dp;
  65. Fileinf f;
  66. char name[V6NAMELEN+1];
  67. cp = 0;
  68. for (i=0; i<r->ndata; i+=sizeof(struct v6dir)) {
  69. if (i%BLSIZE==0)
  70. cp = doread(r, i, BLSIZE);
  71. dp = (struct v6dir *)(cp+i%BLSIZE);
  72. ino = dp->ino[0] + (dp->ino[1]<<8);
  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, V6NAMELEN);
  79. name[V6NAMELEN+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, long 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;
  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 v6dinode *dp;
  136. long flags, i;
  137. Fileinf f;
  138. seek(tapefile, BLSIZE*((ino-1)/LINOPB + V6SUPERB + 1), 0);
  139. if (read(tapefile, buf, BLSIZE) != BLSIZE)
  140. error("Can't read inode");
  141. dp = ((struct v6dinode *)buf) + ((ino-1)%LINOPB);
  142. flags = (dp->flags[1]<<8) + dp->flags[0];
  143. f.size = (dp->hisize << 16) + (dp->losize[1]<<8) + dp->losize[0];
  144. if ((flags&V6FMT)==V6IFCHR || (flags&V6FMT)==V6IFBLK)
  145. f.size = 0;
  146. f.addr = emalloc(V6NADDR*sizeof(ushort));
  147. for (i = 0; i < V6NADDR; i++)
  148. ((ushort*)f.addr)[i] = (dp->addr[i][1]<<8) + dp->addr[i][0];
  149. f.mode = flags & V6MODE;
  150. if ((flags&V6FMT)==V6IFDIR)
  151. f.mode |= DMDIR;
  152. f.uid = dp->uid;
  153. f.gid = dp->gid;
  154. f.mdate = (dp->mtime[2]<<0) + (dp->mtime[3]<<8)
  155. +(dp->mtime[0]<<16) + (dp->mtime[1]<<24);
  156. return f;
  157. }
  158. void
  159. getblk(Ram *r, long bno, char *buf)
  160. {
  161. long dbno;
  162. if ((dbno = bmap(r, bno)) == 0) {
  163. memset(buf, 0, BLSIZE);
  164. return;
  165. }
  166. seek(tapefile, dbno*BLSIZE, 0);
  167. if (read(tapefile, buf, BLSIZE) != BLSIZE)
  168. error("bad read");
  169. }
  170. /*
  171. * logical to physical block
  172. * only singly-indirect files for now
  173. */
  174. long
  175. bmap(Ram *r, long bno)
  176. {
  177. unsigned char indbuf[LNINDIR][2];
  178. if (r->ndata <= V6NADDR*BLSIZE) { /* assume size predicts largeness of file */
  179. if (bno < V6NADDR)
  180. return ((ushort*)r->data)[bno];
  181. return 0;
  182. }
  183. if (bno < V6NADDR*LNINDIR) {
  184. seek(tapefile, ((ushort *)r->data)[bno/LNINDIR]*BLSIZE, 0);
  185. if (read(tapefile, (char *)indbuf, BLSIZE) != BLSIZE)
  186. return 0;
  187. return ((indbuf[bno%LNINDIR][1]<<8) + indbuf[bno%LNINDIR][0]);
  188. }
  189. return 0;
  190. }