From patchwork Sat Mar 10 18:18:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andiry Xu X-Patchwork-Id: 10273889 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 4BA50601A0 for ; Sat, 10 Mar 2018 18:21:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3AB2E28BAE for ; Sat, 10 Mar 2018 18:21:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2F82929735; Sat, 10 Mar 2018 18:21:08 +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 C105C28BAE for ; Sat, 10 Mar 2018 18:21:07 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id BCB0E2258AF10; Sat, 10 Mar 2018 10:14:44 -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:c00::241; helo=mail-pf0-x241.google.com; envelope-from=jix024@eng.ucsd.edu; receiver=linux-nvdimm@lists.01.org Received: from mail-pf0-x241.google.com (mail-pf0-x241.google.com [IPv6:2607:f8b0:400e:c00::241]) (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 9C09422603B1C for ; Sat, 10 Mar 2018 10:14:42 -0800 (PST) Received: by mail-pf0-x241.google.com with SMTP id j2so2613993pff.10 for ; Sat, 10 Mar 2018 10:21:01 -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=vIyywayxxkX6FsttsI9rq3pf32VCXBQ2Kb1lyWJjtco=; b=MHMwsnzbS9johkJt7GLi9pjpvZYvDHTNXMSS6VnhM8oBZFozrEhGSsb7MLcPPtoqpI Abn+eqNBUojx9DW36SeqY/IpminboTZ6RG7BAgpm2gIxnpvesztquYRx3X5ki7wC0IDW F/TGKdIPdBIVVpwNnD8L6YcBKSScuMWkZrxqk= 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=vIyywayxxkX6FsttsI9rq3pf32VCXBQ2Kb1lyWJjtco=; b=tP5rlynpWPX5+QbAu3+wPCnNZH35oe6sr4LXJUOayaXbpoONMNIAym6/TWBpoX+ndc cdk6hmz6sZ79TaaQGb/QGVqR0QNGk0cK/3fmPzNQk5bW/YD0MznZ8Dw23G8jpEhBTo0U VDHk65BEBbxPWH+n5LBTpes13hCQs/rk3sgJd3khsjA72LcueXzMw7fZMfsoe6quULGH zJ+QojnDu4ruqlOhPMIbPci066S5Uqcz4a5Dam3IsKZ4INPtFaF6zcs/lV6BCgKhsQey Ow+9iId5DSxBeFQiNpEwvU0HvMaEDtHF71RbzcRWgtRwWRETNG/0XCcQ6BQa2BmExjc0 vU4Q== X-Gm-Message-State: AElRT7GbqV9qs0Pz8RuW387vkXWJJ6OthvHyVAU4pQeKQoOcakO9vo7y r2ovr4ESOluIbzoSUBIky9FoGg== X-Google-Smtp-Source: AG47ELvgcWhw4QD7GyJXHGV/qELJorEQ4dakVQhJ8d+wBr4dVMJ7xHZ2vHOIbMKOsZ0MTttrKBxt4g== X-Received: by 10.101.93.82 with SMTP id e18mr2170416pgt.371.1520706060982; Sat, 10 Mar 2018 10:21:00 -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.20.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 10 Mar 2018 10:21:00 -0800 (PST) From: Andiry Xu To: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nvdimm@lists.01.org Subject: [RFC v2 37/83] Journal: Lite journal create and commit. Date: Sat, 10 Mar 2018 10:18:18 -0800 Message-Id: <1520705944-6723-38-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 NOVA uses lite journal to perform light weight transaction. Instead of journaling metadata/data changes directly, NOVA first append updates to each inode's log, and then journal the log tail pointers to make sure all the logs are updated atomically. For inode creation and deletion, NOVA journals the inode's valid field. Signed-off-by: Andiry Xu --- fs/nova/journal.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/nova/journal.h | 11 ++++ 2 files changed, 190 insertions(+) diff --git a/fs/nova/journal.c b/fs/nova/journal.c index f31de97..0e203fa 100644 --- a/fs/nova/journal.c +++ b/fs/nova/journal.c @@ -161,3 +161,182 @@ static int nova_recover_lite_journal(struct super_block *sb, return 0; } + +/**************************** Create/commit ******************************/ + +/* Create and append an undo entry for a small update to PMEM. */ +static u64 nova_append_entry_journal(struct super_block *sb, + u64 curr_p, void *field) +{ + struct nova_lite_journal_entry *entry; + struct nova_sb_info *sbi = NOVA_SB(sb); + u64 *aligned_field; + u64 addr; + + entry = (struct nova_lite_journal_entry *)nova_get_block(sb, + curr_p); + entry->type = cpu_to_le64(JOURNAL_ENTRY); + entry->padding = 0; + /* Align to 8 bytes */ + aligned_field = (u64 *)((unsigned long)field & ~7UL); + /* Store the offset from the start of Nova instead of the pointer */ + addr = (u64)nova_get_addr_off(sbi, aligned_field); + entry->data1 = cpu_to_le64(addr); + entry->data2 = cpu_to_le64(*aligned_field); + nova_update_journal_entry_csum(sb, entry); + + curr_p = next_lite_journal(curr_p); + return curr_p; +} + +static u64 nova_journal_inode_tail(struct super_block *sb, + u64 curr_p, struct nova_inode *pi) +{ + curr_p = nova_append_entry_journal(sb, curr_p, &pi->log_tail); + + return curr_p; +} + +/* Create and append undo log entries for creating a new file or directory. */ +static u64 nova_append_inode_journal(struct super_block *sb, + u64 curr_p, struct inode *inode, int new_inode, + int invalidate, int is_dir) +{ + struct nova_inode *pi = nova_get_inode(sb, inode); + + if (!pi) { + nova_err(sb, "%s: get inode failed\n", __func__); + return curr_p; + } + + if (is_dir) + return nova_journal_inode_tail(sb, curr_p, pi); + + if (new_inode) { + curr_p = nova_append_entry_journal(sb, curr_p, + &pi->valid); + } else { + curr_p = nova_journal_inode_tail(sb, curr_p, pi); + if (invalidate) { + curr_p = nova_append_entry_journal(sb, curr_p, + &pi->valid); + curr_p = nova_append_entry_journal(sb, curr_p, + &pi->delete_epoch_id); + } + } + + return curr_p; +} + +static u64 nova_append_dentry_journal(struct super_block *sb, + u64 curr_p, struct nova_dentry *dentry) +{ + curr_p = nova_append_entry_journal(sb, curr_p, &dentry->ino); + curr_p = nova_append_entry_journal(sb, curr_p, &dentry->csum); + return curr_p; +} + +/* Journaled transactions for inode creation */ +u64 nova_create_inode_transaction(struct super_block *sb, + struct inode *inode, struct inode *dir, int cpu, + int new_inode, int invalidate) +{ + struct journal_ptr_pair *pair; + u64 temp; + + pair = nova_get_journal_pointers(sb, cpu); + + temp = pair->journal_head; + + temp = nova_append_inode_journal(sb, temp, inode, + new_inode, invalidate, 0); + + temp = nova_append_inode_journal(sb, temp, dir, + new_inode, invalidate, 1); + + pair->journal_tail = temp; + nova_flush_buffer(&pair->journal_head, CACHELINE_SIZE, 1); + + nova_dbgv("%s: head 0x%llx, tail 0x%llx\n", + __func__, pair->journal_head, pair->journal_tail); + return temp; +} + +/* Journaled transactions for rename operations */ +u64 nova_create_rename_transaction(struct super_block *sb, + struct inode *old_inode, struct inode *old_dir, struct inode *new_inode, + struct inode *new_dir, struct nova_dentry *father_entry, + int invalidate_new_inode, int cpu) +{ + struct journal_ptr_pair *pair; + u64 temp; + + pair = nova_get_journal_pointers(sb, cpu); + + temp = pair->journal_head; + + /* Journal tails for old inode */ + temp = nova_append_inode_journal(sb, temp, old_inode, 0, 0, 0); + + /* Journal tails for old dir */ + temp = nova_append_inode_journal(sb, temp, old_dir, 0, 0, 1); + + if (new_inode) { + /* New inode may be unlinked */ + temp = nova_append_inode_journal(sb, temp, new_inode, 0, + invalidate_new_inode, 0); + } + + if (new_dir) + temp = nova_append_inode_journal(sb, temp, new_dir, 0, 0, 1); + + if (father_entry) + temp = nova_append_dentry_journal(sb, temp, father_entry); + + pair->journal_tail = temp; + nova_flush_buffer(&pair->journal_head, CACHELINE_SIZE, 1); + + nova_dbgv("%s: head 0x%llx, tail 0x%llx\n", + __func__, pair->journal_head, pair->journal_tail); + return temp; +} + +/* For log entry inplace update */ +u64 nova_create_logentry_transaction(struct super_block *sb, + void *entry, enum nova_entry_type type, int cpu) +{ + struct journal_ptr_pair *pair; + size_t size = 0; + int i, count; + u64 temp; + + pair = nova_get_journal_pointers(sb, cpu); + + size = nova_get_log_entry_size(sb, type); + + temp = pair->journal_head; + + count = size / 8; + for (i = 0; i < count; i++) { + temp = nova_append_entry_journal(sb, temp, + (char *)entry + i * 8); + } + + pair->journal_tail = temp; + nova_flush_buffer(&pair->journal_head, CACHELINE_SIZE, 1); + + nova_dbgv("%s: head 0x%llx, tail 0x%llx\n", + __func__, pair->journal_head, pair->journal_tail); + return temp; +} + +/* Commit the transactions by dropping the journal entries */ +void nova_commit_lite_transaction(struct super_block *sb, u64 tail, int cpu) +{ + struct journal_ptr_pair *pair; + + pair = nova_get_journal_pointers(sb, cpu); + + pair->journal_head = tail; + nova_flush_buffer(&pair->journal_head, CACHELINE_SIZE, 1); +} diff --git a/fs/nova/journal.h b/fs/nova/journal.h index d1d0ffb..2259880 100644 --- a/fs/nova/journal.h +++ b/fs/nova/journal.h @@ -40,4 +40,15 @@ struct journal_ptr_pair *nova_get_journal_pointers(struct super_block *sb, } +u64 nova_create_inode_transaction(struct super_block *sb, + struct inode *inode, struct inode *dir, int cpu, + int new_inode, int invalidate); +u64 nova_create_rename_transaction(struct super_block *sb, + struct inode *old_inode, struct inode *old_dir, struct inode *new_inode, + struct inode *new_dir, struct nova_dentry *father_entry, + int invalidate_new_inode, int cpu); +u64 nova_create_logentry_transaction(struct super_block *sb, + void *entry, enum nova_entry_type type, int cpu); +void nova_commit_lite_transaction(struct super_block *sb, u64 tail, int cpu); + #endif