util.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * net/9p/util.c
  3. *
  4. * This file contains some helper functions
  5. *
  6. * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
  7. * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
  8. * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2
  12. * as published by the Free Software Foundation.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to:
  21. * Free Software Foundation
  22. * 51 Franklin Street, Fifth Floor
  23. * Boston, MA 02111-1301 USA
  24. *
  25. */
  26. #include <linux/module.h>
  27. #include <linux/errno.h>
  28. #include <linux/fs.h>
  29. #include <linux/sched.h>
  30. #include <linux/parser.h>
  31. #include <linux/idr.h>
  32. #include <net/9p/9p.h>
  33. /**
  34. * struct p9_idpool - per-connection accounting for tag idpool
  35. * @lock: protects the pool
  36. * @pool: idr to allocate tag id from
  37. *
  38. */
  39. struct p9_idpool {
  40. spinlock_t lock;
  41. struct idr pool;
  42. };
  43. /**
  44. * p9_idpool_create - create a new per-connection id pool
  45. *
  46. */
  47. struct p9_idpool *p9_idpool_create(void)
  48. {
  49. struct p9_idpool *p;
  50. p = kmalloc(sizeof(struct p9_idpool), GFP_KERNEL);
  51. if (!p)
  52. return ERR_PTR(-ENOMEM);
  53. spin_lock_init(&p->lock);
  54. idr_init(&p->pool);
  55. return p;
  56. }
  57. EXPORT_SYMBOL(p9_idpool_create);
  58. /**
  59. * p9_idpool_destroy - create a new per-connection id pool
  60. * @p: idpool to destory
  61. */
  62. void p9_idpool_destroy(struct p9_idpool *p)
  63. {
  64. idr_destroy(&p->pool);
  65. kfree(p);
  66. }
  67. EXPORT_SYMBOL(p9_idpool_destroy);
  68. /**
  69. * p9_idpool_get - allocate numeric id from pool
  70. * @p: pool to allocate from
  71. *
  72. * Bugs: This seems to be an awful generic function, should it be in idr.c with
  73. * the lock included in struct idr?
  74. */
  75. int p9_idpool_get(struct p9_idpool *p)
  76. {
  77. int i = 0;
  78. int error;
  79. unsigned long flags;
  80. retry:
  81. if (idr_pre_get(&p->pool, GFP_KERNEL) == 0)
  82. return 0;
  83. spin_lock_irqsave(&p->lock, flags);
  84. /* no need to store exactly p, we just need something non-null */
  85. error = idr_get_new(&p->pool, p, &i);
  86. spin_unlock_irqrestore(&p->lock, flags);
  87. if (error == -EAGAIN)
  88. goto retry;
  89. else if (error)
  90. return -1;
  91. P9_DPRINTK(P9_DEBUG_MUX, " id %d pool %p\n", i, p);
  92. return i;
  93. }
  94. EXPORT_SYMBOL(p9_idpool_get);
  95. /**
  96. * p9_idpool_put - release numeric id from pool
  97. * @id: numeric id which is being released
  98. * @p: pool to release id into
  99. *
  100. * Bugs: This seems to be an awful generic function, should it be in idr.c with
  101. * the lock included in struct idr?
  102. */
  103. void p9_idpool_put(int id, struct p9_idpool *p)
  104. {
  105. unsigned long flags;
  106. P9_DPRINTK(P9_DEBUG_MUX, " id %d pool %p\n", id, p);
  107. spin_lock_irqsave(&p->lock, flags);
  108. idr_remove(&p->pool, id);
  109. spin_unlock_irqrestore(&p->lock, flags);
  110. }
  111. EXPORT_SYMBOL(p9_idpool_put);
  112. /**
  113. * p9_idpool_check - check if the specified id is available
  114. * @id: id to check
  115. * @p: pool to check
  116. */
  117. int p9_idpool_check(int id, struct p9_idpool *p)
  118. {
  119. return idr_find(&p->pool, id) != NULL;
  120. }
  121. EXPORT_SYMBOL(p9_idpool_check);