From patchwork Tue Mar 20 17:02:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Brandenburg X-Patchwork-Id: 10297539 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 8A54360349 for ; Tue, 20 Mar 2018 17:03:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7AAC228B77 for ; Tue, 20 Mar 2018 17:03:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6F16F295FF; Tue, 20 Mar 2018 17:03:10 +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=-6.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,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 EFE9C28B77 for ; Tue, 20 Mar 2018 17:03:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751751AbeCTRDG (ORCPT ); Tue, 20 Mar 2018 13:03:06 -0400 Received: from mail-qt0-f196.google.com ([209.85.216.196]:43286 "EHLO mail-qt0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751719AbeCTRC4 (ORCPT ); Tue, 20 Mar 2018 13:02:56 -0400 Received: by mail-qt0-f196.google.com with SMTP id s48so2342082qtb.10 for ; Tue, 20 Mar 2018 10:02:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=omnibond-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=OJgadrAmMLyG2cU2CvsmZnrGCf3yi0hTq20AImZY2jY=; b=UCKBNTfCk+fvXcV5n8N0RzXkc1NSuUATQAET5SO4pUkUgzHWfWFEakkNq6r3URAbMg sJcQVRN8jXpXcfMHk6nx5GHBtfwDqejm0wt+MFf5FMeFOyK7nnybPYB6o8EoSxgKM10I BlzbZ2XXXr5PKUiK9ASfYqAq+/SPbhIPBpO+d6uN1pgBZ+xwcZGTD/SzDeuaBERPPR1r YkmW8lmuFXMACm9bWXxX8w4z30g0zDkMNvD8nPkdpVWFDnA7lPZw8LhYm0CMni/TYNdX wMeKaFPsB0dynKMdYK0B/aJSNLl10iSvsD8OjPBWQhWwIlHCmSgcjz5ckgw/NDsdOzaD sulA== 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=OJgadrAmMLyG2cU2CvsmZnrGCf3yi0hTq20AImZY2jY=; b=YnGa56Xj3XVLfhumNPOMT8XbE55y9HdS9v8TJIBQszhe1TQm80zTv/nQ96t76dQJWz Rt1gUF7zOZmt5GexEtcNP4H1ZYUJSijLO7Z3Ne0Rom/2knj0LShuLWDv275fwmp/z9xA VzHoTT59fnvkrY6BEx1nX/2tt8/MW5NE8DjylPjVDD4THubqgDuZ+O7Vg3dXcVLdNlOF ItfpARsxG9WJqcuQB5geVTeDbwPveDHkcHSJE/+Xy6fVLT20+QIRfLTjEJkdWnfVURmr ToScdjZ45Yp3kLoEJthvApqspFxLy5zD+ZAxqMw821ZYnGo/nMPq27Oa1i+F3shammOL g7lQ== X-Gm-Message-State: AElRT7HF3AHP3aGmnJYJg4KKGZni6/fpKttO2FXNUyMp4axlkGLP3aS7 XCiiQQwFPYLXrNrBt/H8vqGBlA== X-Google-Smtp-Source: AG47ELs1GQy6PuRxVjWXSr5uEHNcqHo5rMqeJvxnSBu/JEoE1LA3Xqh5TrsmVeYwm2x4HnOONx7fJw== X-Received: by 10.237.43.3 with SMTP id p3mr25647076qtd.41.1521565375549; Tue, 20 Mar 2018 10:02:55 -0700 (PDT) Received: from ip-172-31-31-212.ec2.internal (ec2-34-238-158-165.compute-1.amazonaws.com. [34.238.158.165]) by smtp.gmail.com with ESMTPSA id l1sm1587277qtb.33.2018.03.20.10.02.54 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 20 Mar 2018 10:02:54 -0700 (PDT) From: Martin Brandenburg To: hubcap@omnibond.com, linux-fsdevel@vger.kernel.org Cc: Martin Brandenburg Subject: [PATCH 13/24] orangefs: hold i_lock during inode_getattr Date: Tue, 20 Mar 2018 17:02:23 +0000 Message-Id: <20180320170234.1412-14-martin@omnibond.com> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180320170234.1412-1-martin@omnibond.com> References: <20180320170234.1412-1-martin@omnibond.com> 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 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 --- 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 6222f029f93a..d77787f7b2f3 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -252,8 +252,8 @@ int orangefs_getattr(const struct path *path, struct kstat *stat, struct orangefs_inode_s *orangefs_inode = NULL; 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 ab1be285f89d..8b13f1d15999 100644 --- a/fs/orangefs/orangefs-utils.c +++ b/fs/orangefs/orangefs-utils.c @@ -276,12 +276,17 @@ int orangefs_inode_getattr(struct inode *inode, int flags) loff_t inode_size, rounded_up_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) @@ -301,13 +306,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; } } @@ -325,20 +340,16 @@ int orangefs_inode_getattr(struct inode *inode, int flags) inode->i_size = inode_size; orangefs_inode->blksize = new_op->downcall.resp.getattr.attributes.blksize; - spin_lock(&inode->i_lock); inode->i_bytes = inode_size; inode->i_blocks = (unsigned long)(rounded_up_size / 512); - spin_unlock(&inode->i_lock); } break; case S_IFDIR: if (flags) { inode->i_size = PAGE_SIZE; orangefs_inode->blksize = i_blocksize(inode); - spin_lock(&inode->i_lock); inode_set_bytes(inode, inode->i_size); - spin_unlock(&inode->i_lock); } set_nlink(inode, 1); break; @@ -352,7 +363,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; } @@ -362,7 +373,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-> @@ -386,6 +397,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;