Lines Matching full:volume

2 /* vnode and volume validity verification.
19 * (2) On a RW volume, in response to certain vnode (inode)-accessing RPC
27 * (3) On a RO (or Backup) volume, in response to certain vnode-accessing RPC
28 * calls, each server maintains a time-limited per-volume promise that it
29 * will send us a CB.CallBack request if the RO volume is updated to a
30 * snapshot of the RW volume ("vos release"). This is an atomic event
31 * that cuts over all instances of the RO volume across multiple servers
34 * Note that a volume-level callbacks may also be sent for other reasons,
35 * such as the volumeserver taking over control of the volume from the
41 * (4) Certain RPC calls include a volume information record "VolSync" in
42 * their reply. This contains a creation date for the volume that should
43 * remain unchanged for a RW volume (but will be changed if the volume is
45 * when a RO volume is released.
50 * a volume have been altered since we last checked a vnode.
60 * recognised that a RO volume has been updated.
70 * (1) When a volume-level CB.CallBack occurs, we increment ->cb_v_break on
71 * the volume and reset ->cb_expires_at (ie. set AFS_NO_CB_PROMISE) on the
72 * volume and volume's server record.
74 * (2) When a CB.InitCallBackState occurs, we treat this as a volume-level
75 * callback break on all the volumes that have been using that volume
85 * ->cb_v_break match, and if they don't, we lock volume->cb_check_lock
88 * After checking the volume, we check the vnode. If there's a mismatch
89 * between the volume counters and the vnode's mirrors of those counters,
95 * (A) If the Creation timestamp has changed on a RW volume or regressed
96 * on a RO volume, we try to increment ->cb_scrub; if it advances on a
97 * RO volume, we assume "vos release" happened and try to increment
107 * volume->cb_v_check is then set to ->cb_v_break.
111 * the volume and the volume's server record.
118 * Check the validity of a vnode/inode and its parent volume.
122 const struct afs_volume *volume = vnode->volume; in afs_check_validity() local
125 if (atomic_read(&volume->cb_v_check) != atomic_read(&volume->cb_v_break) || in afs_check_validity()
127 volume->cb_expires_at <= deadline || in afs_check_validity()
128 vnode->cb_ro_snapshot != atomic_read(&volume->cb_ro_snapshot) || in afs_check_validity()
129 vnode->cb_scrub != atomic_read(&volume->cb_scrub) || in afs_check_validity()
141 static bool __afs_is_server_excluded(struct afs_operation *op, struct afs_volume *volume) in __afs_is_server_excluded() argument
150 slist = rcu_dereference(volume->servers); in __afs_is_server_excluded()
164 * Update the volume's server list when the creation time changes and see if
167 static int afs_is_server_excluded(struct afs_operation *op, struct afs_volume *volume) in afs_is_server_excluded() argument
171 if (__afs_is_server_excluded(op, volume)) in afs_is_server_excluded()
174 set_bit(AFS_VOLUME_NEEDS_UPDATE, &volume->flags); in afs_is_server_excluded()
175 ret = afs_check_volume_status(op->volume, op); in afs_is_server_excluded()
179 return __afs_is_server_excluded(op, volume); in afs_is_server_excluded()
183 * Handle a change to the volume creation time in the VolSync record.
185 static int afs_update_volume_creation_time(struct afs_operation *op, struct afs_volume *volume) in afs_update_volume_creation_time() argument
188 time64_t cur = volume->creation_time; in afs_update_volume_creation_time()
193 _enter("%llx,%llx,%llx->%llx", volume->vid, cur, old, new); in afs_update_volume_creation_time()
196 volume->creation_time = new; in afs_update_volume_creation_time()
212 * our caches. For a RW vol, this will only change if the volume is in afs_update_volume_creation_time()
214 * the volume is updated to a new snapshot (eg. "vos release"). in afs_update_volume_creation_time()
216 if (volume->type == AFSVL_RWVOL) in afs_update_volume_creation_time()
218 if (volume->type == AFSVL_BACKVOL) { in afs_update_volume_creation_time()
224 /* We have an RO volume, we need to query the VL server and look at the in afs_update_volume_creation_time()
227 ret = afs_is_server_excluded(op, volume); in afs_update_volume_creation_time()
231 snap = atomic_read(&volume->cb_ro_snapshot); in afs_update_volume_creation_time()
232 trace_afs_cb_v_break(volume->vid, snap, afs_cb_break_volume_excluded); in afs_update_volume_creation_time()
237 snap = atomic_inc_return(&volume->cb_ro_snapshot); in afs_update_volume_creation_time()
238 trace_afs_cb_v_break(volume->vid, snap, afs_cb_break_for_vos_release); in afs_update_volume_creation_time()
239 volume->creation_time = new; in afs_update_volume_creation_time()
243 atomic_inc(&volume->cb_scrub); in afs_update_volume_creation_time()
244 trace_afs_cb_v_break(volume->vid, 0, afs_cb_break_for_creation_regress); in afs_update_volume_creation_time()
245 volume->creation_time = new; in afs_update_volume_creation_time()
250 * Handle a change to the volume update time in the VolSync record.
252 static void afs_update_volume_update_time(struct afs_operation *op, struct afs_volume *volume) in afs_update_volume_update_time() argument
255 time64_t cur = volume->update_time; in afs_update_volume_update_time()
259 _enter("%llx,%llx,%llx->%llx", volume->vid, cur, old, new); in afs_update_volume_update_time()
262 volume->update_time = new; in afs_update_volume_update_time()
269 /* If the volume update time changes in an unexpected way, we need to in afs_update_volume_update_time()
272 * volume is updated to a new snapshot (eg. "vos release"). in afs_update_volume_update_time()
284 atomic_inc(&volume->cb_scrub); in afs_update_volume_update_time()
285 trace_afs_cb_v_break(volume->vid, 0, reason); in afs_update_volume_update_time()
287 volume->update_time = new; in afs_update_volume_update_time()
291 static int afs_update_volume_times(struct afs_operation *op, struct afs_volume *volume) in afs_update_volume_times() argument
295 if (likely(op->volsync.creation == volume->creation_time && in afs_update_volume_times()
296 op->volsync.update == volume->update_time)) in afs_update_volume_times()
299 mutex_lock(&volume->volsync_lock); in afs_update_volume_times()
300 if (op->volsync.creation != volume->creation_time) { in afs_update_volume_times()
301 ret = afs_update_volume_creation_time(op, volume); in afs_update_volume_times()
305 if (op->volsync.update != volume->update_time) in afs_update_volume_times()
306 afs_update_volume_update_time(op, volume); in afs_update_volume_times()
308 mutex_unlock(&volume->volsync_lock); in afs_update_volume_times()
313 * Update the state of a volume, including recording the expiration time of the
321 struct afs_volume *volume = op->volume; in afs_update_volume_state() local
322 unsigned int cb_v_break = atomic_read(&volume->cb_v_break); in afs_update_volume_state()
323 unsigned int cb_v_check = atomic_read(&volume->cb_v_check); in afs_update_volume_state()
326 _enter("%llx", op->volume->vid); in afs_update_volume_state()
329 ret = afs_update_volume_times(op, volume); in afs_update_volume_state()
344 volume->cb_expires_at = expires_at; in afs_update_volume_state()
347 atomic_cmpxchg(&volume->cb_v_check, cb_v_check, op->cb_v_break); in afs_update_volume_state()
381 struct afs_volume *volume = vnode->volume; in afs_validate() local
398 /* Validate a volume after the v_break has changed or the volume in afs_validate()
399 * callback expired. We only want to do this once per volume per in afs_validate()
403 if (volume->cb_expires_at <= deadline || in afs_validate()
404 atomic_read(&volume->cb_v_check) != atomic_read(&volume->cb_v_break)) { in afs_validate()
405 ret = mutex_lock_interruptible(&volume->cb_check_lock); in afs_validate()
411 cb_ro_snapshot = atomic_read(&volume->cb_ro_snapshot); in afs_validate()
412 cb_scrub = atomic_read(&volume->cb_scrub); in afs_validate()
419 volume->cb_expires_at <= deadline || in afs_validate()
420 atomic_read(&volume->cb_v_check) != atomic_read(&volume->cb_v_break) || in afs_validate()
435 /* We can drop the volume lock now as. */ in afs_validate()
437 mutex_unlock(&volume->cb_check_lock); in afs_validate()
441 cb_ro_snapshot = atomic_read(&volume->cb_ro_snapshot); in afs_validate()
442 cb_scrub = atomic_read(&volume->cb_scrub); in afs_validate()
468 mutex_unlock(&volume->cb_check_lock); in afs_validate()