summaryrefslogtreecommitdiff
path: root/fs/afs/server.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2020-03-27 18:02:44 +0300
committerDavid Howells <dhowells@redhat.com>2020-05-31 17:19:51 +0300
commit8230fd8217b7ea76f838ae88e4a5a8e54f37099f (patch)
treec395ba533ee29c24e1ce7e4c0b9f65f8b14e0972 /fs/afs/server.c
parent6d043a578265e8c24384648f9c74c8874b429f28 (diff)
downloadlinux-8230fd8217b7ea76f838ae88e4a5a8e54f37099f.tar.xz
afs: Make callback processing more efficient.
afs_vol_interest objects represent the volume IDs currently being accessed from a fileserver. These hold lists of afs_cb_interest objects that repesent the superblocks using that volume ID on that server. When a callback notification from the server telling of a modification by another client arrives, the volume ID specified in the notification is looked up in the server's afs_vol_interest list. Through the afs_cb_interest list, the relevant superblocks can be iterated over and the specific inode looked up and marked in each one. Make the following efficiency improvements: (1) Hold rcu_read_lock() over the entire processing rather than locking it each time. (2) Do all the callbacks for each vid together rather than individually. Each volume then only needs to be looked up once. (3) afs_vol_interest objects are now stored in an rb_tree rather than a flat list to reduce the lookup step count. (4) afs_vol_interest lookup is now done with RCU, but because it's in an rb_tree which may rotate under us, a seqlock is used so that if it changes during the walk, we repeat the walk with a lock held. With this and the preceding patch which adds RCU-based lookups in the inode cache, target volumes/vnodes can be taken without the need to take any locks, except on the target itself. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs/server.c')
-rw-r--r--fs/afs/server.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/fs/afs/server.c b/fs/afs/server.c
index 3f707b5ecb62..5ed90f419c54 100644
--- a/fs/afs/server.c
+++ b/fs/afs/server.c
@@ -212,8 +212,8 @@ static struct afs_server *afs_alloc_server(struct afs_net *net,
server->addr_version = alist->version;
server->uuid = *uuid;
rwlock_init(&server->fs_lock);
- INIT_HLIST_HEAD(&server->cb_volumes);
- rwlock_init(&server->cb_break_lock);
+ server->cb_volumes = RB_ROOT;
+ seqlock_init(&server->cb_break_lock);
init_waitqueue_head(&server->probe_wq);
INIT_LIST_HEAD(&server->probe_link);
spin_lock_init(&server->probe_lock);