ceph: fix cap removal races
authorSage Weil <sage@newdream.net>
Wed, 12 May 2010 03:56:31 +0000 (20:56 -0700)
committerSage Weil <sage@newdream.net>
Wed, 12 May 2010 03:56:31 +0000 (20:56 -0700)
commitf818a73674c5d197f66b636a46d7d578d7258129
tree90c485b5ca0a211b84ad8feddfce4f301de3d5c9
parent45c6ceb547ad2d98215351974a4686bf8cb13e14
ceph: fix cap removal races

The iterate_session_caps helper traverses the session caps list and tries
to grab an inode reference.  However, the __ceph_remove_cap was clearing
the inode backpointer _before_ removing itself from the session list,
causing a null pointer dereference.

Clear cap->ci under protection of s_cap_lock to avoid the race, and to
tightly couple the list and backpointer state.  Use a local flag to
indicate whether we are releasing the cap, as cap->session may be modified
by a racing thread in iterate_session_caps.

Signed-off-by: Sage Weil <sage@newdream.net>
fs/ceph/caps.c
fs/ceph/mds_client.c