From patchwork Sat Mar 10 18:18:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andiry Xu X-Patchwork-Id: 10273929 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E3136602BD for ; Sat, 10 Mar 2018 18:21:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D11BB28BAE for ; Sat, 10 Mar 2018 18:21:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C5DC929735; Sat, 10 Mar 2018 18:21:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_NONE,T_DKIM_INVALID autolearn=no version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 70E5828BAE for ; Sat, 10 Mar 2018 18:21:28 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 68B212253FB4E; Sat, 10 Mar 2018 10:15:04 -0800 (PST) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=2607:f8b0:400e:c01::242; helo=mail-pl0-x242.google.com; envelope-from=jix024@eng.ucsd.edu; receiver=linux-nvdimm@lists.01.org Received: from mail-pl0-x242.google.com (mail-pl0-x242.google.com [IPv6:2607:f8b0:400e:c01::242]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 8A4342263148F for ; Sat, 10 Mar 2018 10:15:00 -0800 (PST) Received: by mail-pl0-x242.google.com with SMTP id f23-v6so7024249plr.10 for ; Sat, 10 Mar 2018 10:21:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=eng.ucsd.edu; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=HPkkQF+9vFD3ciwJo7lahJwBTWY627yqzXqF41ZRP9Q=; b=hxkD9IigSuZ+MxKVBqroz91IlXHv/B5omRSZHvcXklJSpjdZ2ASLJaobcdoLeKR90a bJLJWqX6yxo5ih60S9fJ7ciUoUIpJd+msFCONEbO8kVBl3Jh965cWoTWYzg9/s3eOWlV At9F48kY+Tq46tFSHPe19T02lxpgVeaGx8KAI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=HPkkQF+9vFD3ciwJo7lahJwBTWY627yqzXqF41ZRP9Q=; b=GxYkau8okMF+LQbBc+EmFDRq42nyK2XQX251/zblI6zLg4R7+8GgEwpsn/UE6biLnr Pryzey5oZ2SoIJiQjqB45cx4cyxl8tU8/fCYc5Um4olshslKGUhyW0JAwd5yM/3UnEWE BNwY84PEOhj45Sc0Np0t6lvpIe2Eqk4y15SMWGw/VEw74uegvLl9leWQmY7asxzIWXmR WpEUHmxJ/YspEK35NMWDHaalmAfS6BLZpqpDF8tAqDXoB+y4sOIXqgtUQWCKvGa02MTY 6z/venXOKSsxb/tqVpmuuSpDzXqiassJnFLPIVXTrm16IQUKcNmT1aVb5O9046ZnqRMe +JzQ== X-Gm-Message-State: AElRT7G4NHFIOC2f3gbfPLn8XgHgkZwSXcOhtXR7N8dr2E8ex2OF7Toi AJdF4KiGCb0uAPNFzA1jHJuZRQ== X-Google-Smtp-Source: AG47ELtI3phqD3D59xfPW1ErXrAqBnA83Gs4QJEifM2RWuqm74YiFNR6aHvJliVyXsFRhCIzWYWuLA== X-Received: by 2002:a17:902:a981:: with SMTP id bh1-v6mr2684119plb.5.1520706078913; Sat, 10 Mar 2018 10:21:18 -0800 (PST) Received: from brienza-desktop.8.8.4.4 (andxu.ucsd.edu. [132.239.17.134]) by smtp.gmail.com with ESMTPSA id h80sm9210167pfj.181.2018.03.10.10.21.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 10 Mar 2018 10:21:18 -0800 (PST) From: Andiry Xu To: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nvdimm@lists.01.org Subject: [RFC v2 52/83] Rebuild: file inode. Date: Sat, 10 Mar 2018 10:18:33 -0800 Message-Id: <1520705944-6723-53-git-send-email-jix024@eng.ucsd.edu> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1520705944-6723-1-git-send-email-jix024@eng.ucsd.edu> References: <1520705944-6723-1-git-send-email-jix024@eng.ucsd.edu> X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: coughlan@redhat.com, miklos@szeredi.hu, Andiry Xu , david@fromorbit.com, jack@suse.com, swanson@cs.ucsd.edu, swhiteho@redhat.com, andiry.xu@gmail.com MIME-Version: 1.0 Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP From: Andiry Xu Rebuild file inode metadata and radix tree on read_inode. Signed-off-by: Andiry Xu --- fs/nova/log.h | 4 ++ fs/nova/rebuild.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/fs/nova/log.h b/fs/nova/log.h index 87ce5f9..bdb85eb 100644 --- a/fs/nova/log.h +++ b/fs/nova/log.h @@ -385,6 +385,10 @@ int nova_inplace_update_write_entry(struct super_block *sb, int nova_append_file_write_entry(struct super_block *sb, struct nova_inode *pi, struct inode *inode, struct nova_file_write_item *item, struct nova_inode_update *update); +int nova_assign_write_entry(struct super_block *sb, + struct nova_inode_info_header *sih, + struct nova_file_write_entry *entry, + bool free); int nova_invalidate_dentries(struct super_block *sb, struct nova_inode_update *update); int nova_inplace_update_dentry(struct super_block *sb, diff --git a/fs/nova/rebuild.c b/fs/nova/rebuild.c index 9a1327d..07cf6e3 100644 --- a/fs/nova/rebuild.c +++ b/fs/nova/rebuild.c @@ -156,6 +156,126 @@ static int nova_rebuild_inode_finish(struct super_block *sb, return 0; } +static void nova_rebuild_handle_write_entry(struct super_block *sb, + struct nova_inode_info_header *sih, struct nova_inode_rebuild *reb, + struct nova_file_write_entry *entry) +{ + if (entry->num_pages != entry->invalid_pages) { + /* + * The overlaped blocks are already freed. + * Don't double free them, just re-assign the pointers. + */ + nova_assign_write_entry(sb, sih, entry, false); + } + + if (entry->trans_id >= sih->trans_id) { + nova_rebuild_file_time_and_size(sb, reb, + entry->mtime, entry->mtime, + entry->size); + reb->trans_id = entry->trans_id; + } + + /* Update sih->i_size for setattr apply operations */ + sih->i_size = le64_to_cpu(reb->i_size); +} + +static int nova_rebuild_file_inode_tree(struct super_block *sb, + struct nova_inode *pi, u64 pi_addr, + struct nova_inode_info_header *sih) +{ + struct nova_file_write_entry *entry = NULL; + struct nova_setattr_logentry *attr_entry = NULL; + struct nova_link_change_entry *link_change_entry = NULL; + struct nova_inode_rebuild rebuild, *reb; + unsigned int data_bits = blk_type_to_shift[sih->i_blk_type]; + u64 ino = pi->nova_ino; + timing_t rebuild_time; + void *addr, *entryc = NULL; + u64 curr_p; + u8 type; + int ret; + + NOVA_START_TIMING(rebuild_file_t, rebuild_time); + nova_dbg_verbose("Rebuild file inode %llu tree\n", ino); + + reb = &rebuild; + ret = nova_rebuild_inode_start(sb, pi, sih, reb, pi_addr); + if (ret) + goto out; + + curr_p = sih->log_head; + if (curr_p == 0 && sih->log_tail == 0) + goto out; + +// nova_print_nova_log(sb, sih); + + while (curr_p != sih->log_tail) { + if (goto_next_page(sb, curr_p)) { + sih->log_pages++; + curr_p = next_log_page(sb, curr_p); + } + + if (curr_p == 0) { + nova_err(sb, "File inode %llu log is NULL!\n", ino); + ret = -EIO; + goto out; + } + + addr = (void *)nova_get_block(sb, curr_p); + + entryc = addr; + + type = nova_get_entry_type(entryc); + + switch (type) { + case SET_ATTR: + attr_entry = (struct nova_setattr_logentry *)entryc; + nova_apply_setattr_entry(sb, reb, sih, attr_entry); + sih->last_setattr = curr_p; + if (attr_entry->trans_id >= reb->trans_id) { + nova_rebuild_file_time_and_size(sb, reb, + attr_entry->mtime, + attr_entry->ctime, + attr_entry->size); + reb->trans_id = attr_entry->trans_id; + } + + /* Update sih->i_size for setattr operation */ + sih->i_size = le64_to_cpu(reb->i_size); + curr_p += sizeof(struct nova_setattr_logentry); + break; + case LINK_CHANGE: + link_change_entry = + (struct nova_link_change_entry *)entryc; + nova_apply_link_change_entry(sb, reb, + link_change_entry); + sih->last_link_change = curr_p; + curr_p += sizeof(struct nova_link_change_entry); + break; + case FILE_WRITE: + entry = (struct nova_file_write_entry *)addr; + nova_rebuild_handle_write_entry(sb, sih, reb, + entryc); + curr_p += sizeof(struct nova_file_write_entry); + break; + default: + nova_err(sb, "unknown type %d, 0x%llx\n", type, curr_p); + NOVA_ASSERT(0); + curr_p += sizeof(struct nova_file_write_entry); + break; + } + + } + + ret = nova_rebuild_inode_finish(sb, pi, sih, reb, curr_p); + sih->i_blocks = sih->log_pages + (sih->i_size >> data_bits); + +out: +// nova_print_inode_log_page(sb, inode); + NOVA_END_TIMING(rebuild_file_t, rebuild_time); + return ret; +} + /******************* Directory rebuild *********************/ static inline void nova_rebuild_dir_time_and_size(struct super_block *sb, @@ -360,12 +480,16 @@ int nova_rebuild_inode(struct super_block *sb, struct nova_inode_info *si, /* Treat symlink files as normal files */ /* Fall through */ case S_IFREG: + nova_rebuild_file_inode_tree(sb, pi, pi_addr, sih); break; case S_IFDIR: if (rebuild_dir) nova_rebuild_dir_inode_tree(sb, pi, pi_addr, sih); break; default: + /* In case of special inode, walk the log */ + if (pi->log_head) + nova_rebuild_file_inode_tree(sb, pi, pi_addr, sih); sih->pi_addr = pi_addr; break; }