afs: Make vnode->cb_interest RCU safe
Use RCU-based freeing for afs_cb_interest struct objects and use RCU on vnode->cb_interest. Use that change to allow afs_check_validity() to use read_seqbegin_or_lock() instead of read_seqlock_excl(). This also requires the caller of afs_check_validity() to hold the RCU read lock across the call. Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
@@ -94,15 +94,15 @@ int afs_register_server_cb_interest(struct afs_vnode *vnode,
|
||||
struct afs_server *server = entry->server;
|
||||
|
||||
again:
|
||||
if (vnode->cb_interest &&
|
||||
likely(vnode->cb_interest == entry->cb_interest))
|
||||
vcbi = rcu_dereference_protected(vnode->cb_interest,
|
||||
lockdep_is_held(&vnode->io_lock));
|
||||
if (vcbi && likely(vcbi == entry->cb_interest))
|
||||
return 0;
|
||||
|
||||
read_lock(&slist->lock);
|
||||
cbi = afs_get_cb_interest(entry->cb_interest);
|
||||
read_unlock(&slist->lock);
|
||||
|
||||
vcbi = vnode->cb_interest;
|
||||
if (vcbi) {
|
||||
if (vcbi == cbi) {
|
||||
afs_put_cb_interest(afs_v2net(vnode), cbi);
|
||||
@@ -114,8 +114,9 @@ again:
|
||||
*/
|
||||
if (cbi && vcbi->server == cbi->server) {
|
||||
write_seqlock(&vnode->cb_lock);
|
||||
old = vnode->cb_interest;
|
||||
vnode->cb_interest = cbi;
|
||||
old = rcu_dereference_protected(vnode->cb_interest,
|
||||
lockdep_is_held(&vnode->cb_lock.lock));
|
||||
rcu_assign_pointer(vnode->cb_interest, cbi);
|
||||
write_sequnlock(&vnode->cb_lock);
|
||||
afs_put_cb_interest(afs_v2net(vnode), old);
|
||||
return 0;
|
||||
@@ -160,8 +161,9 @@ again:
|
||||
*/
|
||||
write_seqlock(&vnode->cb_lock);
|
||||
|
||||
old = vnode->cb_interest;
|
||||
vnode->cb_interest = cbi;
|
||||
old = rcu_dereference_protected(vnode->cb_interest,
|
||||
lockdep_is_held(&vnode->cb_lock.lock));
|
||||
rcu_assign_pointer(vnode->cb_interest, cbi);
|
||||
vnode->cb_s_break = cbi->server->cb_s_break;
|
||||
vnode->cb_v_break = vnode->volume->cb_v_break;
|
||||
clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags);
|
||||
@@ -191,10 +193,11 @@ void afs_put_cb_interest(struct afs_net *net, struct afs_cb_interest *cbi)
|
||||
vi = NULL;
|
||||
|
||||
write_unlock(&cbi->server->cb_break_lock);
|
||||
kfree(vi);
|
||||
if (vi)
|
||||
kfree_rcu(vi, rcu);
|
||||
afs_put_server(net, cbi->server);
|
||||
}
|
||||
kfree(cbi);
|
||||
kfree_rcu(cbi, rcu);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user