make VOL_STATE_VLRU_ADD exclusive
[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     default:
32         return 0;
33     }
34 }
35
36 /***************************************************/
37 /* demand attach fs state machine routines         */
38 /***************************************************/
39
40 #ifdef AFS_DEMAND_ATTACH_FS
41 /**
42  * tells caller whether or not the current state requires
43  * exclusive access without holding glock.
44  *
45  * @param state  volume state enumeration
46  *
47  * @return whether volume state is a mutually exclusive state
48  *   @retval 0  no, state is re-entrant
49  *   @retval 1  yes, state is mutually exclusive
50  *
51  * @note DEMAND_ATTACH_FS only
52  */
53 static_inline int
54 VIsExclusiveState(VolState state)
55 {
56     switch (state) {
57     case VOL_STATE_UPDATING:
58     case VOL_STATE_ATTACHING:
59     case VOL_STATE_GET_BITMAP:
60     case VOL_STATE_HDR_LOADING:
61     case VOL_STATE_HDR_ATTACHING:
62     case VOL_STATE_OFFLINING:
63     case VOL_STATE_DETACHING:
64     case VOL_STATE_SALVSYNC_REQ:
65     case VOL_STATE_VNODE_ALLOC:
66     case VOL_STATE_VNODE_GET:
67     case VOL_STATE_VNODE_CLOSE:
68     case VOL_STATE_VNODE_RELEASE:
69     case VOL_STATE_VLRU_ADD:
70         return 1;
71     default:
72         return 0;
73     }
74 }
75
76 /**
77  * tell caller whether V_attachState is an error condition.
78  *
79  * @param state  volume state enumeration
80  *
81  * @return whether volume state is in error state
82  *   @retval 0  state is not an error state
83  *   @retval 1  state is an error state
84  *
85  * @note DEMAND_ATTACH_FS only
86  */
87 static_inline int
88 VIsErrorState(VolState state)
89 {
90     switch (state) {
91     case VOL_STATE_ERROR:
92     case VOL_STATE_SALVAGING:
93         return 1;
94     default:
95         return 0;
96     }
97 }
98
99 /**
100  * tell caller whether V_attachState is an offline condition.
101  *
102  * @param state  volume state enumeration
103  *
104  * @return whether volume state is in offline state
105  *   @retval 0  state is not an offline state
106  *   @retval 1  state is an offline state
107  *
108  * @note DEMAND_ATTACH_FS only
109  */
110 static_inline int
111 VIsOfflineState(VolState state)
112 {
113     switch (state) {
114     case VOL_STATE_UNATTACHED:
115     case VOL_STATE_ERROR:
116     case VOL_STATE_SALVAGING:
117         return 1;
118     default:
119         return 0;
120     }
121 }
122
123 /**
124  * tell caller whether V_attachState is valid.
125  *
126  * @param state  volume state enumeration
127  *
128  * @return whether volume state is a mutually exclusive state
129  *   @retval 0  no, state is not valid
130  *   @retval 1  yes, state is a valid enumeration member
131  *
132  * @note DEMAND_ATTACH_FS only
133  *
134  * @note do we really want to treat VOL_STATE_FREED as valid?
135  */
136 static_inline int
137 VIsValidState(VolState state)
138 {
139     if ((state >= 0) && 
140         (state < VOL_STATE_COUNT)) {
141         return 1;
142     }
143     return 0;
144 }
145
146 /**
147  * increment volume-package internal refcount.
148  *
149  * @param vp  volume object pointer
150  *
151  * @internal volume package internal use only
152  *
153  * @pre VOL_LOCK must be held
154  *
155  * @post volume waiters refcount is incremented
156  *
157  * @see VCancelReservation_r
158  *
159  * @note DEMAND_ATTACH_FS only
160  */
161 static_inline void
162 VCreateReservation_r(Volume * vp)
163 {
164     vp->nWaiters++;
165 }
166
167 /**
168  * wait for the volume to change states.
169  *
170  * @param vp  volume object pointer
171  *
172  * @pre VOL_LOCK held; ref held on volume
173  *
174  * @post VOL_LOCK held; volume state has changed from previous value
175  *
176  * @note DEMAND_ATTACH_FS only
177  */
178 static_inline void
179 VWaitStateChange_r(Volume * vp)
180 {
181     VolState state_save = V_attachState(vp);
182
183     assert(vp->nWaiters || vp->nUsers);
184     do {
185         VOL_CV_WAIT(&V_attachCV(vp));
186     } while (V_attachState(vp) == state_save);
187     assert(V_attachState(vp) != VOL_STATE_FREED);
188 }
189
190 /**
191  * wait for blocking ops to end.
192  *
193  * @pre VOL_LOCK held; ref held on volume
194  *
195  * @post VOL_LOCK held; volume not in exclusive state
196  *
197  * @param vp  volume object pointer
198  *
199  * @note DEMAND_ATTACH_FS only
200  */
201 static_inline void
202 VWaitExclusiveState_r(Volume * vp)
203 {
204     assert(vp->nWaiters || vp->nUsers);
205     while (VIsExclusiveState(V_attachState(vp))) {
206         VOL_CV_WAIT(&V_attachCV(vp));
207     }
208     assert(V_attachState(vp) != VOL_STATE_FREED);
209 }
210
211 /**
212  * change state, and notify other threads,
213  * return previous state to caller.
214  *
215  * @param vp         pointer to volume object
216  * @param new_state  new volume state value
217  * @pre VOL_LOCK held
218  *
219  * @post volume state changed; stats updated
220  *
221  * @return previous volume state
222  *
223  * @note DEMAND_ATTACH_FS only
224  */
225 static_inline VolState
226 VChangeState_r(Volume * vp, VolState new_state)
227 {
228     VolState old_state = V_attachState(vp);
229
230     /* XXX profiling need to make sure these counters
231      * don't kill performance... */
232     VStats.state_levels[old_state]--;
233     VStats.state_levels[new_state]++;
234
235     V_attachState(vp) = new_state;
236     assert(pthread_cond_broadcast(&V_attachCV(vp)) == 0);
237     return old_state;
238 }
239
240 #endif /* AFS_DEMAND_ATTACH_FS */
241
242 #endif /* _AFS_VOL_VOLUME_INLINE_H */