From: Miao Xie <miaox@cn.fujitsu.com>
To: Filipe Manana <fdmanana@suse.com>, <linux-btrfs@vger.kernel.org>
Subject: Re: [PATCH 2/2 v5] Btrfs: be aware of btree inode write errors to avoid fs corruption
Date: Wed, 24 Sep 2014 19:16:16 +0800 [thread overview]
Message-ID: <5422A800.9030308@cn.fujitsu.com> (raw)
In-Reply-To: <1411554506-4238-1-git-send-email-fdmanana@suse.com>
On Wed, 24 Sep 2014 11:28:26 +0100, Filipe Manana wrote:
[SNIP]
> int btrfs_wait_marked_extents(struct btrfs_root *root,
> + struct btrfs_trans_handle *trans,
> struct extent_io_tree *dirty_pages, int mark)
> {
> int err = 0;
> @@ -852,6 +855,7 @@ int btrfs_wait_marked_extents(struct btrfs_root *root,
> struct extent_state *cached_state = NULL;
> u64 start = 0;
> u64 end;
> + int errors;
>
> while (!find_first_extent_bit(dirty_pages, start, &start, &end,
> EXTENT_NEED_WAIT, &cached_state)) {
> @@ -865,6 +869,16 @@ int btrfs_wait_marked_extents(struct btrfs_root *root,
> }
> if (err)
> werr = err;
> +
> + if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID)
> + errors = atomic_xchg(
> + &trans->transaction->log_eb_write_errors, 0);
> + else
> + errors = atomic_xchg(&trans->transaction->eb_write_errors, 0);
There is a bug in log tree commit case.
As we know, each fs/file tree has two log sub-transaction, when we are committing
a log sub-transaction, the other one may be started by the other file sync tasks.
It is very likely that there is no any error happens in the former, but some write
errors happen in the latter. The above code might clear the number of that errors.
So I think the variant for log write error should be created for each log sub-transaction.
Thanks
Miao
> +
> + if (errors && !werr)
> + werr = -EIO;
> +
> return werr;
> }
>
> @@ -874,6 +888,7 @@ int btrfs_wait_marked_extents(struct btrfs_root *root,
> * those extents are on disk for transaction or log commit
> */
> static int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
> + struct btrfs_trans_handle *trans,
> struct extent_io_tree *dirty_pages, int mark)
> {
> int ret;
> @@ -883,7 +898,7 @@ static int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
> blk_start_plug(&plug);
> ret = btrfs_write_marked_extents(root, dirty_pages, mark);
> blk_finish_plug(&plug);
> - ret2 = btrfs_wait_marked_extents(root, dirty_pages, mark);
> + ret2 = btrfs_wait_marked_extents(root, trans, dirty_pages, mark);
>
> if (ret)
> return ret;
> @@ -892,7 +907,7 @@ static int btrfs_write_and_wait_marked_extents(struct btrfs_root *root,
> return 0;
> }
>
> -int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
> +static int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
> struct btrfs_root *root)
> {
> if (!trans || !trans->transaction) {
> @@ -900,7 +915,7 @@ int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
> btree_inode = root->fs_info->btree_inode;
> return filemap_write_and_wait(btree_inode->i_mapping);
> }
> - return btrfs_write_and_wait_marked_extents(root,
> + return btrfs_write_and_wait_marked_extents(root, trans,
> &trans->transaction->dirty_pages,
> EXTENT_DIRTY);
> }
> diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
> index 7dd558e..311f3e3 100644
> --- a/fs/btrfs/transaction.h
> +++ b/fs/btrfs/transaction.h
> @@ -46,6 +46,8 @@ struct btrfs_transaction {
> */
> atomic_t num_writers;
> atomic_t use_count;
> + atomic_t eb_write_errors;
> + atomic_t log_eb_write_errors;
>
> /* Be protected by fs_info->trans_lock when we want to change it. */
> enum btrfs_trans_state state;
> @@ -146,8 +148,6 @@ struct btrfs_trans_handle *btrfs_attach_transaction_barrier(
> struct btrfs_root *root);
> struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root);
> int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid);
> -int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
> - struct btrfs_root *root);
>
> void btrfs_add_dead_root(struct btrfs_root *root);
> int btrfs_defrag_root(struct btrfs_root *root);
> @@ -167,6 +167,7 @@ int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans,
> int btrfs_write_marked_extents(struct btrfs_root *root,
> struct extent_io_tree *dirty_pages, int mark);
> int btrfs_wait_marked_extents(struct btrfs_root *root,
> + struct btrfs_trans_handle *trans,
> struct extent_io_tree *dirty_pages, int mark);
> int btrfs_transaction_blocked(struct btrfs_fs_info *info);
> int btrfs_transaction_in_commit(struct btrfs_fs_info *info);
> diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
> index 2d0fa43..22ffd32 100644
> --- a/fs/btrfs/tree-log.c
> +++ b/fs/btrfs/tree-log.c
> @@ -2583,7 +2583,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
> mutex_unlock(&log_root_tree->log_mutex);
> goto out;
> }
> - btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
> + btrfs_wait_marked_extents(log, trans, &log->dirty_log_pages,
> + mark);
> btrfs_free_logged_extents(log, log_transid);
> mutex_unlock(&log_root_tree->log_mutex);
> ret = -EAGAIN;
> @@ -2599,7 +2600,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
> index2 = root_log_ctx.log_transid % 2;
> if (atomic_read(&log_root_tree->log_commit[index2])) {
> blk_finish_plug(&plug);
> - btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
> + btrfs_wait_marked_extents(log, trans, &log->dirty_log_pages,
> + mark);
> wait_log_commit(trans, log_root_tree,
> root_log_ctx.log_transid);
> btrfs_free_logged_extents(log, log_transid);
> @@ -2623,7 +2625,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
> */
> if (btrfs_need_log_full_commit(root->fs_info, trans)) {
> blk_finish_plug(&plug);
> - btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
> + btrfs_wait_marked_extents(log, trans, &log->dirty_log_pages,
> + mark);
> btrfs_free_logged_extents(log, log_transid);
> mutex_unlock(&log_root_tree->log_mutex);
> ret = -EAGAIN;
> @@ -2641,8 +2644,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
> mutex_unlock(&log_root_tree->log_mutex);
> goto out_wake_log_root;
> }
> - btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
> - btrfs_wait_marked_extents(log_root_tree,
> + btrfs_wait_marked_extents(log, trans, &log->dirty_log_pages, mark);
> + btrfs_wait_marked_extents(log_root_tree, trans,
> &log_root_tree->dirty_log_pages,
> EXTENT_NEW | EXTENT_DIRTY);
> btrfs_wait_logged_extents(log, log_transid);
>
next prev parent reply other threads:[~2014-09-24 11:14 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-22 16:41 [PATCH 1/2] Btrfs: add missing end_page_writeback on submit_extent_page failure Filipe Manana
2014-09-22 16:41 ` [PATCH 2/2] Btrfs: be aware of btree inode write errors to avoid fs corruption Filipe Manana
2014-09-23 14:05 ` Liu Bo
2014-09-23 14:27 ` Filipe David Manana
2014-09-24 0:20 ` [PATCH 2/2 v2] " Filipe Manana
2014-09-24 0:43 ` [PATCH 2/2 v3] " Filipe Manana
2014-09-24 4:49 ` [PATCH 2/2 v4] " Filipe Manana
2014-09-24 10:28 ` [PATCH 2/2 v5] " Filipe Manana
2014-09-24 11:16 ` Miao Xie [this message]
2014-09-24 12:59 ` Filipe David Manana
2014-09-24 17:19 ` [PATCH 2/2 v6] " Filipe Manana
2014-09-24 22:20 ` [PATCH 2/2 v7] " Filipe Manana
2014-09-25 11:12 ` [PATCH 2/2 v8] " Filipe Manana
2014-09-25 16:33 ` [PATCH 2/2 v9] " Filipe Manana
2014-09-25 16:51 ` [PATCH 2/2 v10] " Filipe Manana
2014-09-25 16:30 ` David Sterba
2014-09-25 18:01 ` [PATCH 2/2 v11] " Filipe Manana
2014-09-26 11:25 ` [PATCH 2/2 v12] " Filipe Manana
2014-09-23 10:14 ` [PATCH 1/2] Btrfs: add missing end_page_writeback on submit_extent_page failure Liu Bo
2014-09-23 13:03 ` Filipe David Manana
2014-09-23 13:39 ` Liu Bo
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=5422A800.9030308@cn.fujitsu.com \
--to=miaox@cn.fujitsu.com \
--cc=fdmanana@suse.com \
--cc=linux-btrfs@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).