@@ -2218,6 +2218,7 @@ static int unsafe_request_wait(struct inode *inode)
2218
2218
struct ceph_mds_client * mdsc = ceph_sb_to_client (inode -> i_sb )-> mdsc ;
2219
2219
struct ceph_inode_info * ci = ceph_inode (inode );
2220
2220
struct ceph_mds_request * req1 = NULL , * req2 = NULL ;
2221
+ unsigned int max_sessions ;
2221
2222
int ret , err = 0 ;
2222
2223
2223
2224
spin_lock (& ci -> i_unsafe_lock );
@@ -2235,37 +2236,45 @@ static int unsafe_request_wait(struct inode *inode)
2235
2236
}
2236
2237
spin_unlock (& ci -> i_unsafe_lock );
2237
2238
2239
+ /*
2240
+ * The mdsc->max_sessions is unlikely to be changed
2241
+ * mostly, here we will retry it by reallocating the
2242
+ * sessions array memory to get rid of the mdsc->mutex
2243
+ * lock.
2244
+ */
2245
+ retry :
2246
+ max_sessions = mdsc -> max_sessions ;
2247
+
2238
2248
/*
2239
2249
* Trigger to flush the journal logs in all the relevant MDSes
2240
2250
* manually, or in the worst case we must wait at most 5 seconds
2241
2251
* to wait the journal logs to be flushed by the MDSes periodically.
2242
2252
*/
2243
- if (req1 || req2 ) {
2253
+ if (( req1 || req2 ) && likely ( max_sessions ) ) {
2244
2254
struct ceph_mds_session * * sessions = NULL ;
2245
2255
struct ceph_mds_session * s ;
2246
2256
struct ceph_mds_request * req ;
2247
- unsigned int max ;
2248
2257
int i ;
2249
2258
2250
- /*
2251
- * The mdsc->max_sessions is unlikely to be changed
2252
- * mostly, here we will retry it by reallocating the
2253
- * sessions arrary memory to get rid of the mdsc->mutex
2254
- * lock.
2255
- */
2256
- retry :
2257
- max = mdsc -> max_sessions ;
2258
- sessions = krealloc (sessions , max * sizeof (s ), __GFP_ZERO );
2259
- if (!sessions )
2260
- return - ENOMEM ;
2259
+ sessions = kzalloc (max_sessions * sizeof (s ), GFP_KERNEL );
2260
+ if (!sessions ) {
2261
+ err = - ENOMEM ;
2262
+ goto out ;
2263
+ }
2261
2264
2262
2265
spin_lock (& ci -> i_unsafe_lock );
2263
2266
if (req1 ) {
2264
2267
list_for_each_entry (req , & ci -> i_unsafe_dirops ,
2265
2268
r_unsafe_dir_item ) {
2266
2269
s = req -> r_session ;
2267
- if (unlikely (s -> s_mds >= max )) {
2270
+ if (unlikely (s -> s_mds >= max_sessions )) {
2268
2271
spin_unlock (& ci -> i_unsafe_lock );
2272
+ for (i = 0 ; i < max_sessions ; i ++ ) {
2273
+ s = sessions [i ];
2274
+ if (s )
2275
+ ceph_put_mds_session (s );
2276
+ }
2277
+ kfree (sessions );
2269
2278
goto retry ;
2270
2279
}
2271
2280
if (!sessions [s -> s_mds ]) {
@@ -2278,8 +2287,14 @@ static int unsafe_request_wait(struct inode *inode)
2278
2287
list_for_each_entry (req , & ci -> i_unsafe_iops ,
2279
2288
r_unsafe_target_item ) {
2280
2289
s = req -> r_session ;
2281
- if (unlikely (s -> s_mds >= max )) {
2290
+ if (unlikely (s -> s_mds >= max_sessions )) {
2282
2291
spin_unlock (& ci -> i_unsafe_lock );
2292
+ for (i = 0 ; i < max_sessions ; i ++ ) {
2293
+ s = sessions [i ];
2294
+ if (s )
2295
+ ceph_put_mds_session (s );
2296
+ }
2297
+ kfree (sessions );
2283
2298
goto retry ;
2284
2299
}
2285
2300
if (!sessions [s -> s_mds ]) {
@@ -2300,7 +2315,7 @@ static int unsafe_request_wait(struct inode *inode)
2300
2315
spin_unlock (& ci -> i_ceph_lock );
2301
2316
2302
2317
/* send flush mdlog request to MDSes */
2303
- for (i = 0 ; i < max ; i ++ ) {
2318
+ for (i = 0 ; i < max_sessions ; i ++ ) {
2304
2319
s = sessions [i ];
2305
2320
if (s ) {
2306
2321
send_flush_mdlog (s );
@@ -2317,15 +2332,19 @@ static int unsafe_request_wait(struct inode *inode)
2317
2332
ceph_timeout_jiffies (req1 -> r_timeout ));
2318
2333
if (ret )
2319
2334
err = - EIO ;
2320
- ceph_mdsc_put_request (req1 );
2321
2335
}
2322
2336
if (req2 ) {
2323
2337
ret = !wait_for_completion_timeout (& req2 -> r_safe_completion ,
2324
2338
ceph_timeout_jiffies (req2 -> r_timeout ));
2325
2339
if (ret )
2326
2340
err = - EIO ;
2327
- ceph_mdsc_put_request (req2 );
2328
2341
}
2342
+
2343
+ out :
2344
+ if (req1 )
2345
+ ceph_mdsc_put_request (req1 );
2346
+ if (req2 )
2347
+ ceph_mdsc_put_request (req2 );
2329
2348
return err ;
2330
2349
}
2331
2350
0 commit comments