a26a6dccdefc84844039e3096d78e632a5f5f3b1
[openafs.git] / src / vol / volume_inline.h
1 /*
2  * Copyright 2005-2008, Sine Nomine Associates and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #ifndef _AFS_VOL_VOLUME_INLINE_H
11 #define _AFS_VOL_VOLUME_INLINE_H 1
12
13 #include "volume.h"
14 /**
15  * tell caller whether the given program type represents a salvaging
16  * program.
17  *
18  * @param type  program type enumeration
19  *
20  * @return whether program state is a salvager
21  *   @retval 0  type is a non-salvaging program
22  *   @retval 1  type is a salvaging program
23  */
24 static_inline int
25 VIsSalvager(ProgramType type)
26 {
27     switch(type) {
28     case salvager:
29     case salvageServer:
30         return 1;
31     }
32     return 0;
33 }
34
35 /***************************************************/
36 /* demand attach fs state machine routines         */
37 /***************************************************/
38
39 #ifdef AFS_DEMAND_ATTACH_FS
40 /**
41  * tells caller whether or not the current state requires
42  * exclusive access without holding glock.
43  *
44  * @param state  volume state enumeration
45  *
46  * @return whether volume state is a mutually exclusive state
47  *   @retval 0  no, state is re-entrant
48  *   @retval 1  yes, state is mutually exclusive
49  *
50  * @note DEMAND_ATTACH_FS only
51  */
52 static_inline int
53 VIsExclusiveState(VolState state)
54 {
55     switch (state) {
56     case VOL_STATE_UPDATING:
57     case VOL_STATE_ATTACHING:
58     case VOL_STATE_GET_BITMAP:
59     case VOL_STATE_HDR_LOADING:
60     case VOL_STATE_HDR_ATTACHING:
61     case VOL_STATE_OFFLINING:
62     case VOL_STATE_DETACHING:
63     case VOL_STATE_SALVSYNC_REQ:
64     case VOL_STATE_VNODE_ALLOC:
65     case VOL_STATE_VNODE_GET:
66     case VOL_STATE_VNODE_CLOSE:
67     case VOL_STATE_VNODE_RELEASE:
68         return 1;
69     }
70     return 0;
71 }
72
73 /**
74  * tell caller whether V_attachState is an error condition.
75  *
76  * @param state  volume state enumeration
77  *
78  * @return whether volume state is in error state
79  *   @retval 0  state is not an error state
80  *   @retval 1  state is an error state
81  *
82  * @note DEMAND_ATTACH_FS only
83  */
84 static_inline int
85 VIsErrorState(VolState state)
86 {
87     switch (state) {
88     case VOL_STATE_ERROR:
89     case VOL_STATE_SALVAGING:
90         return 1;
91     }
92     return 0;
93 }
94
95 /**
96  * tell caller whether V_attachState is an offline condition.
97  *
98  * @param state  volume state enumeration
99  *
100  * @return whether volume state is in offline state
101  *   @retval 0  state is not an offline state
102  *   @retval 1  state is an offline state
103  *
104  * @note DEMAND_ATTACH_FS only
105  */
106 static_inline int
107 VIsOfflineState(VolState state)
108 {
109     switch (state) {
110     case VOL_STATE_UNATTACHED:
111     case VOL_STATE_ERROR:
112     case VOL_STATE_SALVAGING:
113         return 1;
114     }
115     return 0;
116 }
117
118 /**
119  * tell caller whether V_attachState is valid.
120  *
121  * @param state  volume state enumeration
122  *
123  * @return whether volume state is a mutually exclusive state
124  *   @retval 0  no, state is not valid
125  *   @retval 1  yes, state is a valid enumeration member
126  *
127  * @note DEMAND_ATTACH_FS only
128  *
129  * @note do we really want to treat VOL_STATE_FREED as valid?
130  */
131 static_inline int
132 VIsValidState(VolState state)
133 {
134     if ((state >= 0) && 
135         (state < VOL_STATE_COUNT)) {
136         return 1;
137     }
138     return 0;
139 }
140
141 /**
142  * increment volume-package internal refcount.
143  *
144  * @param vp  volume object pointer
145  *
146  * @internal volume package internal use only
147  *
148  * @pre VOL_LOCK must be held
149  *
150  * @post volume waiters refcount is incremented
151  *
152  * @see VCancelReservation_r
153  *
154  * @note DEMAND_ATTACH_FS only
155  */
156 static_inline void
157 VCreateReservation_r(Volume * vp)
158 {
159     vp->nWaiters++;
160 }
161
162 /**
163  * wait for the volume to change states.
164  *
165  * @param vp  volume object pointer
166  *
167  * @pre VOL_LOCK held; ref held on volume
168  *
169  * @post VOL_LOCK held; volume state has changed from previous value
170  *
171  * @note DEMAND_ATTACH_FS only
172  */
173 static_inline void
174 VWaitStateChange_r(Volume * vp)
175 {
176     VolState state_save = V_attachState(vp);
177
178     assert(vp->nWaiters || vp->nUsers);
179     do {
180         VOL_CV_WAIT(&V_attachCV(vp));
181     } while (V_attachState(vp) == state_save);
182     assert(V_attachState(vp) != VOL_STATE_FREED);
183 }
184
185 /**
186  * wait for blocking ops to end.
187  *
188  * @pre VOL_LOCK held; ref held on volume
189  *
190  * @post VOL_LOCK held; volume not in exclusive state
191  *
192  * @param vp  volume object pointer
193  *
194  * @note DEMAND_ATTACH_FS only
195  */
196 static_inline void
197 VWaitExclusiveState_r(Volume * vp)
198 {
199     assert(vp->nWaiters || vp->nUsers);
200     while (VIsExclusiveState(V_attachState(vp))) {
201         VOL_CV_WAIT(&V_attachCV(vp));
202     }
203     assert(V_attachState(vp) != VOL_STATE_FREED);
204 }
205
206 /**
207  * change state, and notify other threads,
208  * return previous state to caller.
209  *
210  * @param vp         pointer to volume object
211  * @param new_state  new volume state value
212  * @pre VOL_LOCK held
213  *
214  * @post volume state changed; stats updated
215  *
216  * @return previous volume state
217  *
218  * @note DEMAND_ATTACH_FS only
219  */
220 static_inline VolState
221 VChangeState_r(Volume * vp, VolState new_state)
222 {
223     VolState old_state = V_attachState(vp);
224
225     /* XXX profiling need to make sure these counters
226      * don't kill performance... */
227     VStats.state_levels[old_state]--;
228     VStats.state_levels[new_state]++;
229
230     V_attachState(vp) = new_state;
231     assert(pthread_cond_broadcast(&V_attachCV(vp)) == 0);
232     return old_state;
233 }
234
235 #endif /* AFS_DEMAND_ATTACH_FS */
236
237 #endif /* _AFS_VOL_VOLUME_INLINE_H */