From patchwork Tue Mar 28 19:49:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Brandenburg X-Patchwork-Id: 9650457 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 B76A0601E9 for ; Tue, 28 Mar 2017 19:50:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BB8B126D05 for ; Tue, 28 Mar 2017 19:50:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B05AC2841C; Tue, 28 Mar 2017 19:50:38 +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.4 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM 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 92C0826D05 for ; Tue, 28 Mar 2017 19:50:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932250AbdC1Tug (ORCPT ); Tue, 28 Mar 2017 15:50:36 -0400 Received: from mail-yw0-f180.google.com ([209.85.161.180]:34230 "EHLO mail-yw0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932243AbdC1Tuf (ORCPT ); Tue, 28 Mar 2017 15:50:35 -0400 Received: by mail-yw0-f180.google.com with SMTP id p77so61030695ywg.1 for ; Tue, 28 Mar 2017 12:50:34 -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; bh=Vzqls2ETTJreRpVV+KrGaFbqW5vnHIBaRFysX3UN1PI=; b=CUXlA/FNbelaQvIPi0PL1zCmGjyBN7BNlPcdNLSfYC5I0njrkubXoyXTWJ0RYCxloJ 5X+DYMs56gA3EihQa1pJao+tsLikFLLt/DUOj+SOHOyeDkiiufjAo+OgJyXoJvqpsnHW aKeI7Zt2+feFXO52FWTiOrHlSiWYXpS4/LjpbFwmvr2uUN7ehsGZ9FJ54LRqZ3/KCY2+ Tf5WI2EpgJF/hGKjpzaIK9r14wfS7uHhVkIExvXrRVRAEuaIyh+1HzTUFe1jLdUaq59x CebineetM184i8iVARHQTfuUAbR5IDLU94bEiVgm8c4ZZvOmyY2B97SFXW53Ch8Mz3IC esIw== 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; bh=Vzqls2ETTJreRpVV+KrGaFbqW5vnHIBaRFysX3UN1PI=; b=JjPSfiBB3OS0QfHn1cTlIdU1LfqaUK0sRhgjFsz3Foyhs3OtH8BBPoLUoFC83vHcN+ jD7+C3gB/NZIKbty3TZDeq1tvLi1OrKrcCBu1mx0/UjNExHIHFhXKYcVJxiwjVaeqF7t E4IIKRFpl+PRQW9qLkmIdp5+Mbp/Zsqt8wHxzx/MjV+VPJuAhGyH2nWz4paA2IQeWq7G NQt+D5dqmA2WYmzCpEu+pIP6/ANnBIiYqK5XCW26vTnunE9z2T6UW9r00Ch97Y3Rm8XI O5dJYh8HyoB8xbp8M0oAdJ67ZuifH3zABwD4bHkBFnudNokfLDSl3a9PVMPE/jbKYwjm VWVg== X-Gm-Message-State: AFeK/H2++khlE0++WH3lBJ3Q2bV2TVnvtIt9yAX9k2fUBUDWKpK0U5YvZh4jBoE5Dy8ZWQ== X-Received: by 10.37.43.9 with SMTP id r9mr21711837ybr.25.1490730614606; Tue, 28 Mar 2017 12:50:14 -0700 (PDT) Received: from mbmbp.clemson.edu ([130.127.148.252]) by smtp.gmail.com with ESMTPSA id d134sm1843727ywb.10.2017.03.28.12.50.13 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 28 Mar 2017 12:50:13 -0700 (PDT) From: Martin Brandenburg To: hubcap@omnibond.com, linux-fsdevel@vger.kernel.org Cc: Martin Brandenburg Subject: [PATCH] orangefs: implement statx Date: Tue, 28 Mar 2017 15:49:47 -0400 Message-Id: <1490730587-12661-1-git-send-email-martin@omnibond.com> X-Mailer: git-send-email 2.1.4 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 Fortunately OrangeFS has had a getattr request mask for a long time. The server basically has two difficulty levels for attributes. Fetching any attribute except size requires communicating with the metadata server for that handle. Since all the attributes are right there, it makes sense to return them all. Fetching the size requires communicating with every I/O server (that the file is distributed across). Therefore if asked for anything except size, get everything except size, and if asked for size, get everything. Signed-off-by: Martin Brandenburg --- fs/orangefs/file.c | 6 ++++-- fs/orangefs/inode.c | 15 ++++++++++----- fs/orangefs/orangefs-kernel.h | 3 ++- fs/orangefs/orangefs-utils.c | 13 +++++++++++-- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index e6bbc80..b421df1 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -475,7 +475,8 @@ static ssize_t orangefs_file_write_iter(struct kiocb *iocb, struct iov_iter *ite /* Make sure generic_write_checks sees an up to date inode size. */ if (file->f_flags & O_APPEND) { - rc = orangefs_inode_getattr(file->f_mapping->host, 0, 1); + rc = orangefs_inode_getattr(file->f_mapping->host, 0, 1, + STATX_SIZE); if (rc == -ESTALE) rc = -EIO; if (rc) { @@ -693,7 +694,8 @@ static loff_t orangefs_file_llseek(struct file *file, loff_t offset, int origin) * NOTE: We are only interested in file size here, * so we set mask accordingly. */ - ret = orangefs_inode_getattr(file->f_mapping->host, 0, 1); + ret = orangefs_inode_getattr(file->f_mapping->host, 0, 1, + STATX_SIZE); if (ret == -ESTALE) ret = -EIO; if (ret) { diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index a304bf3..ee28364 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -161,7 +161,7 @@ static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr) iattr->ia_size); /* Ensure that we have a up to date size, so we know if it changed. */ - ret = orangefs_inode_getattr(inode, 0, 1); + ret = orangefs_inode_getattr(inode, 0, 1, STATX_SIZE); if (ret == -ESTALE) ret = -EIO; if (ret) { @@ -256,13 +256,18 @@ int orangefs_getattr(const struct path *path, struct kstat *stat, "orangefs_getattr: called on %pd\n", path->dentry); - ret = orangefs_inode_getattr(inode, 0, 0); + ret = orangefs_inode_getattr(inode, 0, 0, request_mask); if (ret == 0) { generic_fillattr(inode, stat); /* override block size reported to stat */ orangefs_inode = ORANGEFS_I(inode); stat->blksize = orangefs_inode->blksize; + + if (request_mask & STATX_SIZE) + stat->result_mask = STATX_BASIC_STATS; + else + stat->result_mask = STATX_BASIC_STATS & ~STATX_SIZE; } return ret; } @@ -277,7 +282,7 @@ int orangefs_permission(struct inode *inode, int mask) gossip_debug(GOSSIP_INODE_DEBUG, "%s: refreshing\n", __func__); /* Make sure the permission (and other common attrs) are up to date. */ - ret = orangefs_inode_getattr(inode, 0, 0); + ret = orangefs_inode_getattr(inode, 0, 0, STATX_MODE); if (ret < 0) return ret; @@ -375,7 +380,7 @@ struct inode *orangefs_iget(struct super_block *sb, struct orangefs_object_kref if (!inode || !(inode->i_state & I_NEW)) return inode; - error = orangefs_inode_getattr(inode, 1, 1); + error = orangefs_inode_getattr(inode, 1, 1, STATX_ALL); if (error) { iget_failed(inode); return ERR_PTR(error); @@ -420,7 +425,7 @@ struct inode *orangefs_new_inode(struct super_block *sb, struct inode *dir, orangefs_set_inode(inode, ref); inode->i_ino = hash; /* needed for stat etc */ - error = orangefs_inode_getattr(inode, 1, 1); + error = orangefs_inode_getattr(inode, 1, 1, STATX_ALL); if (error) goto out_iput; diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 5e48a0b..016d988 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h @@ -499,7 +499,8 @@ int orangefs_inode_setxattr(struct inode *inode, size_t size, int flags); -int orangefs_inode_getattr(struct inode *inode, int new, int bypass); +int orangefs_inode_getattr(struct inode *inode, int new, int bypass, + u32 request_mask); int orangefs_inode_check_changed(struct inode *inode); diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c index 9b96b99..e6e01f6 100644 --- a/fs/orangefs/orangefs-utils.c +++ b/fs/orangefs/orangefs-utils.c @@ -251,7 +251,8 @@ static int orangefs_inode_is_stale(struct inode *inode, int new, return 0; } -int orangefs_inode_getattr(struct inode *inode, int new, int bypass) +int orangefs_inode_getattr(struct inode *inode, int new, int bypass, + u32 request_mask) { struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); struct orangefs_kernel_op_s *new_op; @@ -270,7 +271,15 @@ int orangefs_inode_getattr(struct inode *inode, int new, int bypass) if (!new_op) return -ENOMEM; new_op->upcall.req.getattr.refn = orangefs_inode->refn; - new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_ALL_NOHINT; + /* + * Size is the hardest attribute to get. The incremental cost of any + * other attribute is essentially free. + */ + if (request_mask & STATX_SIZE) + new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_ALL_NOHINT; + else + new_op->upcall.req.getattr.mask = + ORANGEFS_ATTR_SYS_ALL_NOHINT & ~ORANGEFS_ATTR_SYS_SIZE; ret = service_operation(new_op, __func__, get_interruptible_flag(inode));