xfs_behavior.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /*
  2. * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of version 2 of the GNU General Public License as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it would be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. *
  12. * Further, this software is distributed without any warranty that it is
  13. * free of the rightful claim of any third person regarding infringement
  14. * or the like. Any license provided herein, whether implied or
  15. * otherwise, applies only to this software file. Patent licenses, if
  16. * any, provided herein do not apply to combinations of this program with
  17. * other software, or any other product whatsoever.
  18. *
  19. * You should have received a copy of the GNU General Public License along
  20. * with this program; if not, write the Free Software Foundation, Inc., 59
  21. * Temple Place - Suite 330, Boston MA 02111-1307, USA.
  22. *
  23. * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
  24. * Mountain View, CA 94043, or:
  25. *
  26. * http://www.sgi.com
  27. *
  28. * For further information regarding this notice, see:
  29. *
  30. * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
  31. *
  32. */
  33. #include "xfs.h"
  34. /*
  35. * Source file used to associate/disassociate behaviors with virtualized
  36. * objects. See xfs_behavior.h for more information about behaviors, etc.
  37. *
  38. * The implementation is split between functions in this file and macros
  39. * in xfs_behavior.h.
  40. */
  41. /*
  42. * Insert a new behavior descriptor into a behavior chain.
  43. *
  44. * The behavior chain is ordered based on the 'position' number which
  45. * lives in the first field of the ops vector (higher numbers first).
  46. *
  47. * Attemps to insert duplicate ops result in an EINVAL return code.
  48. * Otherwise, return 0 to indicate success.
  49. */
  50. int
  51. bhv_insert(bhv_head_t *bhp, bhv_desc_t *bdp)
  52. {
  53. bhv_desc_t *curdesc, *prev;
  54. int position;
  55. /*
  56. * Validate the position value of the new behavior.
  57. */
  58. position = BHV_POSITION(bdp);
  59. ASSERT(position >= BHV_POSITION_BASE && position <= BHV_POSITION_TOP);
  60. /*
  61. * Find location to insert behavior. Check for duplicates.
  62. */
  63. prev = NULL;
  64. for (curdesc = bhp->bh_first;
  65. curdesc != NULL;
  66. curdesc = curdesc->bd_next) {
  67. /* Check for duplication. */
  68. if (curdesc->bd_ops == bdp->bd_ops) {
  69. ASSERT(0);
  70. return EINVAL;
  71. }
  72. /* Find correct position */
  73. if (position >= BHV_POSITION(curdesc)) {
  74. ASSERT(position != BHV_POSITION(curdesc));
  75. break; /* found it */
  76. }
  77. prev = curdesc;
  78. }
  79. if (prev == NULL) {
  80. /* insert at front of chain */
  81. bdp->bd_next = bhp->bh_first;
  82. bhp->bh_first = bdp;
  83. } else {
  84. /* insert after prev */
  85. bdp->bd_next = prev->bd_next;
  86. prev->bd_next = bdp;
  87. }
  88. return 0;
  89. }
  90. /*
  91. * Remove a behavior descriptor from a position in a behavior chain;
  92. * the postition is guaranteed not to be the first position.
  93. * Should only be called by the bhv_remove() macro.
  94. */
  95. void
  96. bhv_remove_not_first(bhv_head_t *bhp, bhv_desc_t *bdp)
  97. {
  98. bhv_desc_t *curdesc, *prev;
  99. ASSERT(bhp->bh_first != NULL);
  100. ASSERT(bhp->bh_first->bd_next != NULL);
  101. prev = bhp->bh_first;
  102. for (curdesc = bhp->bh_first->bd_next;
  103. curdesc != NULL;
  104. curdesc = curdesc->bd_next) {
  105. if (curdesc == bdp)
  106. break; /* found it */
  107. prev = curdesc;
  108. }
  109. ASSERT(curdesc == bdp);
  110. prev->bd_next = bdp->bd_next; /* remove from after prev */
  111. }
  112. /*
  113. * Look for a specific ops vector on the specified behavior chain.
  114. * Return the associated behavior descriptor. Or NULL, if not found.
  115. */
  116. bhv_desc_t *
  117. bhv_lookup(bhv_head_t *bhp, void *ops)
  118. {
  119. bhv_desc_t *curdesc;
  120. for (curdesc = bhp->bh_first;
  121. curdesc != NULL;
  122. curdesc = curdesc->bd_next) {
  123. if (curdesc->bd_ops == ops)
  124. return curdesc;
  125. }
  126. return NULL;
  127. }
  128. /*
  129. * Looks for the first behavior within a specified range of positions.
  130. * Return the associated behavior descriptor. Or NULL, if none found.
  131. */
  132. bhv_desc_t *
  133. bhv_lookup_range(bhv_head_t *bhp, int low, int high)
  134. {
  135. bhv_desc_t *curdesc;
  136. for (curdesc = bhp->bh_first;
  137. curdesc != NULL;
  138. curdesc = curdesc->bd_next) {
  139. int position = BHV_POSITION(curdesc);
  140. if (position <= high) {
  141. if (position >= low)
  142. return curdesc;
  143. return NULL;
  144. }
  145. }
  146. return NULL;
  147. }
  148. /*
  149. * Return the base behavior in the chain, or NULL if the chain
  150. * is empty.
  151. *
  152. * The caller has not read locked the behavior chain, so acquire the
  153. * lock before traversing the chain.
  154. */
  155. bhv_desc_t *
  156. bhv_base(bhv_head_t *bhp)
  157. {
  158. bhv_desc_t *curdesc;
  159. for (curdesc = bhp->bh_first;
  160. curdesc != NULL;
  161. curdesc = curdesc->bd_next) {
  162. if (curdesc->bd_next == NULL) {
  163. return curdesc;
  164. }
  165. }
  166. return NULL;
  167. }
  168. void
  169. bhv_head_init(
  170. bhv_head_t *bhp,
  171. char *name)
  172. {
  173. bhp->bh_first = NULL;
  174. }
  175. void
  176. bhv_insert_initial(
  177. bhv_head_t *bhp,
  178. bhv_desc_t *bdp)
  179. {
  180. ASSERT(bhp->bh_first == NULL);
  181. (bhp)->bh_first = bdp;
  182. }
  183. void
  184. bhv_head_destroy(
  185. bhv_head_t *bhp)
  186. {
  187. ASSERT(bhp->bh_first == NULL);
  188. }