@@ -223,9 +223,15 @@ static void sub_reserved_credits(journal_t *journal, int blocks)
223
223
* with j_state_lock held for reading. Returns 0 if handle joined the running
224
224
* transaction. Returns 1 if we had to wait, j_state_lock is dropped, and
225
225
* caller must retry.
226
+ *
227
+ * Note: because j_state_lock may be dropped depending on the return
228
+ * value, we need to fake out sparse so ti doesn't complain about a
229
+ * locking imbalance. Callers of add_transaction_credits will need to
230
+ * make a similar accomodation.
226
231
*/
227
232
static int add_transaction_credits (journal_t * journal , int blocks ,
228
233
int rsv_blocks )
234
+ __must_hold (& journal - > j_state_lock )
229
235
{
230
236
transaction_t * t = journal -> j_running_transaction ;
231
237
int needed ;
@@ -238,6 +244,7 @@ static int add_transaction_credits(journal_t *journal, int blocks,
238
244
if (t -> t_state != T_RUNNING ) {
239
245
WARN_ON_ONCE (t -> t_state >= T_FLUSH );
240
246
wait_transaction_locked (journal );
247
+ __acquire (& journal -> j_state_lock ); /* fake out sparse */
241
248
return 1 ;
242
249
}
243
250
@@ -266,10 +273,12 @@ static int add_transaction_credits(journal_t *journal, int blocks,
266
273
wait_event (journal -> j_wait_reserved ,
267
274
atomic_read (& journal -> j_reserved_credits ) + total <=
268
275
journal -> j_max_transaction_buffers );
276
+ __acquire (& journal -> j_state_lock ); /* fake out sparse */
269
277
return 1 ;
270
278
}
271
279
272
280
wait_transaction_locked (journal );
281
+ __acquire (& journal -> j_state_lock ); /* fake out sparse */
273
282
return 1 ;
274
283
}
275
284
@@ -293,6 +302,7 @@ static int add_transaction_credits(journal_t *journal, int blocks,
293
302
journal -> j_max_transaction_buffers )
294
303
__jbd2_log_wait_for_space (journal );
295
304
write_unlock (& journal -> j_state_lock );
305
+ __acquire (& journal -> j_state_lock ); /* fake out sparse */
296
306
return 1 ;
297
307
}
298
308
@@ -310,6 +320,7 @@ static int add_transaction_credits(journal_t *journal, int blocks,
310
320
wait_event (journal -> j_wait_reserved ,
311
321
atomic_read (& journal -> j_reserved_credits ) + rsv_blocks
312
322
<= journal -> j_max_transaction_buffers / 2 );
323
+ __acquire (& journal -> j_state_lock ); /* fake out sparse */
313
324
return 1 ;
314
325
}
315
326
return 0 ;
@@ -413,8 +424,14 @@ static int start_this_handle(journal_t *journal, handle_t *handle,
413
424
414
425
if (!handle -> h_reserved ) {
415
426
/* We may have dropped j_state_lock - restart in that case */
416
- if (add_transaction_credits (journal , blocks , rsv_blocks ))
427
+ if (add_transaction_credits (journal , blocks , rsv_blocks )) {
428
+ /*
429
+ * add_transaction_credits releases
430
+ * j_state_lock on a non-zero return
431
+ */
432
+ __release (& journal -> j_state_lock );
417
433
goto repeat ;
434
+ }
418
435
} else {
419
436
/*
420
437
* We have handle reserved so we are allowed to join T_LOCKED
0 commit comments