devwren.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #include "all.h"
  2. enum{
  3. MAXWREN = 7,
  4. };
  5. #define WMAGIC "kfs wren device\n"
  6. typedef struct Wren Wren;
  7. struct Wren{
  8. QLock;
  9. Device dev;
  10. uvlong size;
  11. int fd;
  12. };
  13. static Wren *wrens;
  14. static int maxwren;
  15. char *wrenfile;
  16. int nwren;
  17. int badmagic;
  18. static Wren *
  19. wren(Device dev)
  20. {
  21. int i;
  22. for(i = 0; i < maxwren; i++)
  23. if(devcmp(dev, wrens[i].dev) == 0)
  24. return &wrens[i];
  25. panic("can't find wren for %D", dev);
  26. return 0;
  27. }
  28. void
  29. wreninit(Device dev)
  30. {
  31. char buf[MAXBUFSIZE];
  32. Wren *w;
  33. Dir *d;
  34. int fd, i;
  35. if(wrens == 0)
  36. wrens = ialloc(MAXWREN * sizeof *wrens);
  37. w = &wrens[maxwren];
  38. fd = open(wrenfile, ORDWR);
  39. if(fd < 0)
  40. panic("can't open %s", wrenfile);
  41. if((d = dirfstat(fd)) == nil)
  42. panic("can't stat %s\n", wrenfile);
  43. seek(fd, 0, 0);
  44. i = read(fd, buf, sizeof buf);
  45. if(i < sizeof buf)
  46. panic("can't read %s", wrenfile);
  47. badmagic = 0;
  48. RBUFSIZE = 1024;
  49. if(strncmp(buf+256, WMAGIC, strlen(WMAGIC)) == 0){
  50. RBUFSIZE = atol(buf+256+strlen(WMAGIC));
  51. if(RBUFSIZE % 512){
  52. fprint(2, "kfs: bad buffersize(%d): assuming 1k blocks\n", RBUFSIZE);
  53. RBUFSIZE = 1024;
  54. }
  55. }else
  56. badmagic = 1;
  57. w->dev = dev;
  58. w->size = d->length;
  59. free(d);
  60. w->fd = fd;
  61. maxwren++;
  62. }
  63. void
  64. wrenream(Device dev)
  65. {
  66. Wren *w;
  67. char buf[MAXBUFSIZE];
  68. int fd, i;
  69. if(RBUFSIZE % 512)
  70. panic("kfs: bad buffersize(%d): restart a multiple of 512\n", RBUFSIZE);
  71. if(RBUFSIZE > sizeof(buf))
  72. panic("kfs: bad buffersize(%d): must be at most %d\n", RBUFSIZE, sizeof(buf));
  73. print("kfs: reaming the file system using %d byte blocks\n", RBUFSIZE);
  74. w = wren(dev);
  75. fd = w->fd;
  76. memset(buf, 0, sizeof buf);
  77. sprint(buf+256, "%s%d\n", WMAGIC, RBUFSIZE);
  78. qlock(w);
  79. i = seek(fd, 0, 0) < 0 || write(fd, buf, RBUFSIZE) != RBUFSIZE;
  80. qunlock(w);
  81. if(i < 0)
  82. panic("can't ream disk");
  83. }
  84. int
  85. wrentag(char *p, int tag, long qpath)
  86. {
  87. Tag *t;
  88. t = (Tag*)(p+BUFSIZE);
  89. return t->tag != tag || (qpath&~QPDIR) != t->path;
  90. }
  91. int
  92. wrencheck(Device dev)
  93. {
  94. char buf[MAXBUFSIZE];
  95. if(badmagic)
  96. return 1;
  97. if(RBUFSIZE > sizeof(buf))
  98. panic("kfs: bad buffersize(%d): must be at most %d\n", RBUFSIZE, sizeof(buf));
  99. if(wrenread(dev, wrensuper(dev), buf) || wrentag(buf, Tsuper, QPSUPER)
  100. || wrenread(dev, wrenroot(dev), buf) || wrentag(buf, Tdir, QPROOT))
  101. return 1;
  102. if(((Dentry *)buf)[0].mode & DALLOC)
  103. return 0;
  104. return 1;
  105. }
  106. long
  107. wrensize(Device dev)
  108. {
  109. return wren(dev)->size / RBUFSIZE;
  110. }
  111. long
  112. wrensuper(Device dev)
  113. {
  114. USED(dev);
  115. return 1;
  116. }
  117. long
  118. wrenroot(Device dev)
  119. {
  120. USED(dev);
  121. return 2;
  122. }
  123. int
  124. wrenread(Device dev, long addr, void *b)
  125. {
  126. Wren *w;
  127. int fd, i;
  128. w = wren(dev);
  129. fd = w->fd;
  130. qlock(w);
  131. i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || read(fd, b, RBUFSIZE) != RBUFSIZE;
  132. qunlock(w);
  133. if(i)
  134. print("wrenread failed: %r\n");
  135. return i;
  136. }
  137. int
  138. wrenwrite(Device dev, long addr, void *b)
  139. {
  140. Wren *w;
  141. int fd, i;
  142. w = wren(dev);
  143. fd = w->fd;
  144. qlock(w);
  145. i = seek(fd, (vlong)addr*RBUFSIZE, 0) == -1 || write(fd, b, RBUFSIZE) != RBUFSIZE;
  146. qunlock(w);
  147. if(i)
  148. print("wrenwrite failed: %r\n");
  149. return i;
  150. }