Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit e3a00a2

Browse files
jankaratytso
authored andcommitted
jbd2: precompute number of transaction descriptor blocks
Instead of computing the number of descriptor blocks a transaction can have each time we need it (which is currently when starting each transaction but will become more frequent later) precompute the number once during journal initialization together with maximum transaction size. We perform the precomputation whenever journal feature set is updated similarly as for computation of journal->j_revoke_records_per_block. CC: [email protected] Signed-off-by: Jan Kara <[email protected]> Reviewed-by: Zhang Yi <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 4aa99c7 commit e3a00a2

File tree

3 files changed

+54
-38
lines changed

3 files changed

+54
-38
lines changed

fs/jbd2/journal.c

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,6 +1427,48 @@ static int journal_revoke_records_per_block(journal_t *journal)
14271427
return space / record_size;
14281428
}
14291429

1430+
static int jbd2_journal_get_max_txn_bufs(journal_t *journal)
1431+
{
1432+
return (journal->j_total_len - journal->j_fc_wbufsize) / 4;
1433+
}
1434+
1435+
/*
1436+
* Base amount of descriptor blocks we reserve for each transaction.
1437+
*/
1438+
static int jbd2_descriptor_blocks_per_trans(journal_t *journal)
1439+
{
1440+
int tag_space = journal->j_blocksize - sizeof(journal_header_t);
1441+
int tags_per_block;
1442+
1443+
/* Subtract UUID */
1444+
tag_space -= 16;
1445+
if (jbd2_journal_has_csum_v2or3(journal))
1446+
tag_space -= sizeof(struct jbd2_journal_block_tail);
1447+
/* Commit code leaves a slack space of 16 bytes at the end of block */
1448+
tags_per_block = (tag_space - 16) / journal_tag_bytes(journal);
1449+
/*
1450+
* Revoke descriptors are accounted separately so we need to reserve
1451+
* space for commit block and normal transaction descriptor blocks.
1452+
*/
1453+
return 1 + DIV_ROUND_UP(jbd2_journal_get_max_txn_bufs(journal),
1454+
tags_per_block);
1455+
}
1456+
1457+
/*
1458+
* Initialize number of blocks each transaction reserves for its bookkeeping
1459+
* and maximum number of blocks a transaction can use. This needs to be called
1460+
* after the journal size and the fastcommit area size are initialized.
1461+
*/
1462+
static void jbd2_journal_init_transaction_limits(journal_t *journal)
1463+
{
1464+
journal->j_revoke_records_per_block =
1465+
journal_revoke_records_per_block(journal);
1466+
journal->j_transaction_overhead_buffers =
1467+
jbd2_descriptor_blocks_per_trans(journal);
1468+
journal->j_max_transaction_buffers =
1469+
jbd2_journal_get_max_txn_bufs(journal);
1470+
}
1471+
14301472
/*
14311473
* Load the on-disk journal superblock and read the key fields into the
14321474
* journal_t.
@@ -1468,8 +1510,8 @@ static int journal_load_superblock(journal_t *journal)
14681510
if (jbd2_journal_has_csum_v2or3(journal))
14691511
journal->j_csum_seed = jbd2_chksum(journal, ~0, sb->s_uuid,
14701512
sizeof(sb->s_uuid));
1471-
journal->j_revoke_records_per_block =
1472-
journal_revoke_records_per_block(journal);
1513+
/* After journal features are set, we can compute transaction limits */
1514+
jbd2_journal_init_transaction_limits(journal);
14731515

14741516
if (jbd2_has_feature_fast_commit(journal)) {
14751517
journal->j_fc_last = be32_to_cpu(sb->s_maxlen);
@@ -1674,11 +1716,6 @@ journal_t *jbd2_journal_init_inode(struct inode *inode)
16741716
return journal;
16751717
}
16761718

