v6fs.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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. * old (V6 and before) PDP-11 Unix filesystem
  11. */
  12. #include <u.h>
  13. #include <libc.h>
  14. #include <auth.h>
  15. #include <fcall.h>
  16. #include "tapefs.h"
  17. /*
  18. * v6 disk inode
  19. */
  20. #define V6NADDR 8
  21. #define V6FMT 0160000
  22. #define V6IFREG 0100000
  23. #define V6IFDIR 0140000
  24. #define V6IFCHR 0120000
  25. #define V6IFBLK 0160000
  26. #define V6MODE 0777
  27. #define V6LARGE 010000
  28. #define V6SUPERB 1
  29. #define V6ROOT 1 /* root inode */
  30. #define V6NAMELEN 14
  31. #define BLSIZE 512
  32. #define LINOPB (BLSIZE/sizeof(struct v6dinode))
  33. #define LNINDIR (BLSIZE/sizeof(unsigned short))
  34. struct v6dinode {
  35. unsigned char flags[2];
  36. unsigned char nlinks;
  37. unsigned char uid;
  38. unsigned char gid;
  39. unsigned char hisize;
  40. unsigned char losize[2];
  41. unsigned char addr[V6NADDR][2];
  42. unsigned char atime[4]; /* pdp-11 order */
  43. unsigned char mtime[4]; /* pdp-11 order */
  44. };
  45. struct v6dir {
  46. uint8_t ino[2];
  47. char name[V6NAMELEN];
  48. };
  49. int tapefile;
  50. Fileinf iget(int ino);
  51. int32_t bmap(Ram *r, int32_t bno);
  52. void getblk(Ram *r, int32_t bno, char *buf);
  53. void
  54. populate(char *name)
  55. {
  56. Fileinf f;
  57. replete = 0;
  58. tapefile = open(name, OREAD);
  59. if (tapefile<0)
  60. error("Can't open argument file");
  61. f = iget(V6ROOT);
  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 v6dir *dp;
  74. Fileinf f;
  75. char name[V6NAMELEN+1];
  76. cp = 0;
  77. for (i=0; i<r->ndata; i+=sizeof(struct v6dir)) {
  78. if (i%BLSIZE==0)
  79. cp = doread(r, i, BLSIZE);
  80. dp = (struct v6dir *)(cp+i%BLSIZE);
  81. ino = dp->ino[0] + (dp->ino[1]<<8);
  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, V6NAMELEN);
  88. name[V6NAMELEN] = '\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, int64_t off, int32_t cnt)
  106. {
  107. static char buf[Maxbuf+BLSIZE];
  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, int32_t off, int32_t 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[BLSIZE];
  144. struct v6dinode *dp;
  145. int32_t flags, i;
  146. Fileinf f;
  147. seek(tapefile, BLSIZE*((ino-1)/LINOPB + V6SUPERB + 1), 0);
  148. if (read(tapefile, buf, BLSIZE) != BLSIZE)
  149. error("Can't read inode");
  150. dp = ((struct v6dinode *)buf) + ((ino-1)%LINOPB);
  151. flags = (dp->flags[1]<<8) + dp->flags[0];
  152. f.size = (dp->hisize << 16) + (dp->losize[1]<<8) + dp->losize[0];
  153. if ((flags&V6FMT)==V6IFCHR || (flags&V6FMT)==V6IFBLK)
  154. f.size = 0;
  155. f.data = emalloc(V6NADDR*sizeof(uint16_t));
  156. for (i = 0; i < V6NADDR; i++)
  157. ((uint16_t*)f.data)[i] = (dp->addr[i][1]<<8) + dp->addr[i][0];
  158. f.mode = flags & V6MODE;
  159. if ((flags&V6FMT)==V6IFDIR)
  160. f.mode |= DMDIR;
  161. f.uid = dp->uid;
  162. f.gid = dp->gid;
  163. f.mdate = (dp->mtime[2]<<0) + (dp->mtime[3]<<8)
  164. +(dp->mtime[0]<<16) + (dp->mtime[1]<<24);
  165. return f;
  166. }
  167. void
  168. getblk(Ram *r, int32_t bno, char *buf)
  169. {
  170. int32_t dbno;
  171. if ((dbno = bmap(r, bno)) == 0) {
  172. memset(buf, 0, BLSIZE);
  173. return;
  174. }
  175. seek(tapefile, dbno*BLSIZE, 0);
  176. if (read(tapefile, buf, BLSIZE) != BLSIZE)
  177. error("bad read");
  178. }
  179. /*
  180. * logical to physical block
  181. * only singly-indirect files for now
  182. */
  183. int32_t
  184. bmap(Ram *r, int32_t bno)
  185. {
  186. unsigned char indbuf[LNINDIR][2];
  187. if (r->ndata <= V6NADDR*BLSIZE) { /* assume size predicts largeness of file */
  188. if (bno < V6NADDR)
  189. return ((uint16_t*)r->data)[bno];
  190. return 0;
  191. }
  192. if (bno < V6NADDR*LNINDIR) {
  193. seek(tapefile, ((uint16_t *)r->data)[bno/LNINDIR]*BLSIZE, 0);
  194. if (read(tapefile, (char *)indbuf, BLSIZE) != BLSIZE)
  195. return 0;
  196. return ((indbuf[bno%LNINDIR][1]<<8) + indbuf[bno%LNINDIR][0]);
  197. }
  198. return 0;
  199. }