devwren.c 3.4 KB

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