1677-
static int jbd2_journal_get_max_txn_bufs(journal_t *journal)
1678-
{
1679-
return (journal->j_total_len - journal->j_fc_wbufsize) / 4;
1680-
}
1681-
16821719
/*
16831720
* Given a journal_t structure, initialise the various fields for
16841721
* startup of a new journaling session. We use this both when creating
@@ -1724,8 +1761,6 @@ static int journal_reset(journal_t *journal)
17241761
journal->j_commit_sequence = journal->j_transaction_sequence - 1;
17251762
journal->j_commit_request = journal->j_commit_sequence;
17261763

1727-
journal->j_max_transaction_buffers = jbd2_journal_get_max_txn_bufs(journal);
1728-
17291764
/*
17301765
* Now that journal recovery is done, turn fast commits off here. This
17311766
* way, if fast commit was enabled before the crash but if now FS has
@@ -2266,8 +2301,6 @@ jbd2_journal_initialize_fast_commit(journal_t *journal)
22662301
journal->j_fc_first = journal->j_last + 1;
22672302
journal->j_fc_off = 0;
22682303
journal->j_free = journal->j_last - journal->j_first;
2269-
journal->j_max_transaction_buffers =
2270-
jbd2_journal_get_max_txn_bufs(journal);
22712304

22722305
return 0;
22732306
}
@@ -2355,8 +2388,7 @@ int jbd2_journal_set_features(journal_t *journal, unsigned long compat,
23552388
sb->s_feature_ro_compat |= cpu_to_be32(ro);
23562389
sb->s_feature_incompat |= cpu_to_be32(incompat);
23572390
unlock_buffer(journal->j_sb_buffer);
2358-
journal->j_revoke_records_per_block =
2359-
journal_revoke_records_per_block(journal);
2391+
jbd2_journal_init_transaction_limits(journal);
23602392

23612393
return 1;
23622394
#undef COMPAT_FEATURE_ON
@@ -2387,8 +2419,7 @@ void jbd2_journal_clear_features(journal_t *journal, unsigned long compat,
23872419
sb->s_feature_compat &= ~cpu_to_be32(compat);
23882420
sb->s_feature_ro_compat &= ~cpu_to_be32(ro);
23892421
sb->s_feature_incompat &= ~cpu_to_be32(incompat);
2390-
journal->j_revoke_records_per_block =
2391-
journal_revoke_records_per_block(journal);
2422+
jbd2_journal_init_transaction_limits(journal);
23922423
}
23932424
EXPORT_SYMBOL(jbd2_journal_clear_features);
23942425

fs/jbd2/transaction.c

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -62,28 +62,6 @@ void jbd2_journal_free_transaction(transaction_t *transaction)
6262
kmem_cache_free(transaction_cache, transaction);
6363
}
6464

65-
/*
66-
* Base amount of descriptor blocks we reserve for each transaction.
67-
*/
68-
static int jbd2_descriptor_blocks_per_trans(journal_t *journal)
69-
{
70-
int tag_space = journal->j_blocksize - sizeof(journal_header_t);
71-
int tags_per_block;
72-
73-
/* Subtract UUID */
74-
tag_space -= 16;
75-
if (jbd2_journal_has_csum_v2or3(journal))
76-
tag_space -= sizeof(struct jbd2_journal_block_tail);
77-
/* Commit code leaves a slack space of 16 bytes at the end of block */
78-
tags_per_block = (tag_space - 16) / journal_tag_bytes(journal);
79-
/*
80-
* Revoke descriptors are accounted separately so we need to reserve
81-
* space for commit block and normal transaction descriptor blocks.
82-
*/
83-
return 1 + DIV_ROUND_UP(journal->j_max_transaction_buffers,
84-
tags_per_block);
85-
}
86-
8765
/*
8866
* jbd2_get_transaction: obtain a new transaction_t object.
8967
*
@@ -109,7 +87,7 @@ static void jbd2_get_transaction(journal_t *journal,
10987
transaction->t_expires = jiffies + journal->j_commit_interval;
11088
atomic_set(&transaction->t_updates, 0);
11189
atomic_set(&transaction->t_outstanding_credits,
112-
jbd2_descriptor_blocks_per_trans(journal) +
90+
journal->j_transaction_overhead_buffers +
11391
atomic_read(&journal->j_reserved_credits));
11492
atomic_set(&transaction->t_outstanding_revokes, 0);
11593
atomic_set(&transaction->t_handle_count, 0);

include/linux/jbd2.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,13 @@ struct journal_s
10851085
*/
10861086
int j_revoke_records_per_block;
10871087

1088+
/**
1089+
* @j_transaction_overhead:
1090+
*
1091+
* Number of blocks each transaction needs for its own bookkeeping
1092+
*/
1093+
int j_transaction_overhead_buffers;
1094+
10881095
/**
10891096
* @j_commit_interval:
10901097
*

0 commit comments

Comments
 (0)