util.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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 <linux/slab.h>
  33. #include <net/9p/9p.h>
  34. /**
  35. * struct p9_idpool - per-connection accounting for tag idpool
  36. * @lock: protects the pool
  37. * @pool: idr to allocate tag id from
  38. *
  39. */
  40. struct p9_idpool {
  41. spinlock_t lock;
  42. struct idr pool;
  43. };
  44. /**
  45. * p9_idpool_create - create a new per-connection id pool
  46. *
  47. */
  48. struct p9_idpool *p9_idpool_create(void)
  49. {
  50. struct p9_idpool *p;
  51. p = kmalloc(sizeof(struct p9_idpool), GFP_KERNEL);
  52. if (!p)
  53. return ERR_PTR(-ENOMEM);
  54. spin_lock_init(&p->lock);
  55. idr_init(&p->pool);
  56. return p;
  57. }
  58. EXPORT_SYMBOL(p9_idpool_create);
  59. /**
  60. * p9_idpool_destroy - create a new per-connection id pool
  61. * @p: idpool to destroy
  62. */
  63. void p9_idpool_destroy(struct p9_idpool *p)
  64. {
  65. idr_destroy(&p->pool);
  66. kfree(p);
  67. }
  68. EXPORT_SYMBOL(p9_idpool_destroy);
  69. /**
  70. * p9_idpool_get - allocate numeric id from pool
  71. * @p: pool to allocate from
  72. *
  73. * Bugs: This seems to be an awful generic function, should it be in idr.c with
  74. * the lock included in struct idr?
  75. */
  76. int p9_idpool_get(struct p9_idpool *p)
  77. {
  78. int i = 0;
  79. int error;
  80. unsigned long flags;
  81. retry:
  82. if (idr_pre_get(&p->pool, GFP_NOFS) == 0)
  83. return -1;
  84. spin_lock_irqsave(&p->lock, flags);
  85. /* no need to store exactly p, we just need something non-null */
  86. error = idr_get_new(&p->pool, p, &i);
  87. spin_unlock_irqrestore(&p->lock, flags);
  88. if (error == -EAGAIN)
  89. goto retry;
  90. else if (error)
  91. return -1;
  92. p9_debug(P9_DEBUG_MUX, " id %d pool %p\n", i, p);
  93. return i;
  94. }
  95. EXPORT_SYMBOL(p9_idpool_get);
  96. /**
  97. * p9_idpool_put - release numeric id from pool
  98. * @id: numeric id which is being released
  99. * @p: pool to release id into
  100. *
  101. * Bugs: This seems to be an awful generic function, should it be in idr.c with
  102. * the lock included in struct idr?
  103. */
  104. void p9_idpool_put(int id, struct p9_idpool *p)
  105. {
  106. unsigned long flags;
  107. p9_debug(P9_DEBUG_MUX, " id %d pool %p\n", id, p);
  108. spin_lock_irqsave(&p->lock, flags);
  109. idr_remove(&p->pool, id);
  110. spin_unlock_irqrestore(&p->lock, flags);
  111. }
  112. EXPORT_SYMBOL(p9_idpool_put);
  113. /**
  114. * p9_idpool_check - check if the specified id is available
  115. * @id: id to check
  116. * @p: pool to check
  117. */
  118. int p9_idpool_check(int id, struct p9_idpool *p)
  119. {
  120. return idr_find(&p->pool, id) != NULL;
  121. }
  122. EXPORT_SYMBOL(p9_idpool_check);