Re: [PATCH v2 05/12] jbd2: fast-commit commit path new APIs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Aug 8, 2019, at 9:45 PM, Harshad Shirwadkar <harshadshirwadkar@xxxxxxxxx> wrote:
> 
> This patch adds new helper APIs that ext4 needs for fast
> commits. These new fast commit APIs are used by subsequent fast commit
> patches to implement fast commits. Following new APIs are added:
> 
> /*
> * Returns when either a full commit or a fast commit
> * completes
> */
> int jbd2_fc_complete_commit(journal_tc *journal, tid_t tid,
> 			    tid_t tid, tid_t subtid)
> 
> /* Send all the data buffers related to an inode */
> int journal_submit_inode_data(journal_t *journal,
> 			      struct jbd2_inode *jinode)
> 
> /* Map one fast commit buffer for use by the file system */
> int jbd2_map_fc_buf(journal_t *journal, struct buffer_head **bh_out)
> 
> /* Wait on fast commit buffers to complete IO */
> jbd2_wait_on_fc_bufs(journal_t *journal, int num_bufs)
> 
> Signed-off-by: Harshad Shirwadkar <harshadshirwadkar@xxxxxxxxx>

Reviewed-by: Andreas Dilger <adilger@xxxxxxxxx>

> ---
> 
> Changelog:
> 
> V2: 1) Fixed error reported by kbuild test robot. Removed duplicate
>       EXPORT_SYMBOL() call. Also, added EXPORT_SYMBOL() for the new
>       APIs introduced.
>    2) Changed jbd2_submit_fc_bufs() to jbd2_wait_on_fc_bufs(). This
>       gives client file system to submit JBD2 buffers according to
>       its own convenience.
> ---
> fs/jbd2/commit.c     | 32 +++++++++++++++
> fs/jbd2/journal.c    | 98 ++++++++++++++++++++++++++++++++++++++++++++
> include/linux/jbd2.h |  6 +++
> 3 files changed, 136 insertions(+)
> 
> diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
> index 9281814606e7..db62a53436e3 100644
> --- a/fs/jbd2/commit.c
> +++ b/fs/jbd2/commit.c
> @@ -202,6 +202,38 @@ static int journal_submit_inode_data_buffers(struct address_space *mapping,
> 	return ret;
> }
> 
> +int jbd2_submit_inode_data(journal_t *journal, struct jbd2_inode *jinode)
> +{
> +	struct address_space *mapping;
> +	loff_t dirty_start = jinode->i_dirty_start;
> +	loff_t dirty_end = jinode->i_dirty_end;
> +	int ret;
> +
> +	if (!jinode)
> +		return 0;
> +
> +	if (!(jinode->i_flags & JI_WRITE_DATA))
> +		return 0;
> +
> +	dirty_start = jinode->i_dirty_start;
> +	dirty_end = jinode->i_dirty_end;
> +
> +	mapping = jinode->i_vfs_inode->i_mapping;
> +	jinode->i_flags |= JI_COMMIT_RUNNING;
> +
> +	trace_jbd2_submit_inode_data(jinode->i_vfs_inode);
> +	ret = journal_submit_inode_data_buffers(mapping, dirty_start,
> +						dirty_end);
> +
> +	jinode->i_flags &= ~JI_COMMIT_RUNNING;
> +	/* Protect JI_COMMIT_RUNNING flag */
> +	smp_mb();
> +	wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL(jbd2_submit_inode_data);
> +
> /*
>  * Submit all the data buffers of inode associated with the transaction to
>  * disk.
> diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
> index ab05e47ed2d4..1e15804b2c3c 100644
> --- a/fs/jbd2/journal.c
> +++ b/fs/jbd2/journal.c
> @@ -811,6 +811,33 @@ int jbd2_complete_transaction(journal_t *journal, tid_t tid)
> }
> EXPORT_SYMBOL(jbd2_complete_transaction);
> 
> +int jbd2_fc_complete_commit(journal_t *journal, tid_t tid, tid_t subtid)
> +{
> +	int	need_to_wait = 1;
> +
> +	read_lock(&journal->j_state_lock);
> +	if (journal->j_running_transaction &&
> +	    journal->j_running_transaction->t_tid == tid) {
> +		/* Check if fast commit was already done */
> +		if (journal->j_subtid > subtid)
> +			need_to_wait = 0;
> +		if (journal->j_commit_request != tid) {
> +			/* transaction not yet started, so request it */
> +			read_unlock(&journal->j_state_lock);
> +			jbd2_log_start_commit(journal, tid, false);
> +			goto wait_commit;
> +		}
> +	} else if (!(journal->j_committing_transaction &&
> +		     journal->j_committing_transaction->t_tid == tid))
> +		need_to_wait = 0;
> +	read_unlock(&journal->j_state_lock);
> +	if (!need_to_wait)
> +		return 0;
> +wait_commit:
> +	return __jbd2_log_wait_commit(journal, tid, subtid);
> +}
> +EXPORT_SYMBOL(jbd2_fc_complete_commit);
> +
> /*
>  * Log buffer allocation routines:
>  */
> @@ -831,6 +858,77 @@ int jbd2_journal_next_log_block(journal_t *journal, unsigned long long *retp)
> 	return jbd2_journal_bmap(journal, blocknr, retp);
> }
> 
> +int jbd2_map_fc_buf(journal_t *journal, struct buffer_head **bh_out)
> +{
> +	unsigned long long pblock;
> +	unsigned long blocknr;
> +	int ret = 0;
> +	struct buffer_head *bh;
> +	int fc_off;
> +	journal_header_t *jhdr;
> +
> +	write_lock(&journal->j_state_lock);
> +
> +	if (journal->j_fc_off + journal->j_first_fc < journal->j_last_fc) {
> +		fc_off = journal->j_fc_off;
> +		blocknr = journal->j_first_fc + fc_off;
> +		journal->j_fc_off++;
> +	} else {
> +		ret = -EINVAL;
> +	}
> +	write_unlock(&journal->j_state_lock);
> +
> +	if (ret)
> +		return ret;
> +
> +	ret = jbd2_journal_bmap(journal, blocknr, &pblock);
> +	if (ret)
> +		return ret;
> +
> +	bh = __getblk(journal->j_dev, pblock, journal->j_blocksize);
> +	if (!bh)
> +		return -ENOMEM;
> +
> +	lock_buffer(bh);
> +	jhdr = (journal_header_t *)bh->b_data;
> +	jhdr->h_magic = cpu_to_be32(JBD2_MAGIC_NUMBER);
> +	jhdr->h_blocktype = cpu_to_be32(JBD2_FC_BLOCK);
> +	jhdr->h_sequence = cpu_to_be32(journal->j_running_transaction->t_tid);
> +
> +	set_buffer_uptodate(bh);
> +	unlock_buffer(bh);
> +	journal->j_fc_wbuf[fc_off] = bh;
> +
> +	*bh_out = bh;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(jbd2_map_fc_buf);
> +
> +int jbd2_wait_on_fc_bufs(journal_t *journal, int num_blks)
> +{
> +	struct buffer_head *bh;
> +	int i, j_fc_off;
> +
> +	read_lock(&journal->j_state_lock);
> +	j_fc_off = journal->j_fc_off;
> +	read_unlock(&journal->j_state_lock);
> +
> +	/*
> +	 * Wait in reverse order to minimize chances of us being woken up before
> +	 * all IOs have completed
> +	 */
> +	for (i = j_fc_off - 1; i >= j_fc_off - num_blks; i--) {
> +		bh = journal->j_fc_wbuf[i];
> +		wait_on_buffer(bh);
> +		if (unlikely(!buffer_uptodate(bh)))
> +			return -EIO;
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(jbd2_wait_on_fc_bufs);
> +
> /*
>  * Conversion of logical to physical block numbers for the journal
>  *
> diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
> index 535f88dff653..5362777d06f8 100644
> --- a/include/linux/jbd2.h
> +++ b/include/linux/jbd2.h
> @@ -124,6 +124,7 @@ typedef struct journal_s	journal_t;	/* Journal control structure */
> #define JBD2_SUPERBLOCK_V1	3
> #define JBD2_SUPERBLOCK_V2	4
> #define JBD2_REVOKE_BLOCK	5
> +#define JBD2_FC_BLOCK		6
> 
> /*
>  * Standard header for all descriptor blocks:
> @@ -1582,6 +1583,7 @@ int jbd2_transaction_committed(journal_t *journal, tid_t tid);
> int jbd2_complete_transaction(journal_t *journal, tid_t tid);
> int jbd2_log_do_checkpoint(journal_t *journal);
> int jbd2_trans_will_send_data_barrier(journal_t *journal, tid_t tid);
> +int jbd2_fc_complete_commit(journal_t *journal, tid_t tid, tid_t subtid);
> 
> void __jbd2_log_wait_for_space(journal_t *journal);
> extern void __jbd2_journal_drop_transaction(journal_t *, transaction_t *);
> @@ -1732,6 +1734,10 @@ static inline tid_t  jbd2_get_latest_transaction(journal_t *journal)
> 	return tid;
> }
> 
> +int jbd2_map_fc_buf(journal_t *journal, struct buffer_head **bh_out);
> +int jbd2_wait_on_fc_bufs(journal_t *journal, int num_blks);
> +int jbd2_submit_inode_data(journal_t *journal, struct jbd2_inode *jinode);
> +
> #ifdef __KERNEL__
> 
> #define buffer_trace_init(bh)	do {} while (0)
> --
> 2.23.0.rc1.153.gdeed80330f-goog
> 


Cheers, Andreas





Attachment: signature.asc
Description: Message signed with OpenPGP


[Index of Archives]     [Reiser Filesystem Development]     [Ceph FS]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite National Park]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Media]

  Powered by Linux