All of lore.kernel.org
 help / color / mirror / Atom feed
From: Su Yue <suy.fnst@cn.fujitsu.com>
To: <linux-btrfs@vger.kernel.org>
Cc: <suy.fnst@cn.fujitsu.com>
Subject: [PATCH v3 07/17] btrfs-progs: lowmem check: introduce try_avoid_extents_overwrite()
Date: Thu, 11 Jan 2018 15:35:01 +0800	[thread overview]
Message-ID: <20180111073511.25288-8-suy.fnst@cn.fujitsu.com> (raw)
In-Reply-To: <20180111073511.25288-1-suy.fnst@cn.fujitsu.com>

Define a global enum extents_operation to record extents are excluded
or new chunk is allocated for extents.
Another global u64 last_allocated_chunk records the last chunk start
allocated by lowmem repair.
Although global variable is not so graceful, it simplifies codes much.

New function try_to_force_cow_in_new_chunk() will try to mark block
groups full, allocate a new chunk and records the start.
If the last allocated chunk is almost full, a new chunk will be
allocated.

try_avoid_extents_overwrite() prefer to allocates new chunk first.
If it failed because of no space or wrong used bytes(fsck-tests/004),
then it try to exclude metadata blocks but costs lots of time in
large filesystem.

Signed-off-by: Su Yue <suy.fnst@cn.fujitsu.com>
---
 cmds-check.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)

