aoedev.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /* Copyright (c) 2007 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 <linux/delay.h>
  10. #include <linux/slab.h>
  11. #include "aoe.h"
  12. static void dummy_timer(ulong);
  13. static void aoedev_freedev(struct aoedev *);
  14. static void freetgt(struct aoedev *d, struct aoetgt *t);
  15. static void skbpoolfree(struct aoedev *d);
  16. static struct aoedev *devlist;
  17. static DEFINE_SPINLOCK(devlist_lock);
  18. struct aoedev *
  19. aoedev_by_aoeaddr(int maj, int min)
  20. {
  21. struct aoedev *d;
  22. ulong flags;
  23. spin_lock_irqsave(&devlist_lock, flags);
  24. for (d=devlist; d; d=d->next)
  25. if (d->aoemajor == maj && d->aoeminor == min)
  26. break;
  27. spin_unlock_irqrestore(&devlist_lock, flags);
  28. return d;
  29. }
  30. static void
  31. dummy_timer(ulong vp)
  32. {
  33. struct aoedev *d;
  34. d = (struct aoedev *)vp;
  35. if (d->flags & DEVFL_TKILL)
  36. return;
  37. d->timer.expires = jiffies + HZ;
  38. add_timer(&d->timer);
  39. }
  40. void
  41. aoedev_downdev(struct aoedev *d)
  42. {
  43. struct aoetgt **t, **te;
  44. struct frame *f, *e;
  45. struct buf *buf;
  46. struct bio *bio;
  47. t = d->targets;
  48. te = t + NTARGETS;
  49. for (; t < te && *t; t++) {
  50. f = (*t)->frames;
  51. e = f + (*t)->nframes;
  52. for (; f < e; f->tag = FREETAG, f->buf = NULL, f++) {
  53. if (f->tag == FREETAG || f->buf == NULL)
  54. continue;
  55. buf = f->buf;
  56. bio = buf->bio;
  57. if (--buf->nframesout == 0
  58. && buf != d->inprocess) {
  59. mempool_free(buf, d->bufpool);
  60. bio_endio(bio, -EIO);
  61. }
  62. }
  63. (*t)->maxout = (*t)->nframes;
  64. (*t)->nout = 0;
  65. }
  66. buf = d->inprocess;
  67. if (buf) {
  68. bio = buf->bio;
  69. mempool_free(buf, d->bufpool);
  70. bio_endio(bio, -EIO);
  71. }
  72. d->inprocess = NULL;
  73. d->htgt = NULL;
  74. while (!list_empty(&d->bufq)) {
  75. buf = container_of(d->bufq.next, struct buf, bufs);
  76. list_del(d->bufq.next);
  77. bio = buf->bio;
  78. mempool_free(buf, d->bufpool);
  79. bio_endio(bio, -EIO);
  80. }
  81. if (d->gd)
  82. set_capacity(d->gd, 0);
  83. d->flags &= ~DEVFL_UP;
  84. }
  85. static void
  86. aoedev_freedev(struct aoedev *d)
  87. {
  88. struct aoetgt **t, **e;
  89. cancel_work_sync(&d->work);
  90. if (d->gd) {
  91. aoedisk_rm_sysfs(d);
  92. del_gendisk(d->gd);
  93. put_disk(d->gd);
  94. }
  95. t = d->targets;
  96. e = t + NTARGETS;
  97. for (; t < e && *t; t++)
  98. freetgt(d, *t);
  99. if (d->bufpool)
  100. mempool_destroy(d->bufpool);
  101. skbpoolfree(d);
  102. blk_cleanup_queue(d->blkq);
  103. kfree(d);
  104. }
  105. int
  106. aoedev_flush(const char __user *str, size_t cnt)
  107. {
  108. ulong flags;
  109. struct aoedev *d, **dd;
  110. struct aoedev *rmd = NULL;
  111. char buf[16];
  112. int all = 0;
  113. if (cnt >= 3) {
  114. if (cnt > sizeof buf)
  115. cnt = sizeof buf;
  116. if (copy_from_user(buf, str, cnt))
  117. return -EFAULT;
  118. all = !strncmp(buf, "all", 3);
  119. }
  120. spin_lock_irqsave(&devlist_lock, flags);
  121. dd = &devlist;
  122. while ((d = *dd)) {
  123. spin_lock(&d->lock);
  124. if ((!all && (d->flags & DEVFL_UP))
  125. || (d->flags & (DEVFL_GDALLOC|DEVFL_NEWSIZE))
  126. || d->nopen) {
  127. spin_unlock(&d->lock);
  128. dd = &d->next;
  129. continue;
  130. }
  131. *dd = d->next;
  132. aoedev_downdev(d);
  133. d->flags |= DEVFL_TKILL;
  134. spin_unlock(&d->lock);
  135. d->next = rmd;
  136. rmd = d;
  137. }
  138. spin_unlock_irqrestore(&devlist_lock, flags);
  139. while ((d = rmd)) {
  140. rmd = d->next;
  141. del_timer_sync(&d->timer);
  142. aoedev_freedev(d); /* must be able to sleep */
  143. }
  144. return 0;
  145. }
  146. /* I'm not really sure that this is a realistic problem, but if the
  147. network driver goes gonzo let's just leak memory after complaining. */
  148. static void
  149. skbfree(struct sk_buff *skb)
  150. {
  151. enum { Sms = 100, Tms = 3*1000};
  152. int i = Tms / Sms;
  153. if (skb == NULL)
  154. return;
  155. while (atomic_read(&skb_shinfo(skb)->dataref) != 1 && i-- > 0)
  156. msleep(Sms);
  157. if (i < 0) {
  158. printk(KERN_ERR
  159. "aoe: %s holds ref: %s\n",
  160. skb->dev ? skb->dev->name : "netif",
  161. "cannot free skb -- memory leaked.");
  162. return;
  163. }
  164. skb_shinfo(skb)->nr_frags = skb->data_len = 0;
  165. skb_trim(skb, 0);
  166. dev_kfree_skb(skb);
  167. }
  168. static void
  169. skbpoolfree(struct aoedev *d)
  170. {
  171. struct sk_buff *skb, *tmp;
  172. skb_queue_walk_safe(&d->skbpool, skb, tmp)
  173. skbfree(skb);
  174. __skb_queue_head_init(&d->skbpool);
  175. }
  176. /* find it or malloc it */
  177. struct aoedev *
  178. aoedev_by_sysminor_m(ulong sysminor)
  179. {
  180. struct aoedev *d;
  181. ulong flags;
  182. spin_lock_irqsave(&devlist_lock, flags);
  183. for (d=devlist; d; d=d->next)
  184. if (d->sysminor == sysminor)
  185. break;
  186. if (d)
  187. goto out;
  188. d = kcalloc(1, sizeof *d, GFP_ATOMIC);
  189. if (!d)
  190. goto out;
  191. INIT_WORK(&d->work, aoecmd_sleepwork);
  192. spin_lock_init(&d->lock);
  193. skb_queue_head_init(&d->sendq);
  194. skb_queue_head_init(&d->skbpool);
  195. init_timer(&d->timer);
  196. d->timer.data = (ulong) d;
  197. d->timer.function = dummy_timer;
  198. d->timer.expires = jiffies + HZ;
  199. add_timer(&d->timer);
  200. d->bufpool = NULL; /* defer to aoeblk_gdalloc */
  201. d->tgt = d->targets;
  202. INIT_LIST_HEAD(&d->bufq);
  203. d->sysminor = sysminor;
  204. d->aoemajor = AOEMAJOR(sysminor);
  205. d->aoeminor = AOEMINOR(sysminor);
  206. d->mintimer = MINTIMER;
  207. d->next = devlist;
  208. devlist = d;
  209. out:
  210. spin_unlock_irqrestore(&devlist_lock, flags);
  211. return d;
  212. }
  213. static void
  214. freetgt(struct aoedev *d, struct aoetgt *t)
  215. {
  216. struct frame *f, *e;
  217. f = t->frames;
  218. e = f + t->nframes;
  219. for (; f < e; f++)
  220. skbfree(f->skb);
  221. kfree(t->frames);
  222. kfree(t);
  223. }
  224. void
  225. aoedev_exit(void)
  226. {
  227. struct aoedev *d;
  228. ulong flags;
  229. while ((d = devlist)) {
  230. devlist = d->next;
  231. spin_lock_irqsave(&d->lock, flags);
  232. aoedev_downdev(d);
  233. d->flags |= DEVFL_TKILL;
  234. spin_unlock_irqrestore(&d->lock, flags);
  235. del_timer_sync(&d->timer);
  236. aoedev_freedev(d);
  237. }
  238. }
  239. int __init
  240. aoedev_init(void)
  241. {
  242. return 0;
  243. }