2 * Copyright 2005-2008, Sine Nomine Associates and others.
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
10 #ifndef _AFS_VOL_VOLUME_INLINE_H
11 #define _AFS_VOL_VOLUME_INLINE_H 1
15 * tell caller whether the given program type represents a salvaging
18 * @param type program type enumeration
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
25 VIsSalvager(ProgramType type)
38 * tells caller whether or not we need to lock the entire partition when
41 * @return whether or not we need to lock the partition
42 * @retval 0 no, we do not
43 * @retval 1 yes, we do
46 VRequiresPartLock(void)
48 switch (programType) {
58 * tells caller whether we should check the inUse field in the volume
59 * header when attaching a volume.
61 * If we check inUse, that generally means we will salvage the volume
62 * (or put it in an error state) if we detect that another program
63 * claims to be using the volume when we try to attach. We don't always
64 * want to do that, since sometimes we know that the volume may be in
65 * use by another program, e.g. when we are attaching with V_PEEK, and
68 * @param mode the mode of attachment for the volume
70 * @return whether or not we should check inUse
71 * @retval 0 no, we should not check inUse
72 * @retval 1 yes, we should check inUse
75 VShouldCheckInUse(int mode)
77 if (programType == fileServer) {
80 if (VCanUseFSSYNC() && mode != V_SECRETLY && mode != V_PEEK) {
81 /* If we can FSSYNC, we assume we checked out the volume from
82 * the fileserver, so inUse should not be set. If we checked out
83 * with V_SECRETLY or V_PEEK, though, we didn't ask the
84 * fileserver, so don't check inUse. */
90 /***************************************************/
91 /* demand attach fs state machine routines */
92 /***************************************************/
94 #ifdef AFS_DEMAND_ATTACH_FS
96 * tells caller whether or not the current state requires
97 * exclusive access without holding glock.
99 * @param state volume state enumeration
101 * @return whether volume state is a mutually exclusive state
102 * @retval 0 no, state is re-entrant
103 * @retval 1 yes, state is mutually exclusive
105 * @note DEMAND_ATTACH_FS only
108 VIsExclusiveState(VolState state)
111 case VOL_STATE_UPDATING:
112 case VOL_STATE_ATTACHING:
113 case VOL_STATE_GET_BITMAP:
114 case VOL_STATE_HDR_LOADING:
115 case VOL_STATE_HDR_ATTACHING:
116 case VOL_STATE_OFFLINING:
117 case VOL_STATE_DETACHING:
118 case VOL_STATE_SALVSYNC_REQ:
119 case VOL_STATE_VNODE_ALLOC:
120 case VOL_STATE_VNODE_GET:
121 case VOL_STATE_VNODE_CLOSE:
122 case VOL_STATE_VNODE_RELEASE:
123 case VOL_STATE_VLRU_ADD:
131 * tell caller whether V_attachState is an error condition.
133 * @param state volume state enumeration
135 * @return whether volume state is in error state
136 * @retval 0 state is not an error state
137 * @retval 1 state is an error state
139 * @note DEMAND_ATTACH_FS only
142 VIsErrorState(VolState state)
145 case VOL_STATE_ERROR:
146 case VOL_STATE_SALVAGING:
154 * tell caller whether V_attachState is an offline condition.
156 * @param state volume state enumeration
158 * @return whether volume state is in offline state
159 * @retval 0 state is not an offline state
160 * @retval 1 state is an offline state
162 * @note DEMAND_ATTACH_FS only
165 VIsOfflineState(VolState state)
168 case VOL_STATE_UNATTACHED:
169 case VOL_STATE_ERROR:
170 case VOL_STATE_SALVAGING:
178 * tell caller whether V_attachState is valid.
180 * @param state volume state enumeration
182 * @return whether volume state is a mutually exclusive state
183 * @retval 0 no, state is not valid
184 * @retval 1 yes, state is a valid enumeration member
186 * @note DEMAND_ATTACH_FS only
188 * @note do we really want to treat VOL_STATE_FREED as valid?
191 VIsValidState(VolState state)
194 (state < VOL_STATE_COUNT)) {
201 * increment volume-package internal refcount.
203 * @param vp volume object pointer
205 * @internal volume package internal use only
207 * @pre VOL_LOCK must be held
209 * @post volume waiters refcount is incremented
211 * @see VCancelReservation_r
213 * @note DEMAND_ATTACH_FS only
216 VCreateReservation_r(Volume * vp)
222 * wait for the volume to change states.
224 * @param vp volume object pointer
226 * @pre VOL_LOCK held; ref held on volume
228 * @post VOL_LOCK held; volume state has changed from previous value
230 * @note DEMAND_ATTACH_FS only
233 VWaitStateChange_r(Volume * vp)
235 VolState state_save = V_attachState(vp);
237 assert(vp->nWaiters || vp->nUsers);
239 VOL_CV_WAIT(&V_attachCV(vp));
240 } while (V_attachState(vp) == state_save);
241 assert(V_attachState(vp) != VOL_STATE_FREED);
245 * wait for blocking ops to end.
247 * @pre VOL_LOCK held; ref held on volume
249 * @post VOL_LOCK held; volume not in exclusive state
251 * @param vp volume object pointer
253 * @note DEMAND_ATTACH_FS only
256 VWaitExclusiveState_r(Volume * vp)
258 assert(vp->nWaiters || vp->nUsers);
259 while (VIsExclusiveState(V_attachState(vp))) {
260 VOL_CV_WAIT(&V_attachCV(vp));
262 assert(V_attachState(vp) != VOL_STATE_FREED);
266 * change state, and notify other threads,
267 * return previous state to caller.
269 * @param vp pointer to volume object
270 * @param new_state new volume state value
273 * @post volume state changed; stats updated
275 * @return previous volume state
277 * @note DEMAND_ATTACH_FS only
279 static_inline VolState
280 VChangeState_r(Volume * vp, VolState new_state)
282 VolState old_state = V_attachState(vp);
284 /* XXX profiling need to make sure these counters
285 * don't kill performance... */
286 VStats.state_levels[old_state]--;
287 VStats.state_levels[new_state]++;
289 V_attachState(vp) = new_state;
290 assert(pthread_cond_broadcast(&V_attachCV(vp)) == 0);
294 #endif /* AFS_DEMAND_ATTACH_FS */
296 #define VENUMCASE(en) \
302 * translate a ProgramType code to a string.
304 * @param[in] type ProgramType numeric code
306 * @return a human-readable string for that program type
307 * @retval "**UNKNOWN**" an unknown ProgramType was given
310 VPTypeToString(ProgramType type)
313 VENUMCASE(fileServer);
314 VENUMCASE(volumeUtility);
316 VENUMCASE(salvageServer);
317 VENUMCASE(debugUtility);
318 VENUMCASE(volumeServer);
319 VENUMCASE(volumeSalvager);
321 return "**UNKNOWN**";
327 #endif /* _AFS_VOL_VOLUME_INLINE_H */