Skip to content

Commit 6a92b08

Browse files
jtlaytonidryomov
authored andcommitted
ceph: don't take s_mutex or snap_rwsem in ceph_check_caps
These locks appear to be completely unnecessary. Almost all of this function is done under the inode->i_ceph_lock, aside from the actual sending of the message. Don't take either lock in this function. Signed-off-by: Jeff Layton <jlayton@kernel.org> Reviewed-by: Luis Henriques <lhenriques@suse.de> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
1 parent 52d60f8 commit 6a92b08

1 file changed

Lines changed: 11 additions & 61 deletions

File tree

fs/ceph/caps.c

Lines changed: 11 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,22 +1912,20 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
19121912
struct ceph_cap *cap;
19131913
u64 flush_tid, oldest_flush_tid;
19141914
int file_wanted, used, cap_used;
1915-
int took_snap_rwsem = 0; /* true if mdsc->snap_rwsem held */
19161915
int issued, implemented, want, retain, revoking, flushing = 0;
19171916
int mds = -1; /* keep track of how far we've gone through i_caps list
19181917
to avoid an infinite loop on retry */
19191918
struct rb_node *p;
19201919
bool queue_invalidate = false;
19211920
bool tried_invalidate = false;
19221921

1922+
if (session)
1923+
ceph_get_mds_session(session);
1924+
19231925
spin_lock(&ci->i_ceph_lock);
19241926
if (ci->i_ceph_flags & CEPH_I_FLUSH)
19251927
flags |= CHECK_CAPS_FLUSH;
1926-
1927-
goto retry_locked;
19281928
retry:
1929-
spin_lock(&ci->i_ceph_lock);
1930-
retry_locked:
19311929
/* Caps wanted by virtue of active open files. */
19321930
file_wanted = __ceph_caps_file_wanted(ci);
19331931

@@ -2007,7 +2005,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
20072005
ci->i_rdcache_revoking = ci->i_rdcache_gen;
20082006
}
20092007
tried_invalidate = true;
2010-
goto retry_locked;
2008+
goto retry;
20112009
}
20122010

20132011
for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
@@ -2021,8 +2019,6 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
20212019
((flags & CHECK_CAPS_AUTHONLY) && cap != ci->i_auth_cap))
20222020
continue;
20232021

2024-
/* NOTE: no side-effects allowed, until we take s_mutex */
2025-
20262022
/*
20272023
* If we have an auth cap, we don't need to consider any
20282024
* overlapping caps as used.
@@ -2085,37 +2081,8 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
20852081
continue; /* nope, all good */
20862082

20872083
ack:
2088-
if (session && session != cap->session) {
2089-
dout("oops, wrong session %p mutex\n", session);
2090-
mutex_unlock(&session->s_mutex);
2091-
session = NULL;
2092-
}
2093-
if (!session) {
2094-
session = cap->session;
2095-
if (mutex_trylock(&session->s_mutex) == 0) {
2096-
dout("inverting session/ino locks on %p\n",
2097-
session);
2098-
session = ceph_get_mds_session(session);
2099-
spin_unlock(&ci->i_ceph_lock);
2100-
if (took_snap_rwsem) {
2101-
up_read(&mdsc->snap_rwsem);
2102-
took_snap_rwsem = 0;
2103-
}
2104-
if (session) {
2105-
mutex_lock(&session->s_mutex);
2106-
ceph_put_mds_session(session);
2107-
} else {
2108-
/*
2109-
* Because we take the reference while
2110-
* holding the i_ceph_lock, it should
2111-
* never be NULL. Throw a warning if it
2112-
* ever is.
2113-
*/
2114-
WARN_ON_ONCE(true);
2115-
}
2116-
goto retry;
2117-
}
2118-
}
2084+
ceph_put_mds_session(session);
2085+
session = ceph_get_mds_session(cap->session);
21192086

21202087
/* kick flushing and flush snaps before sending normal
21212088
* cap message */
@@ -2127,20 +2094,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
21272094
if (ci->i_ceph_flags & CEPH_I_FLUSH_SNAPS)
21282095
__ceph_flush_snaps(ci, session);
21292096

2130-
goto retry_locked;
2131-
}
2132-
2133-
/* take snap_rwsem after session mutex */
2134-
if (!took_snap_rwsem) {
2135-
if (down_read_trylock(&mdsc->snap_rwsem) == 0) {
2136-
dout("inverting snap/in locks on %p\n",
2137-
inode);
2138-
spin_unlock(&ci->i_ceph_lock);
2139-
down_read(&mdsc->snap_rwsem);
2140-
took_snap_rwsem = 1;
2141-
goto retry;
2142-
}
2143-
took_snap_rwsem = 1;
2097+
goto retry;
21442098
}
21452099

21462100
if (cap == ci->i_auth_cap && ci->i_dirty_caps) {
@@ -2162,9 +2116,10 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
21622116

21632117
__prep_cap(&arg, cap, CEPH_CAP_OP_UPDATE, mflags, cap_used,
21642118
want, retain, flushing, flush_tid, oldest_flush_tid);
2165-
spin_unlock(&ci->i_ceph_lock);
21662119

2120+
spin_unlock(&ci->i_ceph_lock);
21672121
__send_cap(&arg, ci);
2122+
spin_lock(&ci->i_ceph_lock);
21682123

21692124
goto retry; /* retake i_ceph_lock and restart our cap scan. */
21702125
}
@@ -2179,13 +2134,9 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags,
21792134

21802135
spin_unlock(&ci->i_ceph_lock);
21812136

2137+
ceph_put_mds_session(session);
21822138
if (queue_invalidate)
21832139
ceph_queue_invalidate(inode);
2184-
2185-
if (session)
2186-
mutex_unlock(&session->s_mutex);
2187-
if (took_snap_rwsem)
2188-
up_read(&mdsc->snap_rwsem);
21892140
}
21902141

21912142
/*
@@ -3550,13 +3501,12 @@ static void handle_cap_grant(struct inode *inode,
35503501
if (wake)
35513502
wake_up_all(&ci->i_cap_wq);
35523503

3504+
mutex_unlock(&session->s_mutex);
35533505
if (check_caps == 1)
35543506
ceph_check_caps(ci, CHECK_CAPS_AUTHONLY | CHECK_CAPS_NOINVAL,
35553507
session);
35563508
else if (check_caps == 2)
35573509
ceph_check_caps(ci, CHECK_CAPS_NOINVAL, session);
3558-
else
3559-
mutex_unlock(&session->s_mutex);
35603510
}
35613511

35623512
/*

0 commit comments

Comments
 (0)