util.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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. struct p9_idpool {
  34. spinlock_t lock;
  35. struct idr pool;
  36. };
  37. struct p9_idpool *p9_idpool_create(void)
  38. {
  39. struct p9_idpool *p;
  40. p = kmalloc(sizeof(struct p9_idpool), GFP_KERNEL);
  41. if (!p)
  42. return ERR_PTR(-ENOMEM);
  43. spin_lock_init(&p->lock);
  44. idr_init(&p->pool);
  45. return p;
  46. }
  47. EXPORT_SYMBOL(p9_idpool_create);
  48. void p9_idpool_destroy(struct p9_idpool *p)
  49. {
  50. idr_destroy(&p->pool);
  51. kfree(p);
  52. }
  53. EXPORT_SYMBOL(p9_idpool_destroy);
  54. /**
  55. * p9_idpool_get - allocate numeric id from pool
  56. * @p - pool to allocate from
  57. *
  58. * XXX - This seems to be an awful generic function, should it be in idr.c with
  59. * the lock included in struct idr?
  60. */
  61. int p9_idpool_get(struct p9_idpool *p)
  62. {
  63. int i = 0;
  64. int error;
  65. unsigned int flags;
  66. retry:
  67. if (idr_pre_get(&p->pool, GFP_KERNEL) == 0)
  68. return 0;
  69. spin_lock_irqsave(&p->lock, flags);
  70. /* no need to store exactly p, we just need something non-null */
  71. error = idr_get_new(&p->pool, p, &i);
  72. spin_unlock_irqrestore(&p->lock, flags);
  73. if (error == -EAGAIN)
  74. goto retry;
  75. else if (error)
  76. return -1;
  77. return i;
  78. }
  79. EXPORT_SYMBOL(p9_idpool_get);
  80. /**
  81. * p9_idpool_put - release numeric id from pool
  82. * @p - pool to allocate from
  83. *
  84. * XXX - This seems to be an awful generic function, should it be in idr.c with
  85. * the lock included in struct idr?
  86. */
  87. void p9_idpool_put(int id, struct p9_idpool *p)
  88. {
  89. unsigned int flags;
  90. spin_lock_irqsave(&p->lock, flags);
  91. idr_remove(&p->pool, id);
  92. spin_unlock_irqrestore(&p->lock, flags);
  93. }
  94. EXPORT_SYMBOL(p9_idpool_put);
  95. /**
  96. * p9_idpool_check - check if the specified id is available
  97. * @id - id to check
  98. * @p - pool
  99. */
  100. int p9_idpool_check(int id, struct p9_idpool *p)
  101. {
  102. return idr_find(&p->pool, id) != NULL;
  103. }
  104. EXPORT_SYMBOL(p9_idpool_check);