Merge branch 'jk/jbd2-revoke-overflow'

This commit is contained in:
Theodore Ts'o 2019-11-05 16:02:20 -05:00
commit a6d4040846
21 changed files with 675 additions and 478 deletions

View file

@ -456,7 +456,9 @@ struct jbd2_revoke_table_s;
* @h_transaction: Which compound transaction is this update a part of?
* @h_journal: Which journal handle belongs to - used iff h_reserved set.
* @h_rsv_handle: Handle reserved for finishing the logical operation.
* @h_buffer_credits: Number of remaining buffers we are allowed to dirty.
* @h_total_credits: Number of remaining buffers we are allowed to add to
journal. These are dirty buffers and revoke descriptor blocks.
* @h_revoke_credits: Number of remaining revoke records available for handle
* @h_ref: Reference count on this handle.
* @h_err: Field for caller's use to track errors through large fs operations.
* @h_sync: Flag for sync-on-close.
@ -466,7 +468,8 @@ struct jbd2_revoke_table_s;
* @h_type: For handle statistics.
* @h_line_no: For handle statistics.
* @h_start_jiffies: Handle Start time.
* @h_requested_credits: Holds @h_buffer_credits after handle is started.
* @h_requested_credits: Holds @h_total_credits after handle is started.
* @h_revoke_credits_requested: Holds @h_revoke_credits after handle is started.
* @saved_alloc_context: Saved context while transaction is open.
**/
@ -483,7 +486,9 @@ struct jbd2_journal_handle
};
handle_t *h_rsv_handle;
int h_buffer_credits;
int h_total_credits;
int h_revoke_credits;
int h_revoke_credits_requested;
int h_ref;
int h_err;
@ -660,11 +665,24 @@ struct transaction_s
atomic_t t_updates;
/*
* Number of buffers reserved for use by all handles in this transaction
* handle but not yet modified. [none]
* Number of blocks reserved for this transaction in the journal.
* This is including all credits reserved when starting transaction
* handles as well as all journal descriptor blocks needed for this
* transaction. [none]
*/
atomic_t t_outstanding_credits;
/*
* Number of revoke records for this transaction added by already
* stopped handles. [none]
*/
atomic_t t_outstanding_revokes;
/*
* How many handles used this transaction? [none]
*/
atomic_t t_handle_count;
/*
* Forward and backward links for the circular list of all transactions
* awaiting checkpoint. [j_list_lock]
@ -682,11 +700,6 @@ struct transaction_s
*/
ktime_t t_start_time;
/*
* How many handles used this transaction? [none]
*/
atomic_t t_handle_count;
/*
* This transaction is being forced and some process is
* waiting for it to finish.
@ -1003,6 +1016,13 @@ struct journal_s
*/
int j_max_transaction_buffers;
/**
* @j_revoke_records_per_block:
*
* Number of revoke records that fit in one descriptor block.
*/
int j_revoke_records_per_block;
/**
* @j_commit_interval:
*
@ -1337,14 +1357,16 @@ static inline handle_t *journal_current_handle(void)
extern handle_t *jbd2_journal_start(journal_t *, int nblocks);
extern handle_t *jbd2__journal_start(journal_t *, int blocks, int rsv_blocks,
gfp_t gfp_mask, unsigned int type,
unsigned int line_no);
int revoke_records, gfp_t gfp_mask,
unsigned int type, unsigned int line_no);
extern int jbd2_journal_restart(handle_t *, int nblocks);
extern int jbd2__journal_restart(handle_t *, int nblocks, gfp_t gfp_mask);
extern int jbd2__journal_restart(handle_t *, int nblocks,
int revoke_records, gfp_t gfp_mask);
extern int jbd2_journal_start_reserved(handle_t *handle,
unsigned int type, unsigned int line_no);
extern void jbd2_journal_free_reserved(handle_t *handle);
extern int jbd2_journal_extend (handle_t *, int nblocks);
extern int jbd2_journal_extend(handle_t *handle, int nblocks,
int revoke_records);
extern int jbd2_journal_get_write_access(handle_t *, struct buffer_head *);
extern int jbd2_journal_get_create_access (handle_t *, struct buffer_head *);
extern int jbd2_journal_get_undo_access(handle_t *, struct buffer_head *);
@ -1539,38 +1561,19 @@ static inline int jbd2_journal_has_csum_v2or3(journal_t *journal)
return journal->j_chksum_driver != NULL;
}
/*
* We reserve t_outstanding_credits >> JBD2_CONTROL_BLOCKS_SHIFT for
* transaction control blocks.
*/
#define JBD2_CONTROL_BLOCKS_SHIFT 5
/*
* Return the minimum number of blocks which must be free in the journal
* before a new transaction may be started. Must be called under j_state_lock.
*/
static inline int jbd2_space_needed(journal_t *journal)
{
int nblocks = journal->j_max_transaction_buffers;
return nblocks + (nblocks >> JBD2_CONTROL_BLOCKS_SHIFT);
}
/*
* Return number of free blocks in the log. Must be called under j_state_lock.
*/
static inline unsigned long jbd2_log_space_left(journal_t *journal)
{
/* Allow for rounding errors */
unsigned long free = journal->j_free - 32;
long free = journal->j_free - 32;
if (journal->j_committing_transaction) {
unsigned long committing = atomic_read(&journal->
j_committing_transaction->t_outstanding_credits);
/* Transaction + control blocks */
free -= committing + (committing >> JBD2_CONTROL_BLOCKS_SHIFT);
free -= atomic_read(&journal->
j_committing_transaction->t_outstanding_credits);
}
return free;
return max_t(long, free, 0);
}
/*
@ -1624,6 +1627,16 @@ static inline tid_t jbd2_get_latest_transaction(journal_t *journal)
return tid;
}
static inline int jbd2_handle_buffer_credits(handle_t *handle)
{
journal_t *journal = handle->h_transaction->t_journal;
return handle->h_total_credits -
DIV_ROUND_UP(handle->h_revoke_credits_requested,
journal->j_revoke_records_per_block);
}
#ifdef __KERNEL__
#define buffer_trace_init(bh) do {} while (0)