mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
This merge window saw the the following new featuers added to ext4:
* Direct I/O via iomap (required the iomap-for-next branch from Darrick as a prereq). * Support for using dioread-nolock where the block size < page size. * Support for encryption for file systems where the block size < page size. * Rework of journal credits handling so a revoke-heavy workload will not cause the journal to run out of space. * Replace bit-spinlocks with spinlocks in jbd2 Also included were some bug fixes and cleanups, mostly to clean up corner cases from fuzzed file systems and error path handling. -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEK2m5VNv+CHkogTfJ8vlZVpUNgaMFAl3dHxoACgkQ8vlZVpUN gaMZswf5AbtQhTEJDXO7Pc1ull38GIGFgAv7uAth0TymLC3h1/FEYWW0crEPFsDr 1Eei55UUVOYrMMUKQ4P7wlLX0cIh3XDPMWnRFuqBoV5/ZOsH/ZSbkY//TG2Xze/v 9wXIH/RKQnzbRtXffJ1+DnvmXJk+HFm1R1gjl0nfyUXGrnlSfqJxhLSczyd6bJJq ehi/tso5UC/4EQsAIdWp7VWsAdaHcZ7ogHqDoy8dXpM1equ408iml7VlKr8R+Nr7 5ANpCISXChSlLLYm0NYN5vhO8upF5uDxWLdCtxVPL5kFdM2m/ELjXw9h9C+78l7C EWJGlGlxvx07Px+e+bfStEsoixpWBg== =0eko -----END PGP SIGNATURE----- Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4 Pull ext4 updates from Ted Ts'o: "This merge window saw the the following new featuers added to ext4: - Direct I/O via iomap (required the iomap-for-next branch from Darrick as a prereq). - Support for using dioread-nolock where the block size < page size. - Support for encryption for file systems where the block size < page size. - Rework of journal credits handling so a revoke-heavy workload will not cause the journal to run out of space. - Replace bit-spinlocks with spinlocks in jbd2 Also included were some bug fixes and cleanups, mostly to clean up corner cases from fuzzed file systems and error path handling" * tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (59 commits) ext4: work around deleting a file with i_nlink == 0 safely ext4: add more paranoia checking in ext4_expand_extra_isize handling jbd2: make jbd2_handle_buffer_credits() handle reserved handles ext4: fix a bug in ext4_wait_for_tail_page_commit ext4: bio_alloc with __GFP_DIRECT_RECLAIM never fails ext4: code cleanup for get_next_id ext4: fix leak of quota reservations ext4: remove unused variable warning in parse_options() ext4: Enable encryption for subpage-sized blocks fs/buffer.c: support fscrypt in block_read_full_page() ext4: Add error handling for io_end_vec struct allocation jbd2: Fine tune estimate of necessary descriptor blocks jbd2: Provide trace event for handle restarts ext4: Reserve revoke credits for freed blocks jbd2: Make credit checking more strict jbd2: Rename h_buffer_credits to h_total_credits jbd2: Reserve space for revoke descriptor blocks jbd2: Drop jbd2_space_needed() jbd2: Account descriptor blocks into t_outstanding_credits jbd2: Factor out common parts of stopping and restarting a handle ...
This commit is contained in:
commit
50b8b3f85a
30 changed files with 1713 additions and 1483 deletions
|
@ -313,7 +313,6 @@ enum jbd_state_bits {
|
|||
BH_Revoked, /* Has been revoked from the log */
|
||||
BH_RevokeValid, /* Revoked flag is valid */
|
||||
BH_JBDDirty, /* Is dirty but journaled */
|
||||
BH_State, /* Pins most journal_head state */
|
||||
BH_JournalHead, /* Pins bh->b_private and jh->b_bh */
|
||||
BH_Shadow, /* IO on shadow buffer is running */
|
||||
BH_Verified, /* Metadata block has been verified ok */
|
||||
|
@ -342,26 +341,6 @@ static inline struct journal_head *bh2jh(struct buffer_head *bh)
|
|||
return bh->b_private;
|
||||
}
|
||||
|
||||
static inline void jbd_lock_bh_state(struct buffer_head *bh)
|
||||
{
|
||||
bit_spin_lock(BH_State, &bh->b_state);
|
||||
}
|
||||
|
||||
static inline int jbd_trylock_bh_state(struct buffer_head *bh)
|
||||
{
|
||||
return bit_spin_trylock(BH_State, &bh->b_state);
|
||||
}
|
||||
|
||||
static inline int jbd_is_locked_bh_state(struct buffer_head *bh)
|
||||
{
|
||||
return bit_spin_is_locked(BH_State, &bh->b_state);
|
||||
}
|
||||
|
||||
static inline void jbd_unlock_bh_state(struct buffer_head *bh)
|
||||
{
|
||||
bit_spin_unlock(BH_State, &bh->b_state);
|
||||
}
|
||||
|
||||
static inline void jbd_lock_bh_journal_head(struct buffer_head *bh)
|
||||
{
|
||||
bit_spin_lock(BH_JournalHead, &bh->b_state);
|
||||
|
@ -477,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.
|
||||
|
@ -487,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.
|
||||
**/
|
||||
|
||||
|
@ -504,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;
|
||||
|
||||
|
@ -556,9 +540,9 @@ struct transaction_chp_stats_s {
|
|||
* ->jbd_lock_bh_journal_head() (This is "innermost")
|
||||
*
|
||||
* j_state_lock
|
||||
* ->jbd_lock_bh_state()
|
||||
* ->b_state_lock
|
||||
*
|
||||
* jbd_lock_bh_state()
|
||||
* b_state_lock
|
||||
* ->j_list_lock
|
||||
*
|
||||
* j_state_lock
|
||||
|
@ -681,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]
|
||||
|
@ -703,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.
|
||||
|
@ -1024,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:
|
||||
*
|
||||
|
@ -1257,7 +1256,7 @@ JBD2_FEATURE_INCOMPAT_FUNCS(csum3, CSUM_V3)
|
|||
|
||||
/* Filing buffers */
|
||||
extern void jbd2_journal_unfile_buffer(journal_t *, struct journal_head *);
|
||||
extern void __jbd2_journal_refile_buffer(struct journal_head *);
|
||||
extern bool __jbd2_journal_refile_buffer(struct journal_head *);
|
||||
extern void jbd2_journal_refile_buffer(journal_t *, struct journal_head *);
|
||||
extern void __jbd2_journal_file_buffer(struct journal_head *, transaction_t *, int);
|
||||
extern void __journal_free_buffer(struct journal_head *bh);
|
||||
|
@ -1358,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 *);
|
||||
|
@ -1560,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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1645,6 +1627,20 @@ 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;
|
||||
|
||||
if (!handle->h_reserved)
|
||||
journal = handle->h_transaction->t_journal;
|
||||
else
|
||||
journal = handle->h_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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue