Lines Matching +full:one +full:- +full:cell
1 // SPDX-License-Identifier: GPL-2.0-or-later
14 #include <keys/rxrpc-type.h>
23 struct key *afs_request_key(struct afs_cell *cell) in afs_request_key() argument
27 _enter("{%x}", key_serial(cell->anonymous_key)); in afs_request_key()
29 _debug("key %s", cell->anonymous_key->description); in afs_request_key()
30 key = request_key_net(&key_type_rxrpc, cell->anonymous_key->description, in afs_request_key()
31 cell->net->net, NULL); in afs_request_key()
33 if (PTR_ERR(key) != -ENOKEY) { in afs_request_key()
39 _leave(" = {%x} [anon]", key_serial(cell->anonymous_key)); in afs_request_key()
40 return key_get(cell->anonymous_key); in afs_request_key()
51 struct key *afs_request_key_rcu(struct afs_cell *cell) in afs_request_key_rcu() argument
55 _enter("{%x}", key_serial(cell->anonymous_key)); in afs_request_key_rcu()
57 _debug("key %s", cell->anonymous_key->description); in afs_request_key_rcu()
59 cell->anonymous_key->description, in afs_request_key_rcu()
60 cell->net->net); in afs_request_key_rcu()
62 if (PTR_ERR(key) != -ENOKEY) { in afs_request_key_rcu()
68 _leave(" = {%x} [anon]", key_serial(cell->anonymous_key)); in afs_request_key_rcu()
69 return key_get(cell->anonymous_key); in afs_request_key_rcu()
86 for (i = 0; i < permits->nr_permits; i++) in afs_permits_rcu()
87 key_put(permits->permits[i].key); in afs_permits_rcu()
96 if (permits && refcount_dec_and_test(&permits->usage)) { in afs_put_permits()
98 hash_del_rcu(&permits->hash_node); in afs_put_permits()
100 call_rcu(&permits->rcu, afs_permits_rcu); in afs_put_permits()
111 spin_lock(&vnode->lock); in afs_clear_permits()
112 permits = rcu_dereference_protected(vnode->permit_cache, in afs_clear_permits()
113 lockdep_is_held(&vnode->lock)); in afs_clear_permits()
114 RCU_INIT_POINTER(vnode->permit_cache, NULL); in afs_clear_permits()
115 spin_unlock(&vnode->lock); in afs_clear_permits()
122 * one at an as-yet indeterminate position in the list.
126 unsigned long h = permits->nr_permits; in afs_hash_permits()
129 for (i = 0; i < permits->nr_permits; i++) { in afs_hash_permits()
130 h += (unsigned long)permits->permits[i].key / sizeof(void *); in afs_hash_permits()
131 h += permits->permits[i].access; in afs_hash_permits()
134 permits->h = h; in afs_hash_permits()
147 afs_access_t caller_access = scb->status.caller_access; in afs_cache_permit()
153 vnode->fid.vid, vnode->fid.vnode, key_serial(key), caller_access); in afs_cache_permit()
160 permits = rcu_dereference(vnode->permit_cache); in afs_cache_permit()
162 if (!permits->invalidated) { in afs_cache_permit()
163 for (i = 0; i < permits->nr_permits; i++) { in afs_cache_permit()
164 if (permits->permits[i].key < key) in afs_cache_permit()
166 if (permits->permits[i].key > key) in afs_cache_permit()
168 if (permits->permits[i].access != caller_access) { in afs_cache_permit()
184 changed |= permits->invalidated; in afs_cache_permit()
185 size = permits->nr_permits; in afs_cache_permit()
188 * pointer so that no one tries to use the stale information. in afs_cache_permit()
191 spin_lock(&vnode->lock); in afs_cache_permit()
192 if (permits != rcu_access_pointer(vnode->permit_cache)) in afs_cache_permit()
194 RCU_INIT_POINTER(vnode->permit_cache, NULL); in afs_cache_permit()
195 spin_unlock(&vnode->lock); in afs_cache_permit()
209 if (permits && !refcount_inc_not_zero(&permits->usage)) in afs_cache_permit()
226 refcount_set(&new->usage, 1); in afs_cache_permit()
227 new->nr_permits = size; in afs_cache_permit()
230 for (i = 0; i < permits->nr_permits; i++) { in afs_cache_permit()
231 if (j == i && permits->permits[i].key > key) { in afs_cache_permit()
232 new->permits[j].key = key; in afs_cache_permit()
233 new->permits[j].access = caller_access; in afs_cache_permit()
236 new->permits[j].key = permits->permits[i].key; in afs_cache_permit()
237 new->permits[j].access = permits->permits[i].access; in afs_cache_permit()
243 new->permits[j].key = key; in afs_cache_permit()
244 new->permits[j].access = caller_access; in afs_cache_permit()
252 hash_for_each_possible(afs_permits_cache, xpermits, hash_node, new->h) { in afs_cache_permit()
253 if (xpermits->h != new->h || in afs_cache_permit()
254 xpermits->invalidated || in afs_cache_permit()
255 xpermits->nr_permits != new->nr_permits || in afs_cache_permit()
256 memcmp(xpermits->permits, new->permits, in afs_cache_permit()
257 new->nr_permits * sizeof(struct afs_permit)) != 0) in afs_cache_permit()
260 if (refcount_inc_not_zero(&xpermits->usage)) { in afs_cache_permit()
268 for (i = 0; i < new->nr_permits; i++) in afs_cache_permit()
269 key_get(new->permits[i].key); in afs_cache_permit()
270 hash_add_rcu(afs_permits_cache, &new->hash_node, new->h); in afs_cache_permit()
280 spin_lock(&vnode->lock); in afs_cache_permit()
281 zap = rcu_access_pointer(vnode->permit_cache); in afs_cache_permit()
283 rcu_assign_pointer(vnode->permit_cache, replacement); in afs_cache_permit()
286 spin_unlock(&vnode->lock); in afs_cache_permit()
294 spin_unlock(&vnode->lock); in afs_cache_permit()
296 /* Someone else changed the cache under us - don't recheck at this in afs_cache_permit()
310 vnode->fid.vid, vnode->fid.vnode, key_serial(key)); in afs_check_permit_rcu()
312 /* check the permits to see if we've got one yet */ in afs_check_permit_rcu()
313 if (key == vnode->volume->cell->anonymous_key) { in afs_check_permit_rcu()
314 *_access = vnode->status.anon_access; in afs_check_permit_rcu()
319 permits = rcu_dereference(vnode->permit_cache); in afs_check_permit_rcu()
321 for (i = 0; i < permits->nr_permits; i++) { in afs_check_permit_rcu()
322 if (permits->permits[i].key < key) in afs_check_permit_rcu()
324 if (permits->permits[i].key > key) in afs_check_permit_rcu()
327 *_access = permits->permits[i].access; in afs_check_permit_rcu()
328 _leave(" = %u [perm %x]", !permits->invalidated, *_access); in afs_check_permit_rcu()
329 return !permits->invalidated; in afs_check_permit_rcu()
350 vnode->fid.vid, vnode->fid.vnode, key_serial(key)); in afs_check_permit()
352 /* check the permits to see if we've got one yet */ in afs_check_permit()
353 if (key == vnode->volume->cell->anonymous_key) { in afs_check_permit()
355 *_access = vnode->status.anon_access; in afs_check_permit()
359 permits = rcu_dereference(vnode->permit_cache); in afs_check_permit()
361 for (i = 0; i < permits->nr_permits; i++) { in afs_check_permit()
362 if (permits->permits[i].key < key) in afs_check_permit()
364 if (permits->permits[i].key > key) in afs_check_permit()
367 *_access = permits->permits[i].access; in afs_check_permit()
368 valid = !permits->invalidated; in afs_check_permit()
377 * (the post-processing will cache the result). in afs_check_permit()
395 * - AFS ACLs are attached to directories only, and a file is controlled by its
407 vnode->fid.vid, vnode->fid.vnode, vnode->flags, mask); in afs_permission()
410 key = afs_request_key_rcu(vnode->volume->cell); in afs_permission()
412 return -ECHILD; in afs_permission()
414 ret = -ECHILD; in afs_permission()
419 key = afs_request_key(vnode->volume->cell); in afs_permission()
429 /* check the permits to see if we've got one yet */ in afs_permission()
437 mask, access, S_ISDIR(inode->i_mode) ? "dir" : "file"); in afs_permission()
440 if (S_ISDIR(inode->i_mode)) { in afs_permission()
453 if ((mask & MAY_EXEC) && !(inode->i_mode & S_IXUSR)) in afs_permission()
458 if (!(inode->i_mode & S_IRUSR)) in afs_permission()
463 if (!(inode->i_mode & S_IWUSR)) in afs_permission()
473 ret = -EACCES; in afs_permission()