All of lore.kernel.org
 help / color / mirror / Atom feed
From: Qu Wenruo <wqu@suse.com>
To: linux-btrfs@vger.kernel.org
Subject: [PATCH 5/7] btrfs: check/lowmem: Check and repair free space cache inode mode
Date: Mon, 25 Mar 2019 16:22:51 +0800	[thread overview]
Message-ID: <20190325082253.19583-6-wqu@suse.com> (raw)
In-Reply-To: <20190325082253.19583-1-wqu@suse.com>

Unlike inodes in fs roots, we don't really check the inode items in root
tree, in fact we just skip everything other than ROOT_ITEM and ROOT_REF.

This makes invalid inode items sneak into root tree.
For example:
        item 9 key (256 INODE_ITEM 0) itemoff 13702 itemsize 160
                generation 30 transid 30 size 65536 nbytes 1507328
                block group 0 mode 0 links 1 uid 0 gid 0 rdev 0
				   ^ Should be 100600
                sequence 23 flags 0x1b(NODATASUM|NODATACOW|NOCOMPRESS|PREALLOC)
                atime 0.0 (1970-01-01 08:00:00)
                ctime 1553491158.189771625 (2019-03-25 13:19:18)
                mtime 0.0 (1970-01-01 08:00:00)
                otime 0.0 (1970-01-01 08:00:00)

There is a report of such problem in the mail list.

This patch will check and repair inode items of free space cache inodes in
lowmem mode.

Since free space cache inodes doesn't have INODE_REF but still has 1
link, we can't use check_inode_item() directly.
Instead we only check the inode mode, as that's the important part.

The check and repair function: check_repair_free_space_inode() is also
exported for original mode.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 check/mode-common.h |  1 +
 check/mode-lowmem.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 check/mode-lowmem.h |  2 ++
 3 files changed, 48 insertions(+)

diff --git a/check/mode-common.h b/check/mode-common.h
index 8895747adf1d..855f83617854 100644
--- a/check/mode-common.h
+++ b/check/mode-common.h
@@ -24,6 +24,7 @@
 #include <sys/stat.h>
 #include "ctree.h"
 
+#define FREE_SPACE_CACHE_INODE_MODE	(0100600)
 /*
  * Use for tree walk to walk through trees whose leaves/nodes can be shared
  * between different trees. (Namely subvolume/fs trees)
diff --git a/check/mode-lowmem.c b/check/mode-lowmem.c
index f37c3b42e6b6..cdb9b66a63a3 100644
--- a/check/mode-lowmem.c
+++ b/check/mode-lowmem.c
@@ -5091,6 +5091,40 @@ out:
 	return err;
 }
 
+/*
+ * For free space inodes, we can't call check_inode_item() as free space
+ * cache inode doesn't have INODE_REF.
+ * We just check its inode mode.
+ */
+int check_repair_free_space_inode(struct btrfs_fs_info *fs_info,
+				  struct btrfs_path *path)
+{
+	struct btrfs_inode_item *iitem;
+	struct btrfs_key key;
+	u32 mode;
+	int ret = 0;
+
+	btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
+	ASSERT(key.type == BTRFS_INODE_ITEM_KEY && is_fstree(key.objectid));
+	iitem = btrfs_item_ptr(path->nodes[0], path->slots[0],
+			       struct btrfs_inode_item);
+	mode = btrfs_inode_mode(path->nodes[0], iitem);
+	if (mode != FREE_SPACE_CACHE_INODE_MODE) {
+		error(
+	"free space cache inode %llu has invalid mode: has 0%o expect 0%o",
+			key.objectid, mode, FREE_SPACE_CACHE_INODE_MODE);
+		ret = -EUCLEAN;
+		if (repair) {
+			ret = repair_imode_lowmem(fs_info->tree_root,
+						  path);
+			if (ret < 0)
+				return ret;
+			return ret;
+		}
+	}
+	return ret;
+}
+
 /*
  * Check all fs/file tree in low_memory mode.
  *
@@ -5130,6 +5164,17 @@ int check_fs_roots_lowmem(struct btrfs_fs_info *fs_info)
 		btrfs_item_key_to_cpu(node, &key, slot);
 		if (key.objectid > BTRFS_LAST_FREE_OBJECTID)
 			goto out;
+		if (key.type == BTRFS_INODE_ITEM_KEY &&
+		    is_fstree(key.objectid)) {
+			ret = check_repair_free_space_inode(fs_info, &path);
+			/* Check if we still have a valid path to continue */
+			if (ret < 0 && path.nodes[0]) {
+				err |= ret;
+				goto next;
+			}
+			if (ret < 0 && !path.nodes[0])
+				goto out;
+		}
 		if (key.type == BTRFS_ROOT_ITEM_KEY &&
 		    fs_root_objectid(key.objectid)) {
 			if (key.objectid == BTRFS_TREE_RELOC_OBJECTID) {
diff --git a/check/mode-lowmem.h b/check/mode-lowmem.h
index e0ab30b770d5..d2983fd12eb4 100644
--- a/check/mode-lowmem.h
+++ b/check/mode-lowmem.h
@@ -67,5 +67,7 @@
 
 int check_fs_roots_lowmem(struct btrfs_fs_info *fs_info);
 int check_chunks_and_extents_lowmem(struct btrfs_fs_info *fs_info);
+int check_repair_free_space_inode(struct btrfs_fs_info *fs_info,
+				  struct btrfs_path *path);
 
 #endif
-- 
2.21.0


  parent reply	other threads:[~2019-03-25  8:23 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-25  8:22 [PATCH 0/7] btrfs: check: Check and repair invalid free space cahce inode mode Qu Wenruo
2019-03-25  8:22 ` [PATCH 1/7] btrfs-progs: check/lowmem: Add inode mode check Qu Wenruo
2019-03-25 15:40   ` Nikolay Borisov
2019-03-25  8:22 ` [PATCH 2/7] btrfs-progs: check/original: " Qu Wenruo
2019-03-25 15:43   ` Nikolay Borisov
2019-03-25 22:59     ` Qu Wenruo
2019-03-25  8:22 ` [PATCH 3/7] btrfs-progs: check/lowmem: Repair invalid inode mode in root tree Qu Wenruo
2019-03-29  9:36   ` Nikolay Borisov
2019-03-29 11:00     ` Qu Wenruo
2019-03-25  8:22 ` [PATCH 4/7] btrfs-progs: check/original: " Qu Wenruo
2019-03-25  8:22 ` Qu Wenruo [this message]
2019-03-25 14:36   ` [PATCH 5/7] btrfs: check/lowmem: Check and repair free space cache inode mode Su Yue
2019-03-25 14:39     ` Qu Wenruo
2019-03-29  9:40   ` Nikolay Borisov
2019-03-29 11:02     ` Qu Wenruo
2019-03-29 11:47       ` Nikolay Borisov
2019-03-25  8:22 ` [PATCH 6/7] btrfs: check/original: Check and repair free space cache inode item Qu Wenruo
2019-03-25  8:22 ` [PATCH 7/7] btrfs: tests/fsck: Add test image for free space cache mode repair Qu Wenruo
2019-03-29 12:05   ` Nikolay Borisov
2019-03-29 12:08     ` Qu Wenruo
2019-04-01  5:52     ` 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=20190325082253.19583-6-wqu@suse.com \
    --to=wqu@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 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.