From patchwork Thu Apr 18 18:40:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: hubcap@kernel.org X-Patchwork-Id: 10907851 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 50F2D1390 for ; Thu, 18 Apr 2019 18:42:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3A988285DB for ; Thu, 18 Apr 2019 18:42:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2F58928D5E; Thu, 18 Apr 2019 18:42:52 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B9BD6285DB for ; Thu, 18 Apr 2019 18:42:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389900AbfDRSmu (ORCPT ); Thu, 18 Apr 2019 14:42:50 -0400 Received: from mail.kernel.org ([198.145.29.99]:60644 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389894AbfDRSmu (ORCPT ); Thu, 18 Apr 2019 14:42:50 -0400 Received: from localhost.localdomain (unknown [24.213.116.99]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id D296521871; Thu, 18 Apr 2019 18:42:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555612969; bh=buXOAXFwKb3+LAJ3rYdauHnMviRKt6GGbvrDf0EOmEE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KNHWasxROHouoZk5BmGUa0IAzNh1PXciQ/5ibJOFl15bIaXOSDANagzNuYfEL0kBn tELTH1gr/tvl8w/Gv0VeEgrWqOAK6TC9MrW3ZekAzmwTozP+CZwTgf529gbkFTXWQt GT4B8qHTfy0zHoQce4y6C5VJNSWQpjvz883I5u9I= From: hubcap@kernel.org To: linux-fsdevel@vger.kernel.org, christoph@lameter.com Cc: Martin Brandenburg , Mike Marshall Subject: [PATCH 05/22] orangefs: hold i_lock during inode_getattr Date: Thu, 18 Apr 2019 14:40:57 -0400 Message-Id: <20190418184113.9152-6-hubcap@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190418184113.9152-1-hubcap@kernel.org> References: <20190418184113.9152-1-hubcap@kernel.org> MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Martin Brandenburg This should be a no-op now. When inode writeback works, this will prevent a getattr from overwriting inode data while an inode is transitioning to dirty. Signed-off-by: Martin Brandenburg Signed-off-by: Mike Marshall --- fs/orangefs/inode.c | 4 ++-- fs/orangefs/orangefs-utils.c | 33 +++++++++++++++++++++++---------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index 152c3683d881..222ef7be0c7c 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -253,8 +253,8 @@ int orangefs_getattr(const struct path *path, struct kstat *stat, struct inode *inode = path->dentry->d_inode; gossip_debug(GOSSIP_INODE_DEBUG, - "orangefs_getattr: called on %pd\n", - path->dentry); + "orangefs_getattr: called on %pd mask %u\n", + path->dentry, request_mask); ret = orangefs_inode_getattr(inode, request_mask & STATX_SIZE ? ORANGEFS_GETATTR_SIZE : 0); diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c index 76f18a3494c7..d44cbe96719a 100644 --- a/fs/orangefs/orangefs-utils.c +++ b/fs/orangefs/orangefs-utils.c @@ -280,12 +280,17 @@ int orangefs_inode_getattr(struct inode *inode, int flags) loff_t inode_size; int ret, type; - gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__, - get_khandle_from_ino(inode)); + gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU flags %d\n", + __func__, get_khandle_from_ino(inode), flags); + spin_lock(&inode->i_lock); /* Must have all the attributes in the mask and be within cache time. */ - if (!flags && time_before(jiffies, orangefs_inode->getattr_time)) + if ((!flags && time_before(jiffies, orangefs_inode->getattr_time)) || + inode->i_state & I_DIRTY) { + spin_unlock(&inode->i_lock); return 0; + } + spin_unlock(&inode->i_lock); new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR); if (!new_op) @@ -306,13 +311,23 @@ int orangefs_inode_getattr(struct inode *inode, int flags) if (ret != 0) goto out; + spin_lock(&inode->i_lock); + /* Must have all the attributes in the mask and be within cache time. */ + if ((!flags && time_before(jiffies, orangefs_inode->getattr_time)) || + inode->i_state & I_DIRTY) { + gossip_debug(GOSSIP_UTILS_DEBUG, "%s: in cache or dirty\n", + __func__); + ret = 0; + goto out_unlock; + } + if (!(flags & ORANGEFS_GETATTR_NEW)) { ret = orangefs_inode_is_stale(inode, &new_op->downcall.resp.getattr.attributes, new_op->downcall.resp.getattr.link_target); if (ret) { ret = -ESTALE; - goto out; + goto out_unlock; } } @@ -328,19 +343,15 @@ int orangefs_inode_getattr(struct inode *inode, int flags) inode->i_size = inode_size; inode->i_blkbits = ffs(new_op->downcall.resp.getattr. attributes.blksize); - spin_lock(&inode->i_lock); inode->i_bytes = inode_size; inode->i_blocks = (inode_size + 512 - inode_size % 512)/512; - spin_unlock(&inode->i_lock); } break; case S_IFDIR: if (flags) { inode->i_size = PAGE_SIZE; - spin_lock(&inode->i_lock); inode_set_bytes(inode, inode->i_size); - spin_unlock(&inode->i_lock); } set_nlink(inode, 1); break; @@ -353,7 +364,7 @@ int orangefs_inode_getattr(struct inode *inode, int flags) ORANGEFS_NAME_MAX); if (ret == -E2BIG) { ret = -EIO; - goto out; + goto out_unlock; } inode->i_link = orangefs_inode->link_target; } @@ -363,7 +374,7 @@ int orangefs_inode_getattr(struct inode *inode, int flags) /* XXX: ESTALE? This is what is done if it is not new. */ orangefs_make_bad_inode(inode); ret = -ESTALE; - goto out; + goto out_unlock; } inode->i_uid = make_kuid(&init_user_ns, new_op-> @@ -387,6 +398,8 @@ int orangefs_inode_getattr(struct inode *inode, int flags) orangefs_inode->getattr_time = jiffies + orangefs_getattr_timeout_msecs*HZ/1000; ret = 0; +out_unlock: + spin_unlock(&inode->i_lock); out: op_release(new_op); return ret;