From patchwork Tue Sep 3 08:24:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 11127399 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9F86014DE for ; Tue, 3 Sep 2019 08:24:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 89A712053B for ; Tue, 3 Sep 2019 08:24:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728147AbfICIYR (ORCPT ); Tue, 3 Sep 2019 04:24:17 -0400 Received: from mx2.suse.de ([195.135.220.15]:53174 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727077AbfICIYR (ORCPT ); Tue, 3 Sep 2019 04:24:17 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id B5B0CAF61 for ; Tue, 3 Sep 2019 08:24:15 +0000 (UTC) From: Qu Wenruo To: linux-btrfs@vger.kernel.org Subject: [PATCH 3/4] btrfs-progs: check/original: Fix inode mode in subvolume trees Date: Tue, 3 Sep 2019 16:24:06 +0800 Message-Id: <20190903082407.13927-4-wqu@suse.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190903082407.13927-1-wqu@suse.com> References: <20190903082407.13927-1-wqu@suse.com> MIME-Version: 1.0 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org To make original mode to repair imode error in subvolume trees, this patch will do: - Remove the show-stopper checks for root->objectid. Now repair_imode_original() will accept inodes in subvolume trees. - Export detect_imode() for original mode Due to the call requirement, original mode must use an existing trans handler to do the repair, thus we need to re-implement most of the work done in repair_imode_common(). - Make repair_imode_original() to use detect_imode. Signed-off-by: Qu Wenruo --- check/main.c | 32 +++++++++++++++++++++++--------- check/mode-common.c | 4 ++-- check/mode-common.h | 2 ++ 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/check/main.c b/check/main.c index 2e16b4e6f05b..8987d13c72e0 100644 --- a/check/main.c +++ b/check/main.c @@ -2771,18 +2771,31 @@ static int repair_imode_original(struct btrfs_trans_handle *trans, struct btrfs_path *path, struct inode_record *rec) { + struct btrfs_key key; int ret; u32 imode; - if (root->root_key.objectid != BTRFS_ROOT_TREE_OBJECTID) - return -ENOTTY; - if (rec->ino != BTRFS_ROOT_TREE_DIR_OBJECTID || !is_fstree(rec->ino)) - return -ENOTTY; + key.objectid = rec->ino; + key.type = BTRFS_INODE_ITEM_KEY; + key.offset = 0; - if (rec->ino == BTRFS_ROOT_TREE_DIR_OBJECTID) - imode = 040755; - else - imode = 0100600; + ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); + if (ret > 0) + ret = -ENOENT; + if (ret < 0) + return ret; + + if (root->objectid == BTRFS_ROOT_TREE_OBJECTID) { + /* In root tree we only have two possible imode */ + if (rec->ino == BTRFS_ROOT_TREE_OBJECTID) + imode = S_IFDIR | 0755; + else + imode = S_IFREG | 0600; + } else { + detect_imode(root, path, &imode); + /* Ignore error returned, just use the default value returned */ + } + btrfs_release_path(path); ret = reset_imode(trans, root, path, rec->ino, imode); if (ret < 0) return ret; @@ -2810,7 +2823,8 @@ static int try_repair_inode(struct btrfs_root *root, struct inode_record *rec) I_ERR_FILE_NBYTES_WRONG | I_ERR_INLINE_RAM_BYTES_WRONG | I_ERR_MISMATCH_DIR_HASH | - I_ERR_UNALIGNED_EXTENT_REC))) + I_ERR_UNALIGNED_EXTENT_REC | + I_ERR_INVALID_IMODE))) return rec->errors; /* diff --git a/check/mode-common.c b/check/mode-common.c index 807d7daf98a6..ab451749e20c 100644 --- a/check/mode-common.c +++ b/check/mode-common.c @@ -836,8 +836,8 @@ int reset_imode(struct btrfs_trans_handle *trans, struct btrfs_root *root, return ret; } -static int detect_imode(struct btrfs_root *root, struct btrfs_path *path, - u32 *imode_ret) +int detect_imode(struct btrfs_root *root, struct btrfs_path *path, + u32 *imode_ret) { struct btrfs_key key; struct btrfs_inode_item *iitem; diff --git a/check/mode-common.h b/check/mode-common.h index 161b84a8deb0..67db89f20edb 100644 --- a/check/mode-common.h +++ b/check/mode-common.h @@ -126,6 +126,8 @@ int delete_corrupted_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_key *di_key, char *namebuf, u32 namelen); +int detect_imode(struct btrfs_root *root, struct btrfs_path *path, + u32 *imode_ret); int reset_imode(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_path *path, u64 ino, u32 mode); int repair_imode_common(struct btrfs_root *root, struct btrfs_path *path);