linux/fs/ceph
Jeff Layton 8434ffe71c ceph: take snap_empty_lock atomically with snaprealm refcount change
There is a race in ceph_put_snap_realm. The change to the nref and the
spinlock acquisition are not done atomically, so you could decrement
nref, and before you take the spinlock, the nref is incremented again.
At that point, you end up putting it on the empty list when it
shouldn't be there. Eventually __cleanup_empty_realms runs and frees
it when it's still in-use.

Fix this by protecting the 1->0 transition with atomic_dec_and_lock,
and just drop the spinlock if we can get the rwsem.

Because these objects can also undergo a 0->1 refcount transition, we
must protect that change as well with the spinlock. Increment locklessly
unless the value is at 0, in which case we take the spinlock, increment
and then take it off the empty list if it did the 0->1 transition.

With these changes, I'm removing the dout() messages from these
functions, as well as in __put_snap_realm. They've always been racy, and
it's better to not print values that may be misleading.

Cc: stable@vger.kernel.org
URL: https://tracker.ceph.com/issues/46419
Reported-by: Mark Nelson <mnelson@redhat.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Luis Henriques <lhenriques@suse.de>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
2021-08-04 19:20:29 +02:00
..
acl.c fs: make helpers idmap mount aware 2021-01-24 14:27:20 +01:00
addr.c ceph: add IO size metrics support 2021-06-29 00:15:51 +02:00
cache.c ceph: rip out old fscache readpage handling 2021-04-27 23:52:21 +02:00
cache.h ceph: convert ceph_readpage to netfs_readpage 2021-04-27 23:52:22 +02:00
caps.c ceph: reduce contention in ceph_check_delayed_caps() 2021-08-04 19:20:05 +02:00
ceph_frag.c
debugfs.c ceph: add IO size metrics support 2021-06-29 00:15:51 +02:00
dir.c ceph: take reference to req->r_parent at point of assignment 2021-06-29 00:15:52 +02:00
export.c ceph: take reference to req->r_parent at point of assignment 2021-06-29 00:15:52 +02:00
file.c ceph: take reference to req->r_parent at point of assignment 2021-06-29 00:15:52 +02:00
inode.c ceph: eliminate ceph_async_iput() 2021-06-29 00:15:52 +02:00
io.c ceph: fix kerneldoc copypasta over ceph_start_io_direct 2021-04-27 23:52:23 +02:00
io.h
ioctl.c ceph: consider inode's last read/write when calculating wanted caps 2020-03-30 12:42:42 +02:00
ioctl.h
Kconfig ceph: convert ceph_readpage to netfs_readpage 2021-04-27 23:52:22 +02:00
locks.c ceph: fix up some warnings on W=1 builds 2020-12-14 23:21:47 +01:00
Makefile ceph: add dentry lease metric support 2020-06-01 13:22:51 +02:00
mds_client.c ceph: reduce contention in ceph_check_delayed_caps() 2021-08-04 19:20:05 +02:00
mds_client.h ceph: eliminate session->s_gen_ttl_lock 2021-06-29 00:15:52 +02:00
mdsmap.c libceph, ceph: get and handle cluster maps with addrvecs 2020-12-14 23:21:50 +01:00
metric.c ceph: allow ceph_put_mds_session to take NULL or ERR_PTR 2021-06-29 00:15:52 +02:00
metric.h ceph: add IO size metrics support 2021-06-29 00:15:51 +02:00
quota.c ceph: eliminate ceph_async_iput() 2021-06-29 00:15:52 +02:00
snap.c ceph: take snap_empty_lock atomically with snaprealm refcount change 2021-08-04 19:20:29 +02:00
strings.c
super.c ceph: add new RECOVER mount_state when recovering session 2020-12-14 23:21:46 +01:00
super.h ceph: reduce contention in ceph_check_delayed_caps() 2021-08-04 19:20:05 +02:00
util.c
xattr.c ceph: support getting ceph.dir.rsnaps vxattr 2021-04-27 23:52:23 +02:00