@@ -261,7 +261,8 @@ int __ext4_handle_dirty_super(const char *where, unsigned int line,
261
261
__ext4_handle_dirty_super(__func__, __LINE__, (handle), (sb))
262
262
263
263
handle_t * __ext4_journal_start_sb (struct super_block * sb , unsigned int line ,
264
- int type , int blocks , int rsv_blocks );
264
+ int type , int blocks , int rsv_blocks ,
265
+ int revoke_creds );
265
266
int __ext4_journal_stop (const char * where , unsigned int line , handle_t * handle );
266
267
267
268
#define EXT4_NOJOURNAL_MAX_REF_COUNT ((unsigned long) 4096)
@@ -288,28 +289,41 @@ static inline int ext4_handle_is_aborted(handle_t *handle)
288
289
return 0 ;
289
290
}
290
291
291
- static inline int ext4_handle_has_enough_credits (handle_t * handle , int needed )
292
+ static inline int ext4_free_metadata_revoke_credits (struct super_block * sb ,
293
+ int blocks )
292
294
{
293
- if (ext4_handle_valid (handle ) && handle -> h_buffer_credits < needed )
294
- return 0 ;
295
- return 1 ;
295
+ /* Freeing each metadata block can result in freeing one cluster */
296
+ return blocks * EXT4_SB (sb )-> s_cluster_ratio ;
297
+ }
298
+
299
+ static inline int ext4_trans_default_revoke_credits (struct super_block * sb )
300
+ {
301
+ return ext4_free_metadata_revoke_credits (sb , 8 );
296
302
}
297
303
298
304
#define ext4_journal_start_sb (sb , type , nblocks ) \
299
- __ext4_journal_start_sb((sb), __LINE__, (type), (nblocks), 0)
305
+ __ext4_journal_start_sb((sb), __LINE__, (type), (nblocks), 0, \
306
+ ext4_trans_default_revoke_credits(sb))
300
307
301
308
#define ext4_journal_start (inode , type , nblocks ) \
302
- __ext4_journal_start((inode), __LINE__, (type), (nblocks), 0)
309
+ __ext4_journal_start((inode), __LINE__, (type), (nblocks), 0, \
310
+ ext4_trans_default_revoke_credits((inode)->i_sb))
311
+
312
+ #define ext4_journal_start_with_reserve (inode , type , blocks , rsv_blocks )\
313
+ __ext4_journal_start((inode), __LINE__, (type), (blocks), (rsv_blocks),\
314
+ ext4_trans_default_revoke_credits((inode)->i_sb))
303
315
304
- #define ext4_journal_start_with_reserve (inode , type , blocks , rsv_blocks ) \
305
- __ext4_journal_start((inode), __LINE__, (type), (blocks), (rsv_blocks))
316
+ #define ext4_journal_start_with_revoke (inode , type , blocks , revoke_creds ) \
317
+ __ext4_journal_start((inode), __LINE__, (type), (blocks), 0, \
318
+ (revoke_creds))
306
319
307
320
static inline handle_t * __ext4_journal_start (struct inode * inode ,
308
321
unsigned int line , int type ,
309
- int blocks , int rsv_blocks )
322
+ int blocks , int rsv_blocks ,
323
+ int revoke_creds )
310
324
{
311
325
return __ext4_journal_start_sb (inode -> i_sb , line , type , blocks ,
312
- rsv_blocks );
326
+ rsv_blocks , revoke_creds );
313
327
}
314
328
315
329
#define ext4_journal_stop (handle ) \
@@ -332,20 +346,68 @@ static inline handle_t *ext4_journal_current_handle(void)
332
346
return journal_current_handle ();
333
347
}
334
348
335
- static inline int ext4_journal_extend (handle_t * handle , int nblocks )
349
+ static inline int ext4_journal_extend (handle_t * handle , int nblocks , int revoke )
336
350
{
337
351
if (ext4_handle_valid (handle ))
338
- return jbd2_journal_extend (handle , nblocks );
352
+ return jbd2_journal_extend (handle , nblocks , revoke );
339
353
return 0 ;
340
354
}
341
355
342
- static inline int ext4_journal_restart (handle_t * handle , int nblocks )
356
+ static inline int ext4_journal_restart (handle_t * handle , int nblocks ,
357
+ int revoke )
343
358
{
344
359
if (ext4_handle_valid (handle ))
345
- return jbd2_journal_restart (handle , nblocks );
360
+ return jbd2__journal_restart (handle , nblocks , revoke , GFP_NOFS );
346
361
return 0 ;
347
362
}
348
363
364
+ int __ext4_journal_ensure_credits (handle_t * handle , int check_cred ,
365
+ int extend_cred , int revoke_cred );
366
+
367
+
368
+ /*
369
+ * Ensure @handle has at least @check_creds credits available. If not,
370
+ * transaction will be extended or restarted to contain at least @extend_cred
371
+ * credits. Before restarting transaction @fn is executed to allow for cleanup
372
+ * before the transaction is restarted.
373
+ *
374
+ * The return value is < 0 in case of error, 0 in case the handle has enough
375
+ * credits or transaction extension succeeded, 1 in case transaction had to be
376
+ * restarted.
377
+ */
378
+ #define ext4_journal_ensure_credits_fn (handle , check_cred , extend_cred , \
379
+ revoke_cred , fn ) \
380
+ ({ \
381
+ __label__ __ensure_end; \
382
+ int err = __ext4_journal_ensure_credits((handle), (check_cred), \
383
+ (extend_cred), (revoke_cred)); \
384
+ \
385
+ if (err <= 0) \
386
+ goto __ensure_end; \
387
+ err = (fn); \
388
+ if (err < 0) \
389
+ goto __ensure_end; \
390
+ err = ext4_journal_restart((handle), (extend_cred), (revoke_cred)); \
391
+ if (err == 0) \
392
+ err = 1; \
393
+ __ensure_end: \
394
+ err; \
395
+ })
396
+
397
+ /*
398
+ * Ensure given handle has at least requested amount of credits available,
399
+ * possibly restarting transaction if needed. We also make sure the transaction
400
+ * has space for at least ext4_trans_default_revoke_credits(sb) revoke records
401
+ * as freeing one or two blocks is very common pattern and requesting this is
402
+ * very cheap.
403
+ */
404
+ static inline int ext4_journal_ensure_credits (handle_t * handle , int credits ,
405
+ int revoke_creds )
406
+ {
407
+ return ext4_journal_ensure_credits_fn (handle , credits , credits ,
408
+ revoke_creds , 0 );
409
+ }
410
+
349
411
static inline int ext4_journal_blocks_per_page (struct inode * inode )
350
412
{
351
413
if (EXT4_JOURNAL (inode ) != NULL )
@@ -407,6 +469,7 @@ static inline int ext4_inode_journal_mode(struct inode *inode)
407
469
return EXT4_INODE_WRITEBACK_DATA_MODE ; /* writeback */
408
470
/* We do not support data journalling with delayed allocation */
409
471
if (!S_ISREG (inode -> i_mode ) ||
472
+ ext4_test_inode_flag (inode , EXT4_INODE_EA_INODE ) ||
410
473
test_opt (inode -> i_sb , DATA_FLAGS ) == EXT4_MOUNT_JOURNAL_DATA ||
411
474
(ext4_test_inode_flag (inode , EXT4_INODE_JOURNAL_DATA ) &&
412
475
!test_opt (inode -> i_sb , DELALLOC ))) {
@@ -437,6 +500,19 @@ static inline int ext4_should_writeback_data(struct inode *inode)
437
500
return ext4_inode_journal_mode (inode ) & EXT4_INODE_WRITEBACK_DATA_MODE ;
438
501
}
439
502
503
+ static inline int ext4_free_data_revoke_credits (struct inode * inode , int blocks )
504
+ {
505
+ if (test_opt (inode -> i_sb , DATA_FLAGS ) == EXT4_MOUNT_JOURNAL_DATA )
506
+ return 0 ;
507
+ if (!ext4_should_journal_data (inode ))
508
+ return 0 ;
509
+ /*
510
+ * Data blocks in one extent are contiguous, just account for partial
511
+ * clusters at extent boundaries
512
+ */
513
+ return blocks + 2 * (EXT4_SB (inode -> i_sb )-> s_cluster_ratio - 1 );
514
+ }
515
+
440
516
/*
441
517
* This function controls whether or not we should try to go down the
442
518
* dioread_nolock code paths, which makes it safe to avoid taking
0 commit comments