Received: by 10.223.185.111 with SMTP id b44csp1649217wrg; Sat, 10 Mar 2018 10:34:38 -0800 (PST) X-Google-Smtp-Source: AG47ELs6LZ2GApAmUEgPTg+ouigmaT67ayeedMbeBNSJx/aiUm/kzU8LeG53OefqUfHK/8xwc93Z X-Received: by 10.98.149.138 with SMTP id c10mr2695056pfk.143.1520706878194; Sat, 10 Mar 2018 10:34:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520706878; cv=none; d=google.com; s=arc-20160816; b=oinfaQbzmFgbdcJuBPDKYu3fCo5qAQv66h6KVDjr5YjpYzVufj+Mxv4V/F8nQkKXEa eJDYw/KP26LNizlZWkHzViy8wlI69LwQ03epipvwnTAfEX0+vlSRJBrnBIzM4Tno9bwG hKloZyioQAvK5Z1/qaJd8P8PeY9jMhb4fHy8CD15GpmbaMlBEPkV+5t3lmy7xUIIYMQx Am7CUhH3SCrlJq7iO5dZ4q0eNQUG6LeklVRVZ9Ov2KSJzrg+iR4AFe5QxJ3QKQ2hdpT0 781rNwyMpAayhwdSyL2CtWJsEy45Gt03juRT75TMxj30/4apefoQI1HLwSxIxCnMKU5/ abGw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=R7Klix0uIBptd6q1kpVQLdMiOXEbKi6rdTJRBEL1NiQ=; b=Qc4HO9iXLQrm2vkkuAO3saOhTlHLianlLKEqf3u6uQ2ycQUGhI4zw+jyZOa4ATHwDV xedLHQ95cg4ncwzQynozcZHFsmCFTE8kumWsNY1N70PYpA4z4s8QzSoQQpWZtXL9aUy8 sSpIBTxP+KXRNCldoCKJW0O2OpAxAsDk3wi92FTVmoVavPUYdlOsSEra591kvOYHIRTD zMoydNihZwOJcKrVlD/U0VaqB1+SjBySZZwrGSlyDLga8LmjvY7DUiBx7gZunwp1AccU 5Ytk0WoxxX1RgwHhEOnMtKTP0O83UaNmCYYKSJX0Teeo5MPQRfMlQ57mj1F6oDmvpcH2 mHxg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@eng.ucsd.edu header.s=google header.b=hTf7lqrL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a2-v6si3060336plm.745.2018.03.10.10.34.23; Sat, 10 Mar 2018 10:34:38 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@eng.ucsd.edu header.s=google header.b=hTf7lqrL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752078AbeCJScY (ORCPT + 99 others); Sat, 10 Mar 2018 13:32:24 -0500 Received: from mail-pg0-f68.google.com ([74.125.83.68]:35977 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932586AbeCJSVQ (ORCPT ); Sat, 10 Mar 2018 13:21:16 -0500 Received: by mail-pg0-f68.google.com with SMTP id i14so4841861pgv.3 for ; Sat, 10 Mar 2018 10:21:15 -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=R7Klix0uIBptd6q1kpVQLdMiOXEbKi6rdTJRBEL1NiQ=; b=hTf7lqrLOR1dPdj1EveBWn7io00Dw8IZw0AmiGWhCOtgJrJtKYM8Aiaf7otueY79sc 0LwlZnCVT4iAwEIIlCBKg69Co+DpRLrov6YWictCwJMH25p+NRzTWH+EujYkNqdCFo7k UahrA5fJMGGhGUuRLCimAcQArCDdBcu8lpbz0= 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=R7Klix0uIBptd6q1kpVQLdMiOXEbKi6rdTJRBEL1NiQ=; b=t7htN4AcMrtt2si6FXIdAVOfDE33BBFHac6S+NmjqtabknyLgD/QqimSw8znt83xE1 YagJHMcPp+qJT1DALq8RaKtsFaYhfT+P605MIiDSG7LCn5e5d/MqqcsNtf1hUSFCnfP1 jCqqmX+4Sz5mMYz4951NLZrnPiH1skCCfMIZfh/llFoL02M5/sKeFE6rLGEowBGfOcN3 hg+9va8xpdYGLm6+wcjY9MQaQSfyM8ABo3Qsci5Up4xl7iutC0V1pVv52EPXyhg3M0u5 6z1fsYG+c1TxKx8gAWbCZMrAEkGIK1sc4jahQrYRQM1uq0N5S0AwuQR9AXqoKsOiRL10 r/fQ== X-Gm-Message-State: AElRT7FJ+D7uIDHreh9vfWTJGE2T82spRR0CYlHDkSiKXJc6vkYe5VLt nP/yg3+tWlToplZdZ5mjhQ+SuQ== X-Received: by 10.98.157.199 with SMTP id a68mr2659818pfk.59.1520706075236; Sat, 10 Mar 2018 10:21:15 -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.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 10 Mar 2018 10:21:14 -0800 (PST) From: Andiry Xu To: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, linux-nvdimm@lists.01.org Cc: dan.j.williams@intel.com, andy.rudoff@intel.com, coughlan@redhat.com, swanson@cs.ucsd.edu, david@fromorbit.com, jack@suse.com, swhiteho@redhat.com, miklos@szeredi.hu, andiry.xu@gmail.com, Andiry Xu Subject: [RFC v2 49/83] Dir: Append create/remove dentry. Date: Sat, 10 Mar 2018 10:18:30 -0800 Message-Id: <1520705944-6723-50-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> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Andiry Xu NOVA adds or removes a directory/file by appending a dentry to the parent directory's log. Dentry contains filename and inode number. A positive inode number indicates a create(valid) dentry, and a dentry with inode number zero is a remove dentry. NOVA can also inplace update a create dentry to invalidate it. Signed-off-by: Andiry Xu --- fs/nova/dir.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/nova/nova.h | 4 ++ 2 files changed, 144 insertions(+) diff --git a/fs/nova/dir.c b/fs/nova/dir.c index 35a66f9..47ee9ad 100644 --- a/fs/nova/dir.c +++ b/fs/nova/dir.c @@ -222,6 +222,146 @@ int nova_append_dir_init_entries(struct super_block *sb, return 0; } +/* adds a directory entry pointing to the inode. assumes the inode has + * already been logged for consistency + */ +int nova_add_dentry(struct dentry *dentry, u64 ino, int inc_link, + struct nova_inode_update *update, u64 epoch_id) +{ + struct inode *dir = dentry->d_parent->d_inode; + struct super_block *sb = dir->i_sb; + struct nova_inode_info *si = NOVA_I(dir); + struct nova_inode_info_header *sih = &si->header; + struct nova_inode *pidir; + const char *name = dentry->d_name.name; + int namelen = dentry->d_name.len; + struct nova_dentry *direntry; + unsigned short loglen; + int ret; + u64 curr_entry; + timing_t add_dentry_time; + + nova_dbg_verbose("%s: dir %lu new inode %llu\n", + __func__, dir->i_ino, ino); + nova_dbg_verbose("%s: %s %d\n", __func__, name, namelen); + NOVA_START_TIMING(add_dentry_t, add_dentry_time); + if (namelen == 0) + return -EINVAL; + + pidir = nova_get_inode(sb, dir); + + /* + * XXX shouldn't update any times until successful + * completion of syscall, but too many callers depend + * on this. + */ + dir->i_mtime = dir->i_ctime = current_time(dir); + + loglen = NOVA_DIR_LOG_REC_LEN(namelen); + ret = nova_append_dentry(sb, pidir, dir, dentry, + ino, loglen, update, + inc_link, epoch_id); + + if (ret) { + nova_dbg("%s: append dir entry failure\n", __func__); + return ret; + } + + curr_entry = update->curr_entry; + direntry = (struct nova_dentry *)nova_get_block(sb, curr_entry); + sih->last_dentry = curr_entry; + ret = nova_insert_dir_radix_tree(sb, sih, name, namelen, direntry); + + sih->trans_id++; + NOVA_END_TIMING(add_dentry_t, add_dentry_time); + return ret; +} + +static int nova_can_inplace_update_dentry(struct super_block *sb, + struct nova_dentry *dentry, u64 epoch_id) +{ + if (dentry && dentry->epoch_id == epoch_id) + return 1; + + return 0; +} + +/* removes a directory entry pointing to the inode. assumes the inode has + * already been logged for consistency + */ +int nova_remove_dentry(struct dentry *dentry, int dec_link, + struct nova_inode_update *update, u64 epoch_id) +{ + struct inode *dir = dentry->d_parent->d_inode; + struct super_block *sb = dir->i_sb; + struct nova_sb_info *sbi = NOVA_SB(sb); + struct nova_inode_info *si = NOVA_I(dir); + struct nova_inode_info_header *sih = &si->header; + struct nova_inode *pidir; + struct qstr *entry = &dentry->d_name; + struct nova_dentry *old_dentry = NULL; + unsigned short loglen; + int ret; + u64 curr_entry; + timing_t remove_dentry_time; + + NOVA_START_TIMING(remove_dentry_t, remove_dentry_time); + + update->create_dentry = NULL; + update->delete_dentry = NULL; + + if (!dentry->d_name.len) { + ret = -EINVAL; + goto out; + } + + ret = nova_remove_dir_radix_tree(sb, sih, entry->name, entry->len, 0, + &old_dentry); + + if (ret) + goto out; + + pidir = nova_get_inode(sb, dir); + + dir->i_mtime = dir->i_ctime = current_time(dir); + + if (nova_can_inplace_update_dentry(sb, old_dentry, epoch_id)) { + nova_inplace_update_dentry(sb, dir, old_dentry, + dec_link, epoch_id); + curr_entry = nova_get_addr_off(sbi, old_dentry); + + sih->last_dentry = curr_entry; + /* Leave create/delete_dentry to NULL + * Do not change tail if used as input + */ + if (update->tail == 0) { + update->tail = sih->log_tail; + } + sih->trans_id++; + goto out; + } + + loglen = NOVA_DIR_LOG_REC_LEN(entry->len); + ret = nova_append_dentry(sb, pidir, dir, dentry, + 0, loglen, update, + dec_link, epoch_id); + + if (ret) { + nova_dbg("%s: append dir entry failure\n", __func__); + goto out; + } + + update->create_dentry = old_dentry; + curr_entry = update->curr_entry; + update->delete_dentry = (struct nova_dentry *)nova_get_block(sb, + curr_entry); + sih->last_dentry = curr_entry; + sih->trans_id++; +out: + NOVA_END_TIMING(remove_dentry_t, remove_dentry_time); + return ret; +} + static u64 nova_find_next_dentry_addr(struct super_block *sb, struct nova_inode_info_header *sih, u64 pos) { diff --git a/fs/nova/nova.h b/fs/nova/nova.h index ed269fe..3a51dae 100644 --- a/fs/nova/nova.h +++ b/fs/nova/nova.h @@ -461,6 +461,10 @@ struct nova_dentry *nova_find_dentry(struct super_block *sb, unsigned long name_len); int nova_append_dir_init_entries(struct super_block *sb, struct nova_inode *pi, u64 self_ino, u64 parent_ino, u64 epoch_id); +int nova_add_dentry(struct dentry *dentry, u64 ino, int inc_link, + struct nova_inode_update *update, u64 epoch_id); +int nova_remove_dentry(struct dentry *dentry, int dec_link, + struct nova_inode_update *update, u64 epoch_id); /* rebuild.c */ int nova_rebuild_inode(struct super_block *sb, struct nova_inode_info *si, -- 2.7.4