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 14/15] btrfs-progs: check: handle mismatched filetype in repair_inode_backref
Date: Fri, 26 Jan 2018 16:35:18 +0800	[thread overview]
Message-ID: <20180126083519.28373-15-suy.fnst@cn.fujitsu.com> (raw)
In-Reply-To: <20180126083519.28373-1-suy.fnst@cn.fujitsu.com>

Original can't handle mismatched well.
Since it only records inode mode and one filetype of dir_item or
dir_index. If backref has mismatched filetype, the one filetype
is untrusted. The only trusted thing is inode mode.

So, if we found mismatched filetype in a backref, just delete
dir_index and dir_item. Then next round of repair will add new
dir_index and dir_item whose filetype bases on the inode mode.

Transform delete_dir_index() to __delete_dir_item() for code reuse.

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

diff --git a/cmds-check.c b/cmds-check.c
index 6091c7ef3442..156b4063bf40 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -3059,27 +3059,41 @@ static int add_missing_dir_index(struct btrfs_root *root,
 	return 0;
 }
 
-static int delete_dir_index(struct btrfs_root *root,
-			    struct inode_backref *backref)
+static int __delete_dir_item(struct btrfs_root *root,
+			     struct inode_backref *backref, bool is_index)
 {
 	struct btrfs_trans_handle *trans;
 	struct btrfs_dir_item *di;
 	struct btrfs_path path;
 	int ret = 0;
+	u64 offset;
+	u8 type;
+
+	if (is_index) {
+		type = BTRFS_DIR_INDEX_KEY;
+		offset = backref->index;
+	} else {
+		type = BTRFS_DIR_ITEM_KEY;
+		offset = btrfs_name_hash(backref->name, backref->namelen);
+	}
 
 	trans = btrfs_start_transaction(root, 1);
 	if (IS_ERR(trans))
 		return PTR_ERR(trans);
 
-	fprintf(stderr, "Deleting bad dir index [%llu,%u,%llu] root %llu\n",
-		(unsigned long long)backref->dir,
-		BTRFS_DIR_INDEX_KEY, (unsigned long long)backref->index,
-		(unsigned long long)root->objectid);
+	fprintf(stderr, "Deleting bad dir %s [%llu,%u,%llu] root %llu\n",
+		is_index ? "index" : "item", (unsigned long long)backref->dir,
+		type, offset, (unsigned long long)root->objectid);
 
 	btrfs_init_path(&path);
-	di = btrfs_lookup_dir_index(trans, root, &path, backref->dir,
-				    backref->name, backref->namelen,
-				    backref->index, -1);
+	if (is_index)
+		di = btrfs_lookup_dir_index(trans, root, &path, backref->dir,
+					    backref->name, backref->namelen,
+					    backref->index, -1);
+	else
+		di = btrfs_lookup_dir_item(trans, root, &path, backref->dir,
+					   backref->name, backref->namelen,
+					   -1);
 	if (IS_ERR(di)) {
 		ret = PTR_ERR(di);
 		btrfs_release_path(&path);
@@ -3099,6 +3113,18 @@ static int delete_dir_index(struct btrfs_root *root,
 	return ret;
 }
 
+static int delete_dir_index(struct btrfs_root *root,
+			    struct inode_backref *backref)
+{
+	return __delete_dir_item(root, backref, true);
+}
+
+static int delete_dir_item(struct btrfs_root *root,
+			   struct inode_backref *backref)
+{
+	return __delete_dir_item(root, backref, false);
+}
+
 static int __create_inode_item(struct btrfs_trans_handle *trans,
 			       struct btrfs_root *root, u64 ino, u64 size,
 			       u64 nbytes, u64 nlink, u32 mode)
@@ -3228,6 +3254,22 @@ static int repair_inode_backrefs(struct btrfs_root *root,
 			continue;
 		}
 
+		if (delete &&
+		    (backref->errors & REF_ERR_FILETYPE_UNMATCH)) {
+			if (backref->found_dir_index)
+				ret = delete_dir_index(root, backref);
+			if (ret)
+				break;
+			if (backref->found_dir_item)
+				ret = delete_dir_item(root, backref);
+			if (ret)
+				break;
+			backref->found_dir_index = 0;
+			backref->found_dir_item = 0;
+			repaired++;
+			continue;
+		}
+
 		if (!delete && !backref->found_dir_index &&
 		    backref->found_dir_item && backref->found_inode_ref) {
 			ret = add_missing_dir_index(root, inode_cache, rec,
@@ -3285,6 +3327,12 @@ static int repair_inode_backrefs(struct btrfs_root *root,
 			btrfs_commit_transaction(trans, root);
 			backref->found_dir_index = 1;
 			backref->found_dir_item = 1;
+			/*
+			 * We can't judge backre->filetype is right or not.
+			 * Just rely on the inode mode.
+			 */
+			if (rec->found_inode_item)
+				backref->errors &= ~REF_ERR_FILETYPE_UNMATCH;
 			repaired++;
 		}
 
-- 
2.16.1




  parent reply	other threads:[~2018-01-26  8:31 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-26  8:35 [PATCH 00/15] btrfs-progs: fix filetype mismatch in check Su Yue
2018-01-26  8:35 ` [PATCH 01/15] btrfs-progs: lowmem check: introduce repair_inode_item_mismatch() Su Yue
2018-01-26  8:35 ` [PATCH 02/15] btrfs-progs: lowmem check: find and guess inode filetype Su Yue
2018-01-26  8:49   ` Qu Wenruo
2018-01-26  9:14   ` Qu Wenruo
2018-01-26  9:21     ` Qu Wenruo
2018-01-26  9:31     ` Su Yue
2018-01-26  9:35       ` Qu Wenruo
2018-01-26  8:35 ` [PATCH 03/15] btrfs-progs: lowmem check: find filetype in repair_inode_missing() Su Yue
2018-01-26  9:22   ` Qu Wenruo
2018-01-26  8:35 ` [PATCH 04/15] btrfs-progs: lowmem check: repair complex cases in repair_dir_item() Su Yue
2018-01-26  9:33   ` Qu Wenruo
2018-01-26  8:35 ` [PATCH 05/15] btrfs-progs: lowmem check: let check_dir_item() continue if find wrong inode_item Su Yue
2018-01-26  9:36   ` Qu Wenruo
2018-01-26  8:35 ` [PATCH 06/15] btrfs-progs: lowmem check: let check_dir_item() return if repaired Su Yue
2018-01-26  9:43   ` Qu Wenruo
2018-01-26  8:35 ` [PATCH 07/15] btrfs-progs: lowmem check: find_dir_item by di_key in check_dir_item() Su Yue
2018-01-26  9:37   ` Qu Wenruo
2018-01-26  8:35 ` [PATCH 08/15] btrfs-progs: lowmem check: call get_dir_isize() after repair Su Yue
2018-01-26  8:35 ` [PATCH 09/15] btrfs-progs: lowmem check: change logic of leaf process if repair Su Yue
2018-01-26 10:01   ` Qu Wenruo
2018-01-26 10:15     ` Su Yue
2018-01-26  8:35 ` [PATCH 10/15] btrfs-progs: check: clear I_ERR_FILE_EXTENT_DISCOUNT after repair Su Yue
2018-01-26 10:02   ` Qu Wenruo
2018-01-26  8:35 ` [PATCH 11/15] btrfs-progs: check: modify indoe_rec and backref " Su Yue
2018-01-26  8:35 ` [PATCH 12/15] btrfs-progs: check: increase counter error in check_inode_recs() Su Yue
2018-01-26 10:05   ` Qu Wenruo
2018-01-26  8:35 ` [PATCH 13/15] btrfs-progs: check: find inode filetype in create_inode_item() Su Yue
2018-01-26 10:11   ` Qu Wenruo
2018-01-26  8:35 ` Su Yue [this message]
2018-01-26  8:35 ` [PATCH 15/15] btrfs-progs: fsck-tests: add image for original and lowmem check Su Yue
2018-01-26 10:17   ` Qu Wenruo

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=20180126083519.28373-15-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.