util.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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. struct semaphore 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. init_MUTEX(&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. retry:
  66. if (idr_pre_get(&p->pool, GFP_KERNEL) == 0)
  67. return 0;
  68. if (down_interruptible(&p->lock) == -EINTR) {
  69. P9_EPRINTK(KERN_WARNING, "Interrupted while locking\n");
  70. return -1;
  71. }
  72. /* no need to store exactly p, we just need something non-null */
  73. error = idr_get_new(&p->pool, p, &i);
  74. up(&p->lock);
  75. if (error == -EAGAIN)
  76. goto retry;
  77. else if (error)
  78. return -1;
  79. return i;
  80. }
  81. EXPORT_SYMBOL(p9_idpool_get);
  82. /**
  83. * p9_idpool_put - release numeric id from pool
  84. * @p - pool to allocate from
  85. *
  86. * XXX - This seems to be an awful generic function, should it be in idr.c with
  87. * the lock included in struct idr?
  88. */
  89. void p9_idpool_put(int id, struct p9_idpool *p)
  90. {
  91. if (down_interruptible(&p->lock) == -EINTR) {
  92. P9_EPRINTK(KERN_WARNING, "Interrupted while locking\n");
  93. return;
  94. }
  95. idr_remove(&p->pool, id);
  96. up(&p->lock);
  97. }
  98. EXPORT_SYMBOL(p9_idpool_put);
  99. /**
  100. * p9_idpool_check - check if the specified id is available
  101. * @id - id to check
  102. * @p - pool
  103. */
  104. int p9_idpool_check(int id, struct p9_idpool *p)
  105. {
  106. return idr_find(&p->pool, id) != NULL;
  107. }
  108. EXPORT_SYMBOL(p9_idpool_check);