From patchwork Fri Oct 31 18:01:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josef Bacik X-Patchwork-Id: 5206271 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 8EBB19F349 for ; Fri, 31 Oct 2014 18:03:46 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 968B72013D for ; Fri, 31 Oct 2014 18:03:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 93D942013A for ; Fri, 31 Oct 2014 18:03:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752234AbaJaSDk (ORCPT ); Fri, 31 Oct 2014 14:03:40 -0400 Received: from mx0a-00082601.pphosted.com ([67.231.145.42]:14526 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756003AbaJaSCj (ORCPT ); Fri, 31 Oct 2014 14:02:39 -0400 Received: from pps.filterd (m0004347 [127.0.0.1]) by m0004347.ppops.net (8.14.5/8.14.5) with SMTP id s9VHqKbZ017177; Fri, 31 Oct 2014 11:02:38 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=fb.com; h=from : to : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=facebook; bh=TW1ZRkyu2MPuy9jSWda/83wMnch33DjGJHwMIqwtT5g=; b=ZVCHoO1YwK45jrcwb1WxIIIqvxdlNJ/MiJOHaR5OU/n3m5nj14bOKbuv4skb5bZFgwvp B5RBfdRNZaNBTvYzzZ12/e+qXkslmlig4/rKNfdtmY1dHR02r/wqUSOLlR38z88Yu7wg 26OfSxyYxvxcM5mH60SCR0cKo9dpqm+YK38= Received: from mail.thefacebook.com ([199.201.64.23]) by m0004347.ppops.net with ESMTP id 1qcb9a0ng2-10 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=OK); Fri, 31 Oct 2014 11:02:37 -0700 Received: from localhost (192.168.57.29) by mail.thefacebook.com (192.168.16.11) with Microsoft SMTP Server (TLS) id 14.3.195.1; Fri, 31 Oct 2014 11:01:51 -0700 From: Josef Bacik To: , Subject: [PATCH 09/11] Btrfs-progs: fix missing inode items Date: Fri, 31 Oct 2014 14:01:27 -0400 Message-ID: <1414778489-4049-10-git-send-email-jbacik@fb.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1414778489-4049-1-git-send-email-jbacik@fb.com> References: <1414778489-4049-1-git-send-email-jbacik@fb.com> MIME-Version: 1.0 X-Originating-IP: [192.168.57.29] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.12.52, 1.0.28, 0.0.0000 definitions=2014-10-31_08:2014-10-31, 2014-10-31, 1970-01-01 signatures=0 X-Proofpoint-Spam-Details: rule=fb_default_notspam policy=fb_default score=0 kscore.is_bulkscore=0 kscore.compositescore=0 circleOfTrustscore=2.87009407511322 compositescore=0.980601274849849 urlsuspect_oldscore=0.980601274849849 suspectscore=0 recipient_domain_to_sender_totalscore=0 phishscore=0 bulkscore=0 kscore.is_spamscore=0 recipient_to_sender_totalscore=0 recipient_domain_to_sender_domain_totalscore=64355 rbsscore=0.980601274849849 spamscore=0 recipient_to_sender_domain_totalscore=0 urlsuspectscore=0.9 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=7.0.1-1402240000 definitions=main-1410310168 X-FB-Internal: deliver Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,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 If we have all the other items but no inode item we can recreate it for the most part, with the exception of the permissions and ownership. Add this ability to btrfsck. Thanks, Signed-off-by: Josef Bacik --- cmds-check.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/cmds-check.c b/cmds-check.c index be75dcb..a30db8d 100644 --- a/cmds-check.c +++ b/cmds-check.c @@ -1727,6 +1727,61 @@ static int delete_dir_index(struct btrfs_root *root, return ret; } +static int create_inode_item(struct btrfs_root *root, + struct inode_record *rec, + struct inode_backref *backref, int root_dir) +{ + struct btrfs_trans_handle *trans; + struct btrfs_inode_item inode_item; + time_t now = time(NULL); + int ret; + + trans = btrfs_start_transaction(root, 1); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + return ret; + } + + fprintf(stderr, "root %llu inode %llu recreating inode item, this may " + "be incomplete, please check permissions and content after " + "the fsck completes.\n", (unsigned long long)root->objectid, + (unsigned long long)rec->ino); + + memset(&inode_item, 0, sizeof(inode_item)); + btrfs_set_stack_inode_generation(&inode_item, trans->transid); + if (root_dir) + btrfs_set_stack_inode_nlink(&inode_item, 1); + else + btrfs_set_stack_inode_nlink(&inode_item, rec->found_link); + btrfs_set_stack_inode_nbytes(&inode_item, rec->found_size); + if (rec->found_dir_item) { + if (rec->found_file_extent) + fprintf(stderr, "root %llu inode %llu has both a dir " + "item and extents, unsure if it is a dir or a " + "regular file so setting it as a directory\n", + (unsigned long long)root->objectid, + (unsigned long long)rec->ino); + btrfs_set_stack_inode_mode(&inode_item, S_IFDIR | 0755); + btrfs_set_stack_inode_size(&inode_item, rec->found_size); + } else if (!rec->found_dir_item) { + btrfs_set_stack_inode_size(&inode_item, rec->extent_end); + btrfs_set_stack_inode_mode(&inode_item, S_IFREG | 0755); + } + btrfs_set_stack_timespec_sec(&inode_item.atime, now); + btrfs_set_stack_timespec_nsec(&inode_item.atime, 0); + btrfs_set_stack_timespec_sec(&inode_item.ctime, now); + btrfs_set_stack_timespec_nsec(&inode_item.ctime, 0); + btrfs_set_stack_timespec_sec(&inode_item.mtime, now); + btrfs_set_stack_timespec_nsec(&inode_item.mtime, 0); + btrfs_set_stack_timespec_sec(&inode_item.otime, 0); + btrfs_set_stack_timespec_nsec(&inode_item.otime, 0); + + ret = btrfs_insert_inode(trans, root, rec->ino, &inode_item); + BUG_ON(ret); + btrfs_commit_transaction(trans, root); + return 0; +} + static int repair_inode_backrefs(struct btrfs_root *root, struct inode_record *rec, struct cache_tree *inode_cache, @@ -1738,6 +1793,15 @@ static int repair_inode_backrefs(struct btrfs_root *root, int repaired = 0; list_for_each_entry_safe(backref, tmp, &rec->backrefs, list) { + if (!delete && rec->ino == root_dirid) { + if (!rec->found_inode_item) { + ret = create_inode_item(root, rec, backref, 1); + if (ret) + break; + repaired++; + } + } + /* Index 0 for root dir's are special, don't mess with it */ if (rec->ino == root_dirid && backref->index == 0) continue; @@ -1799,6 +1863,18 @@ static int repair_inode_backrefs(struct btrfs_root *root, btrfs_commit_transaction(trans, root); repaired++; } + + if (!delete && (backref->found_inode_ref && + backref->found_dir_index && + backref->found_dir_item && + !(backref->errors & REF_ERR_INDEX_UNMATCH) && + !rec->found_inode_item)) { + ret = create_inode_item(root, rec, backref, 0); + if (ret) + break; + repaired++; + } + } return ret ? ret : repaired; }