@@ -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 ;
19281928retry :
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
20872083ack :
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