diff --git a/cmds-check.c b/cmds-check.c
index 795e452a4e63..8ebd1a38a1b9 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -84,6 +84,15 @@ enum btrfs_check_mode {
 
 static enum btrfs_check_mode check_mode = CHECK_MODE_DEFAULT;
 
+enum lowmem_extents_operation {
+	EXTENTS_NONE,
+	EXTENTS_EXCLUDE,
+	EXTENTS_MARK_BG_FULL,
+};
+
+static enum lowmem_extents_operation extents_operation = EXTENTS_NONE;
+static u64 last_allocated_chunk;
+
 struct extent_backref {
 	struct rb_node node;
 	unsigned int is_data:1;
@@ -11074,6 +11083,23 @@ out:
 	return ret;
 }
 
+/*
+ * Returns <0 for error.
+ * Returns 0 for success.
+ */
+static int try_to_force_cow_in_new_chunk(struct btrfs_fs_info *fs_info)
+{
+	int ret;
+
+	if (last_allocated_chunk) {
+		ret = is_chunk_almost_full(fs_info, last_allocated_chunk);
+		if (ret <= 0)
+			return ret;
+	}
+	ret = force_cow_in_new_chunk(fs_info, &last_allocated_chunk);
+	return ret;
+}
+
 static int check_extent_refs(struct btrfs_root *root,
 			     struct cache_tree *extent_cache)
 {
@@ -13600,6 +13626,92 @@ out:
 	return err;
 }
 
+static void cleanup_excluded_extents(struct btrfs_fs_info *fs_info);
+static int end_avoid_extents_overwrite(struct btrfs_fs_info *fs_info)
+{
+	int ret;
+
+	switch (extents_operation) {
+	case EXTENTS_EXCLUDE:
+		cleanup_excluded_extents(fs_info);
+		ret = 0;
+		break;
+	case EXTENTS_MARK_BG_FULL:
+		ret = modify_block_groups_cache(fs_info,
+						BTRFS_BLOCK_GROUP_METADATA, 0);
+		break;
+	case EXTENTS_NONE:
+		ret = 0;
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	if (!ret)
+		extents_operation = EXTENTS_NONE;
+	return ret;
+}
+
+static int pin_metadata_blocks(struct btrfs_fs_info *fs_info);
+static int exclude_metadata_blocks(struct btrfs_fs_info *fs_info);
+/*
+ * NOTE: Do not call this function during transaction.
+ */
+static int avoid_extents_overwrite(struct btrfs_fs_info *fs_info,
+				   enum lowmem_extents_operation op)
+{
+	int ret;
+
+	if (op == extents_operation && EXTENTS_MARK_BG_FULL != op)
+		return 0;
+
+	switch (op) {
+	case EXTENTS_EXCLUDE:
+		ret = exclude_metadata_blocks(fs_info);
+		break;
+	case EXTENTS_MARK_BG_FULL:
+		ret = try_to_force_cow_in_new_chunk(fs_info);
+		break;
+	case EXTENTS_NONE:
+		ret = end_avoid_extents_overwrite(fs_info);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* extents_operation should be assigned anyway for latter clean up. */
+	extents_operation = op;
+
+	if (ret)
+		end_avoid_extents_overwrite(fs_info);
+	return ret;
+}
+
+static int try_avoid_extents_overwrite(struct btrfs_fs_info *fs_info)
+{
+	int ret;
+	int mixed = btrfs_fs_incompat(fs_info, MIXED_GROUPS);
+
+	if (extents_operation != EXTENTS_NONE &&
+	    extents_operation != EXTENTS_MARK_BG_FULL)
+		return 0;
+	ret = avoid_extents_overwrite(fs_info, EXTENTS_MARK_BG_FULL);
+
+	/*
+	 * If there is no space left to allocate, try to exclude all metadata
+	 * blocks. Mix filesystem is unsupported.
+	 */
+	if (ret && ret == -ENOSPC && !mixed) {
+		printf(
+	"Try to exclude all metadata blcoks and extents, it may be slow\n");
+		ret = avoid_extents_overwrite(fs_info, EXTENTS_EXCLUDE);
+	}
+
+	if (ret)
+		error("failed to avoid extents overwrite %s", strerror(-ret));
+	return ret;
+}
+
 /*
  * Low memory usage version check_chunks_and_extents.
  */
-- 
2.15.1




  parent reply	other threads:[~2018-01-11  7:31 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-11  7:34 [PATCH v3 00/17] btrfs-progs: lowmem check: avoid extents overwrite Su Yue
2018-01-11  7:34 ` [PATCH v3 01/17] btrfs-progs: lowmem check: release path in repair_extent_data_item() Su Yue
2018-01-11  7:34 ` [PATCH v3 02/17] btrfs-progs: lowmem check: record returned errors after walk_down_tree_v2() Su Yue
2018-01-11  7:34 ` [PATCH v3 03/17] btrfs-progs: lowmem check: assign @parent early in repair_extent_data_item() Su Yue
2018-01-11  7:34 ` [PATCH v3 04/17] btrfs-progs: lowmem check: exclude extents of metadata blocks Su Yue
2018-01-11  7:34 ` [PATCH v3 05/17] btrfs-progs: lowmem check: introduce mark/clear_block_groups_full() Su Yue
2018-01-11  7:35 ` [PATCH v3 06/17] btrfs-progs: lowmem check: introduce force_cow_in_new_chunk() Su Yue
2018-01-11  7:35 ` Su Yue [this message]
2018-01-11  7:35 ` [PATCH v3 08/17] btrfs-progs: lowmem check: exclude extents if init-extent-tree in lowmem Su Yue
2018-01-11  7:35 ` [PATCH v3 09/17] btrfs-progs: lowmem check: start to remove parameters @trans " Su Yue
2018-01-11  7:35 ` [PATCH v3 10/17] btrfs-progs: lowmem check: remove parameter @trans of delete_extent_item() Su Yue
2018-01-11  7:35 ` [PATCH v3 11/17] btrfs-progs: lowmem check: remove parameter @trans of repair_chunk_item() Su Yue
2018-01-11  7:35 ` [PATCH v3 12/17] btrfs-progs: lowmem check: remove parameter @trans of repair_extent_item() Su Yue
2018-01-11  7:35 ` [PATCH v3 13/17] btrfs-progs: lowmem check: remove parameter @trans of check_leaf_items() Su Yue
2018-01-11  7:35 ` [PATCH v3 14/17] btrfs-progs: lowmem check: remove parameter @trans of repair_tree_back_ref() Su Yue
2018-01-11  7:35 ` [PATCH v3 15/17] btrfs-progs: lowmem check: remove parameter @trans of check_btrfs_root() Su Yue
2018-01-11  7:35 ` [PATCH v3 16/17] btrfs-progs: lowmem check: introduce repair_block_accounting() Su Yue
2018-01-11  7:35 ` [PATCH v3 17/17] btrfs-progs: lowmem check: end of removing parameters @trans in lowmem Su Yue
2018-01-29  6:01 ` [PATCH v3 00/17] btrfs-progs: lowmem check: avoid extents overwrite Su Yue

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=20180111073511.25288-8-suy.fnst@cn.fujitsu.com \
    --to=suy.fnst@cn.fujitsu.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.