From: Jan Kara <jack@suse.cz>
To: Dmitry Monakhov <dmonakhov@openvz.org>
Cc: linux-ext4@vger.kernel.org, jack@suse.cz
Subject: Re: [PATCH 2/5] jbd2: optimize jbd2_journal_force_commit
Date: Mon, 15 Apr 2013 14:29:13 +0200 [thread overview]
Message-ID: <20130415122913.GF2299@quack.suse.cz> (raw)
In-Reply-To: <1365966097-8968-2-git-send-email-dmonakhov@openvz.org>
On Sun 14-04-13 23:01:34, Dmitry Monakhov wrote:
> Current implementation of jbd2_journal_force_commit() is suboptimal because
> result in empty and useless commits. But callers just want to force and wait
> any unfinished commits. We already has jbd2_journal_force_commit_nested()
> which does exactly what we want, except we are guaranteed that we do not hold
> journal transaction open.
Umm, I have a questions regarding this patch:
Grep shows there are just two places in the code which use
ext4_force_commit() (and thus jbd2_journal_force_commit()). These are
ext4_write_inode() and ext4_sync_file() (in data=journal mode). The first
callsite can use _nested() variant immediately as we even assert there's
no handle started. The second call site can use the _nested variant as well
because if we had the transaction started when entering ext4_sync_file() we
would have serious problems (lock inversion, deadlocks in !data=journal
modes) anyway. So IMO there's no need for !nested variant at all (at least
in ext4, ocfs2 uses it as well, IMHO it can be converted as well but that's
a different topic). Thoughts?
Honza
> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
> ---
> fs/jbd2/journal.c | 58 ++++++++++++++++++++++++++++++++++++------------
> fs/jbd2/transaction.c | 23 -------------------
> include/linux/jbd2.h | 2 +-
> 3 files changed, 44 insertions(+), 39 deletions(-)
>
> diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
> index 886ec2f..cfe0aca 100644
> --- a/fs/jbd2/journal.c
> +++ b/fs/jbd2/journal.c
> @@ -566,21 +566,19 @@ int jbd2_log_start_commit(journal_t *journal, tid_t tid)
> }
>
> /*
> - * Force and wait upon a commit if the calling process is not within
> - * transaction. This is used for forcing out undo-protected data which contains
> - * bitmaps, when the fs is running out of space.
> - *
> - * We can only force the running transaction if we don't have an active handle;
> - * otherwise, we will deadlock.
> - *
> - * Returns true if a transaction was started.
> + * Force and wait any uncommitted transactions. We can only force the running
> + * transaction if we don't have an active handle, otherwise, we will deadlock.
> */
> -int jbd2_journal_force_commit_nested(journal_t *journal)
> +int __jbd2_journal_force_commit(journal_t *journal, int nested, int *progress)
> {
> transaction_t *transaction = NULL;
> tid_t tid;
> - int need_to_start = 0;
> + int need_to_start = 0, ret = 0;
>
> + J_ASSERT(!current->journal_info || nested);
> +
> + if (progress)
> + *progress = 0;
> read_lock(&journal->j_state_lock);
> if (journal->j_running_transaction && !current->journal_info) {
> transaction = journal->j_running_transaction;
> @@ -590,16 +588,46 @@ int jbd2_journal_force_commit_nested(journal_t *journal)
> transaction = journal->j_committing_transaction;
>
> if (!transaction) {
> + /* Nothing to commit */
> read_unlock(&journal->j_state_lock);
> - return 0; /* Nothing to retry */
> + return 0;
> }
> -
> tid = transaction->t_tid;
> read_unlock(&journal->j_state_lock);
> if (need_to_start)
> - jbd2_log_start_commit(journal, tid);
> - jbd2_log_wait_commit(journal, tid);
> - return 1;
> + ret = jbd2_log_start_commit(journal, tid);
> + if (!ret)
> + ret = jbd2_log_wait_commit(journal, tid);
> + if (!ret && progress)
> + *progress = 1;
> +
> + return ret;
> +}
> +
> +/**
> + * Force and wait upon a commit if the calling process is not within
> + * transaction. This is used for forcing out undo-protected data which contains
> + * bitmaps, when the fs is running out of space.
> + *
> + * @journal: journal to force
> + * Returns true if progress was made.
> + */
> +int jbd2_journal_force_commit_nested(journal_t *journal)
> +{
> + int progress;
> +
> + __jbd2_journal_force_commit(journal, 1, &progress);
> + return progress;
> +}
> +
> +/**
> + * int journal_force_commit() - force any uncommitted transactions
> + * @journal: journal to force
> + *
> + */
> +int jbd2_journal_force_commit(journal_t *journal)
> +{
> + return __jbd2_journal_force_commit(journal, 0, NULL);
> }
>
> /*
> diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
> index 325bc01..bb2a5c0 100644
> --- a/fs/jbd2/transaction.c
> +++ b/fs/jbd2/transaction.c
> @@ -1515,29 +1515,6 @@ int jbd2_journal_stop(handle_t *handle)
> return err;
> }
>
> -/**
> - * int jbd2_journal_force_commit() - force any uncommitted transactions
> - * @journal: journal to force
> - *
> - * For synchronous operations: force any uncommitted transactions
> - * to disk. May seem kludgy, but it reuses all the handle batching
> - * code in a very simple manner.
> - */
> -int jbd2_journal_force_commit(journal_t *journal)
> -{
> - handle_t *handle;
> - int ret;
> -
> - handle = jbd2_journal_start(journal, 1);
> - if (IS_ERR(handle)) {
> - ret = PTR_ERR(handle);
> - } else {
> - handle->h_sync = 1;
> - ret = jbd2_journal_stop(handle);
> - }
> - return ret;
> -}
> -
> /*
> *
> * List management code snippets: various functions for manipulating the
> diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
> index f9fe889..7b38517 100644
> --- a/include/linux/jbd2.h
> +++ b/include/linux/jbd2.h
> @@ -1125,6 +1125,7 @@ extern void jbd2_journal_ack_err (journal_t *);
> extern int jbd2_journal_clear_err (journal_t *);
> extern int jbd2_journal_bmap(journal_t *, unsigned long, unsigned long long *);
> extern int jbd2_journal_force_commit(journal_t *);
> +extern int jbd2_journal_force_commit_nested(journal_t *);
> extern int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *inode);
> extern int jbd2_journal_begin_ordered_truncate(journal_t *journal,
> struct jbd2_inode *inode, loff_t new_size);
> @@ -1199,7 +1200,6 @@ int __jbd2_log_space_left(journal_t *); /* Called with journal locked */
> int jbd2_log_start_commit(journal_t *journal, tid_t tid);
> int __jbd2_log_start_commit(journal_t *journal, tid_t tid);
> int jbd2_journal_start_commit(journal_t *journal, tid_t *tid);
> -int jbd2_journal_force_commit_nested(journal_t *journal);
> int jbd2_log_wait_commit(journal_t *journal, tid_t tid);
> int jbd2_complete_transaction(journal_t *journal, tid_t tid);
> int jbd2_log_do_checkpoint(journal_t *journal);
> --
> 1.7.1
>
--
Jan Kara <jack@suse.cz>
SUSE Labs, CR
next prev parent reply other threads:[~2013-04-16 16:36 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-14 19:01 [PATCH 1/5] ext4: convert write_begin methods to stable_page_writes semantics Dmitry Monakhov
2013-04-14 19:01 ` [PATCH 2/5] jbd2: optimize jbd2_journal_force_commit Dmitry Monakhov
2013-04-15 12:29 ` Jan Kara [this message]
2013-04-17 7:39 ` Dmitry Monakhov
2013-04-18 18:07 ` Jan Kara
2013-04-22 8:11 ` Dmitry Monakhov
2013-04-23 8:51 ` Jan Kara
2013-08-28 18:33 ` Theodore Ts'o
2013-04-14 19:01 ` [PATCH 3/5] ext4: fix data integrity for ext4_sync_fs Dmitry Monakhov
2013-04-15 13:59 ` Jan Kara
2013-04-14 19:01 ` [PATCH 4/5] jbd: optimize journal_force_commit Dmitry Monakhov
2013-04-14 19:01 ` [PATCH 5/5] ext3: fix data integrity for ext4_sync_fs Dmitry Monakhov
2013-04-15 12:01 ` [PATCH 1/5] ext4: convert write_begin methods to stable_page_writes semantics Jan Kara
2013-04-22 12:36 ` Zheng Liu
2013-08-28 18:32 ` Theodore Ts'o
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130415122913.GF2299@quack.suse.cz \
--to=jack@suse.cz \
--cc=dmonakhov@openvz.org \
--cc=linux-ext4@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).