diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-09 10:08:08 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-09 10:08:08 -0700 |
| commit | 4b22e2074195097c9d6bdc688288d12b7b236bae (patch) | |
| tree | 6d5e9391c76e4db80f0efc4d6faa472566ae9933 /fs/afs/volume.c | |
| parent | 426b4ca2d6a5ab51f6b6175d06e4f8ddea434cdf (diff) | |
| parent | 2757a4dc184997c66ef1de32636f73b9f21aac14 (diff) | |
| download | linux-4b22e2074195097c9d6bdc688288d12b7b236bae.tar.gz linux-4b22e2074195097c9d6bdc688288d12b7b236bae.tar.bz2 linux-4b22e2074195097c9d6bdc688288d12b7b236bae.zip | |
Merge tag 'afs-fixes-20220802' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
Pull AFS fixes from David Howells:
"Fix AFS refcount handling.
The first patch converts afs to use refcount_t for its refcounts and
the second patch fixes afs_put_call() and afs_put_server() to save the
values they're going to log in the tracepoint before decrementing the
refcount"
* tag 'afs-fixes-20220802' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs:
afs: Fix access after dec in put functions
afs: Use refcount_t rather than atomic_t
Diffstat (limited to 'fs/afs/volume.c')
| -rw-r--r-- | fs/afs/volume.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/fs/afs/volume.c b/fs/afs/volume.c index cc665cef0abe..f4937029dcd7 100644 --- a/fs/afs/volume.c +++ b/fs/afs/volume.c @@ -52,7 +52,7 @@ static void afs_remove_volume_from_cell(struct afs_volume *volume) struct afs_cell *cell = volume->cell; if (!hlist_unhashed(&volume->proc_link)) { - trace_afs_volume(volume->vid, atomic_read(&volume->usage), + trace_afs_volume(volume->vid, refcount_read(&cell->ref), afs_volume_trace_remove); write_seqlock(&cell->volume_lock); hlist_del_rcu(&volume->proc_link); @@ -87,7 +87,7 @@ static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params, volume->type_force = params->force; volume->name_len = vldb->name_len; - atomic_set(&volume->usage, 1); + refcount_set(&volume->ref, 1); INIT_HLIST_NODE(&volume->proc_link); rwlock_init(&volume->servers_lock); rwlock_init(&volume->cb_v_break_lock); @@ -228,7 +228,7 @@ static void afs_destroy_volume(struct afs_net *net, struct afs_volume *volume) afs_remove_volume_from_cell(volume); afs_put_serverlist(net, rcu_access_pointer(volume->servers)); afs_put_cell(volume->cell, afs_cell_trace_put_vol); - trace_afs_volume(volume->vid, atomic_read(&volume->usage), + trace_afs_volume(volume->vid, refcount_read(&volume->ref), afs_volume_trace_free); kfree_rcu(volume, rcu); @@ -242,8 +242,10 @@ struct afs_volume *afs_get_volume(struct afs_volume *volume, enum afs_volume_trace reason) { if (volume) { - int u = atomic_inc_return(&volume->usage); - trace_afs_volume(volume->vid, u, reason); + int r; + + __refcount_inc(&volume->ref, &r); + trace_afs_volume(volume->vid, r + 1, reason); } return volume; } @@ -257,9 +259,12 @@ void afs_put_volume(struct afs_net *net, struct afs_volume *volume, { if (volume) { afs_volid_t vid = volume->vid; - int u = atomic_dec_return(&volume->usage); - trace_afs_volume(vid, u, reason); - if (u == 0) + bool zero; + int r; + + zero = __refcount_dec_and_test(&volume->ref, &r); + trace_afs_volume(vid, r - 1, reason); + if (zero) afs_destroy_volume(net, volume); } } |
