From patchwork Thu Dec 18 03:38:00 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qu Wenruo X-Patchwork-Id: 5510311 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 6E1329F30B for ; Thu, 18 Dec 2014 03:40:21 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7AF79209E3 for ; Thu, 18 Dec 2014 03:40:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 85EE8209A7 for ; Thu, 18 Dec 2014 03:40:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751933AbaLRDkN (ORCPT ); Wed, 17 Dec 2014 22:40:13 -0500 Received: from cn.fujitsu.com ([59.151.112.132]:11625 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1751754AbaLRDkJ (ORCPT ); Wed, 17 Dec 2014 22:40:09 -0500 X-IronPort-AV: E=Sophos;i="5.04,848,1406563200"; d="scan'208";a="45394849" Received: from unknown (HELO edo.cn.fujitsu.com) ([10.167.33.5]) by heian.cn.fujitsu.com with ESMTP; 18 Dec 2014 11:36:46 +0800 Received: from G08CNEXCHPEKD02.g08.fujitsu.local (localhost.localdomain [127.0.0.1]) by edo.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id sBI3dePC002171 for ; Thu, 18 Dec 2014 11:39:40 +0800 Received: from localhost.localdomain (10.167.226.33) by G08CNEXCHPEKD02.g08.fujitsu.local (10.167.33.89) with Microsoft SMTP Server (TLS) id 14.3.181.6; Thu, 18 Dec 2014 11:40:05 +0800 From: Qu Wenruo To: Subject: [PATCH 5/5] btrfs-progs: Add repair function for discount file extent hole. Date: Thu, 18 Dec 2014 11:38:00 +0800 Message-ID: <1418873880-7916-6-git-send-email-quwenruo@cn.fujitsu.com> X-Mailer: git-send-email 2.1.3 In-Reply-To: <1418873880-7916-1-git-send-email-quwenruo@cn.fujitsu.com> References: <1418873880-7916-1-git-send-email-quwenruo@cn.fujitsu.com> MIME-Version: 1.0 X-Originating-IP: [10.167.226.33] Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Since orphan extents are handled in previous patches, now just punch holes to fill the file extents hole. Also since now btrfsck is aware of whether the inode has orphan file extent, allow repair_inode_no_item() to determine filetype according to orphan file extent. Signed-off-by: Qu Wenruo --- cmds-check.c | 51 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/cmds-check.c b/cmds-check.c index 1e9bc56..6c43b62 100644 --- a/cmds-check.c +++ b/cmds-check.c @@ -2460,12 +2460,6 @@ static int repair_inode_no_item(struct btrfs_trans_handle *trans, int type_recovered = 0; int ret = 0; - /* - * TODO: - * 1. salvage data from existing file extent and - * punch hole to keep fi ext consistent. - * 2. salvage data from extent tree - */ printf("Trying to rebuild inode:%llu\n", rec->ino); type_recovered = !find_file_type(rec, &filetype); @@ -2479,9 +2473,7 @@ static int repair_inode_no_item(struct btrfs_trans_handle *trans, * For undetermined one, use FILE as fallback. * * TODO: - * 1. If found extent belong to it in extent tree, it must be FILE - * Need extra hook in extent tree scan. - * 2. If found backref(inode_index/item is already handled) to it, + * 1. If found backref(inode_index/item is already handled) to it, * it must be DIR. * Need new inode-inode ref structure to allow search for that. */ @@ -2493,7 +2485,10 @@ static int repair_inode_no_item(struct btrfs_trans_handle *trans, } else if (rec->found_dir_item) { type_recovered = 1; filetype = BTRFS_FT_DIR; - } else { + } else if (!list_empty(&rec->orphan_extents)) { + type_recovered = 1; + filetype = BTRFS_FT_REG_FILE; + } else{ printf("Can't determint the filetype for inode %llu, assume it is a normal file\n", rec->ino); type_recovered = 1; @@ -2584,6 +2579,37 @@ out: return ret; } +static int repair_inode_discount_extent(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, + struct inode_record *rec) +{ + struct rb_node *node; + struct file_extent_hole *hole; + int ret = 0; + + node = rb_first(&rec->holes); + + while (node) { + hole = rb_entry(node, struct file_extent_hole, node); + ret = btrfs_punch_hole(trans, root, rec->ino, + hole->start, hole->len); + if (ret < 0) + goto out; + ret = del_file_extent_hole(&rec->holes, hole->start, + hole->len); + if (ret < 0) + goto out; + if (RB_EMPTY_ROOT(&rec->holes)) + rec->errors &= ~I_ERR_FILE_EXTENT_DISCOUNT; + node = rb_first(&rec->holes); + } + printf("Fixed discount file extents for inode: %llu in root: %llu\n", + rec->ino, root->objectid); +out: + return ret; +} + static int try_repair_inode(struct btrfs_root *root, struct inode_record *rec) { struct btrfs_trans_handle *trans; @@ -2594,7 +2620,8 @@ static int try_repair_inode(struct btrfs_root *root, struct inode_record *rec) I_ERR_NO_ORPHAN_ITEM | I_ERR_LINK_COUNT_WRONG | I_ERR_NO_INODE_ITEM | - I_ERR_FILE_EXTENT_ORPHAN))) + I_ERR_FILE_EXTENT_ORPHAN | + I_ERR_FILE_EXTENT_DISCOUNT))) return rec->errors; path = btrfs_alloc_path(); @@ -2618,6 +2645,8 @@ static int try_repair_inode(struct btrfs_root *root, struct inode_record *rec) ret = repair_inode_no_item(trans, root, path, rec); if (!ret && rec->errors & I_ERR_FILE_EXTENT_ORPHAN) ret = repair_inode_orphan_extent(trans, root, path, rec); + if (!ret && rec->errors & I_ERR_FILE_EXTENT_DISCOUNT) + ret = repair_inode_discount_extent(trans, root, path, rec); if (!ret && rec->errors & I_ERR_DIR_ISIZE_WRONG) ret = repair_inode_isize(trans, root, path, rec); if (!ret && rec->errors & I_ERR_NO_ORPHAN_ITEM)