@@ -1486,6 +1486,7 @@ static int __mark_caps_flushing(struct inode *inode,
1486
1486
1487
1487
cf = kmalloc (sizeof (* cf ), GFP_ATOMIC );
1488
1488
cf -> caps = flushing ;
1489
+ cf -> kick = false;
1489
1490
1490
1491
spin_lock (& mdsc -> cap_dirty_lock );
1491
1492
list_del_init (& ci -> i_dirty_item );
@@ -2101,7 +2102,8 @@ static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc,
2101
2102
2102
2103
static int __kick_flushing_caps (struct ceph_mds_client * mdsc ,
2103
2104
struct ceph_mds_session * session ,
2104
- struct ceph_inode_info * ci )
2105
+ struct ceph_inode_info * ci ,
2106
+ bool kick_all )
2105
2107
{
2106
2108
struct inode * inode = & ci -> vfs_inode ;
2107
2109
struct ceph_cap * cap ;
@@ -2127,7 +2129,9 @@ static int __kick_flushing_caps(struct ceph_mds_client *mdsc,
2127
2129
2128
2130
for (n = rb_first (& ci -> i_cap_flush_tree ); n ; n = rb_next (n )) {
2129
2131
cf = rb_entry (n , struct ceph_cap_flush , i_node );
2130
- if (cf -> tid >= first_tid )
2132
+ if (cf -> tid < first_tid )
2133
+ continue ;
2134
+ if (kick_all || cf -> kick )
2131
2135
break ;
2132
2136
}
2133
2137
if (!n ) {
@@ -2136,6 +2140,8 @@ static int __kick_flushing_caps(struct ceph_mds_client *mdsc,
2136
2140
}
2137
2141
2138
2142
cf = rb_entry (n , struct ceph_cap_flush , i_node );
2143
+ cf -> kick = false;
2144
+
2139
2145
first_tid = cf -> tid + 1 ;
2140
2146
2141
2147
dout ("kick_flushing_caps %p cap %p tid %llu %s\n" , inode ,
@@ -2149,6 +2155,49 @@ static int __kick_flushing_caps(struct ceph_mds_client *mdsc,
2149
2155
return delayed ;
2150
2156
}
2151
2157
2158
+ void ceph_early_kick_flushing_caps (struct ceph_mds_client * mdsc ,
2159
+ struct ceph_mds_session * session )
2160
+ {
2161
+ struct ceph_inode_info * ci ;
2162
+ struct ceph_cap * cap ;
2163
+ struct ceph_cap_flush * cf ;
2164
+ struct rb_node * n ;
2165
+
2166
+ dout ("early_kick_flushing_caps mds%d\n" , session -> s_mds );
2167
+ list_for_each_entry (ci , & session -> s_cap_flushing , i_flushing_item ) {
2168
+ spin_lock (& ci -> i_ceph_lock );
2169
+ cap = ci -> i_auth_cap ;
2170
+ if (!(cap && cap -> session == session )) {
2171
+ pr_err ("%p auth cap %p not mds%d ???\n" ,
2172
+ & ci -> vfs_inode , cap , session -> s_mds );
2173
+ spin_unlock (& ci -> i_ceph_lock );
2174
+ continue ;
2175
+ }
2176
+
2177
+
2178
+ /*
2179
+ * if flushing caps were revoked, we re-send the cap flush
2180
+ * in client reconnect stage. This guarantees MDS * processes
2181
+ * the cap flush message before issuing the flushing caps to
2182
+ * other client.
2183
+ */
2184
+ if ((cap -> issued & ci -> i_flushing_caps ) !=
2185
+ ci -> i_flushing_caps ) {
2186
+ spin_unlock (& ci -> i_ceph_lock );
2187
+ if (!__kick_flushing_caps (mdsc , session , ci , true))
2188
+ continue ;
2189
+ spin_lock (& ci -> i_ceph_lock );
2190
+ }
2191
+
2192
+ for (n = rb_first (& ci -> i_cap_flush_tree ); n ; n = rb_next (n )) {
2193
+ cf = rb_entry (n , struct ceph_cap_flush , i_node );
2194
+ cf -> kick = true;
2195
+ }
2196
+
2197
+ spin_unlock (& ci -> i_ceph_lock );
2198
+ }
2199
+ }
2200
+
2152
2201
void ceph_kick_flushing_caps (struct ceph_mds_client * mdsc ,
2153
2202
struct ceph_mds_session * session )
2154
2203
{
@@ -2158,7 +2207,7 @@ void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,
2158
2207
2159
2208
dout ("kick_flushing_caps mds%d\n" , session -> s_mds );
2160
2209
list_for_each_entry (ci , & session -> s_cap_flushing , i_flushing_item ) {
2161
- int delayed = __kick_flushing_caps (mdsc , session , ci );
2210
+ int delayed = __kick_flushing_caps (mdsc , session , ci , false );
2162
2211
if (delayed ) {
2163
2212
spin_lock (& ci -> i_ceph_lock );
2164
2213
__cap_delay_requeue (mdsc , ci );
@@ -2191,7 +2240,7 @@ static void kick_flushing_inode_caps(struct ceph_mds_client *mdsc,
2191
2240
2192
2241
spin_unlock (& ci -> i_ceph_lock );
2193
2242
2194
- delayed = __kick_flushing_caps (mdsc , session , ci );
2243
+ delayed = __kick_flushing_caps (mdsc , session , ci , true );
2195
2244
if (delayed ) {
2196
2245
spin_lock (& ci -> i_ceph_lock );
2197
2246
__cap_delay_requeue (mdsc , ci );
0 commit comments