summaryrefslogtreecommitdiffstats
path: root/fs/afs/security.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@lithui.me.apana.org.au>2017-12-22 20:00:50 +1100
committerHerbert Xu <herbert@lithui.me.apana.org.au>2017-12-22 20:00:50 +1100
commit45fa9a324d0f5be9140ba2e0db9b8fb8a0b9b7e8 (patch)
treea5e7c8428030ec0462b58133d6548ddff3802018 /fs/afs/security.c
parentfc8517bf627c9b834f80274a1bc9ecd39b27231b (diff)
parent2973633e9f09311e849f975d969737af81a521ff (diff)
downloadtalos-op-linux-45fa9a324d0f5be9140ba2e0db9b8fb8a0b9b7e8.tar.gz
talos-op-linux-45fa9a324d0f5be9140ba2e0db9b8fb8a0b9b7e8.zip
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Merge the crypto tree to pick up inside-secure fixes.
Diffstat (limited to 'fs/afs/security.c')
-rw-r--r--fs/afs/security.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/fs/afs/security.c b/fs/afs/security.c
index 2b00097101b3..b88b7d45fdaa 100644
--- a/fs/afs/security.c
+++ b/fs/afs/security.c
@@ -120,7 +120,7 @@ static void afs_hash_permits(struct afs_permits *permits)
void afs_cache_permit(struct afs_vnode *vnode, struct key *key,
unsigned int cb_break)
{
- struct afs_permits *permits, *xpermits, *replacement, *new = NULL;
+ struct afs_permits *permits, *xpermits, *replacement, *zap, *new = NULL;
afs_access_t caller_access = READ_ONCE(vnode->status.caller_access);
size_t size = 0;
bool changed = false;
@@ -204,7 +204,7 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key,
new = kzalloc(sizeof(struct afs_permits) +
sizeof(struct afs_permit) * size, GFP_NOFS);
if (!new)
- return;
+ goto out_put;
refcount_set(&new->usage, 1);
new->nr_permits = size;
@@ -229,8 +229,6 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key,
afs_hash_permits(new);
- afs_put_permits(permits);
-
/* Now see if the permit list we want is actually already available */
spin_lock(&afs_permits_lock);
@@ -262,11 +260,15 @@ found:
kfree(new);
spin_lock(&vnode->lock);
- if (cb_break != (vnode->cb_break + vnode->cb_interest->server->cb_s_break) ||
- permits != rcu_access_pointer(vnode->permit_cache))
- goto someone_else_changed_it_unlock;
- rcu_assign_pointer(vnode->permit_cache, replacement);
+ zap = rcu_access_pointer(vnode->permit_cache);
+ if (cb_break == (vnode->cb_break + vnode->cb_interest->server->cb_s_break) &&
+ zap == permits)
+ rcu_assign_pointer(vnode->permit_cache, replacement);
+ else
+ zap = replacement;
spin_unlock(&vnode->lock);
+ afs_put_permits(zap);
+out_put:
afs_put_permits(permits);
return;
OpenPOWER on IntegriCloud