aoedev.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /* Copyright (c) 2006 Coraid, Inc. See COPYING for GPL terms. */
  2. /*
  3. * aoedev.c
  4. * AoE device utility functions; maintains device list.
  5. */
  6. #include <linux/hdreg.h>
  7. #include <linux/blkdev.h>
  8. #include <linux/netdevice.h>
  9. #include "aoe.h"
  10. static struct aoedev *devlist;
  11. static spinlock_t devlist_lock;
  12. int
  13. aoedev_isbusy(struct aoedev *d)
  14. {
  15. struct aoetgt **t, **te;
  16. struct frame *f, *e;
  17. t = d->targets;
  18. te = t + NTARGETS;
  19. for (; t < te && *t; t++) {
  20. f = (*t)->frames;
  21. e = f + (*t)->nframes;
  22. for (; f < e; f++)
  23. if (f->tag != FREETAG)
  24. return 1;
  25. }
  26. return 0;
  27. }
  28. struct aoedev *
  29. aoedev_by_aoeaddr(int maj, int min)
  30. {
  31. struct aoedev *d;
  32. ulong flags;
  33. spin_lock_irqsave(&devlist_lock, flags);
  34. for (d=devlist; d; d=d->next)
  35. if (d->aoemajor == maj && d->aoeminor == min)
  36. break;
  37. spin_unlock_irqrestore(&devlist_lock, flags);
  38. return d;
  39. }
  40. static void
  41. dummy_timer(ulong vp)
  42. {
  43. struct aoedev *d;
  44. d = (struct aoedev *)vp;
  45. if (d->flags & DEVFL_TKILL)
  46. return;
  47. d->timer.expires = jiffies + HZ;
  48. add_timer(&d->timer);
  49. }
  50. void
  51. aoedev_downdev(struct aoedev *d)
  52. {
  53. struct aoetgt **t, **te;
  54. struct frame *f, *e;
  55. struct buf *buf;
  56. struct bio *bio;
  57. t = d->targets;
  58. te = t + NTARGETS;
  59. for (; t < te && *t; t++) {
  60. f = (*t)->frames;
  61. e = f + (*t)->nframes;
  62. for (; f < e; f->tag = FREETAG, f->buf = NULL, f++) {
  63. if (f->tag == FREETAG || f->buf == NULL)
  64. continue;
  65. buf = f->buf;
  66. bio = buf->bio;
  67. if (--buf->nframesout == 0
  68. && buf != d->inprocess) {
  69. mempool_free(buf, d->bufpool);
  70. bio_endio(bio, -EIO);
  71. }
  72. }
  73. (*t)->maxout = (*t)->nframes;
  74. (*t)->nout = 0;
  75. }
  76. buf = d->inprocess;
  77. if (buf) {
  78. bio = buf->bio;
  79. mempool_free(buf, d->bufpool);
  80. bio_endio(bio, -EIO);
  81. }
  82. d->inprocess = NULL;
  83. d->htgt = NULL;
  84. while (!list_empty(&d->bufq)) {
  85. buf = container_of(d->bufq.next, struct buf, bufs);
  86. list_del(d->bufq.next);
  87. bio = buf->bio;
  88. mempool_free(buf, d->bufpool);
  89. bio_endio(bio, -EIO);
  90. }
  91. if (d->gd)
  92. d->gd->capacity = 0;
  93. d->flags &= ~DEVFL_UP;
  94. }
  95. /* find it or malloc it */
  96. struct aoedev *
  97. aoedev_by_sysminor_m(ulong sysminor)
  98. {
  99. struct aoedev *d;
  100. ulong flags;
  101. spin_lock_irqsave(&devlist_lock, flags);
  102. for (d=devlist; d; d=d->next)
  103. if (d->sysminor == sysminor)
  104. break;
  105. if (d)
  106. goto out;
  107. d = kcalloc(1, sizeof *d, GFP_ATOMIC);
  108. if (!d)
  109. goto out;
  110. INIT_WORK(&d->work, aoecmd_sleepwork);
  111. spin_lock_init(&d->lock);
  112. init_timer(&d->timer);
  113. d->timer.data = (ulong) d;
  114. d->timer.function = dummy_timer;
  115. d->timer.expires = jiffies + HZ;
  116. add_timer(&d->timer);
  117. d->bufpool = NULL; /* defer to aoeblk_gdalloc */
  118. d->tgt = d->targets;
  119. INIT_LIST_HEAD(&d->bufq);
  120. d->sysminor = sysminor;
  121. d->aoemajor = AOEMAJOR(sysminor);
  122. d->aoeminor = AOEMINOR(sysminor);
  123. d->mintimer = MINTIMER;
  124. d->next = devlist;
  125. devlist = d;
  126. out:
  127. spin_unlock_irqrestore(&devlist_lock, flags);
  128. return d;
  129. }
  130. static void
  131. freetgt(struct aoetgt *t)
  132. {
  133. struct frame *f, *e;
  134. f = t->frames;
  135. e = f + t->nframes;
  136. for (; f < e; f++) {
  137. skb_shinfo(f->skb)->nr_frags = 0;
  138. dev_kfree_skb(f->skb);
  139. }
  140. kfree(t->frames);
  141. kfree(t);
  142. }
  143. static void
  144. aoedev_freedev(struct aoedev *d)
  145. {
  146. struct aoetgt **t, **e;
  147. if (d->gd) {
  148. aoedisk_rm_sysfs(d);
  149. del_gendisk(d->gd);
  150. put_disk(d->gd);
  151. }
  152. t = d->targets;
  153. e = t + NTARGETS;
  154. for (; t < e && *t; t++)
  155. freetgt(*t);
  156. if (d->bufpool)
  157. mempool_destroy(d->bufpool);
  158. kfree(d);
  159. }
  160. void
  161. aoedev_exit(void)
  162. {
  163. struct aoedev *d;
  164. ulong flags;
  165. flush_scheduled_work();
  166. while ((d = devlist)) {
  167. devlist = d->next;
  168. spin_lock_irqsave(&d->lock, flags);
  169. aoedev_downdev(d);
  170. d->flags |= DEVFL_TKILL;
  171. spin_unlock_irqrestore(&d->lock, flags);
  172. del_timer_sync(&d->timer);
  173. aoedev_freedev(d);
  174. }
  175. }
  176. int __init
  177. aoedev_init(void)
  178. {
  179. spin_lock_init(&devlist_lock);
  180. return 0;
  181. }