From: Martin Brandenburg <martin@omnibond.com>
To: hubcap@omnibond.com, linux-fsdevel@vger.kernel.org
Cc: Martin Brandenburg <martin@omnibond.com>
Subject: [PATCH 13/24] orangefs: hold i_lock during inode_getattr
Date: Tue, 20 Mar 2018 17:02:23 +0000 [thread overview]
Message-ID: <20180320170234.1412-14-martin@omnibond.com> (raw)
In-Reply-To: <20180320170234.1412-1-martin@omnibond.com>
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 <martin@omnibond.com>
---
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;
--
2.16.2
next prev parent reply other threads:[~2018-03-20 17:02 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-20 17:02 [PATCH 00/24] orangefs: page cache Martin Brandenburg
2018-03-20 17:02 ` [PATCH 01/24] orangefs: make several *_operations structs static Martin Brandenburg
2018-03-20 17:02 ` [PATCH 02/24] orangefs: remove unused code Martin Brandenburg
2018-03-20 17:02 ` [PATCH 03/24] orangefs: create uapi interface Martin Brandenburg
2018-03-20 17:02 ` [PATCH 04/24] orangefs: open code short single-use functions Martin Brandenburg
2018-03-20 17:02 ` [PATCH 05/24] orangefs: implement vm_ops->fault Martin Brandenburg
2018-03-20 17:02 ` [PATCH 06/24] orangefs: implement xattr cache Martin Brandenburg
2018-03-20 17:02 ` [PATCH 07/24] orangefs: simpler installation documentation Martin Brandenburg
2018-03-20 17:02 ` [PATCH 08/24] orangefs: add tracepoint for service_operation Martin Brandenburg
2018-03-20 17:02 ` [PATCH 09/24] orangefs: tracepoints for orangefs_devreq_{read,write_iter,poll} Martin Brandenburg
2018-03-20 17:02 ` [PATCH 10/24] orangefs: do not invalidate attributes on inode create Martin Brandenburg
2018-03-20 17:02 ` [PATCH 11/24] orangefs: simply orangefs_inode_getattr interface Martin Brandenburg
2018-03-20 17:02 ` [PATCH 12/24] orangefs: update attributes rather than relying on server Martin Brandenburg
2018-03-20 17:02 ` Martin Brandenburg [this message]
2018-03-20 17:02 ` [PATCH 14/24] orangefs: set up and use backing_dev_info Martin Brandenburg
2018-03-20 17:02 ` [PATCH 15/24] orangefs: let setattr write to cached inode Martin Brandenburg
2018-03-20 17:02 ` [PATCH 16/24] orangefs: reorganize setattr functions to track attribute changes Martin Brandenburg
2018-03-20 17:02 ` [PATCH 17/24] orangefs: remove orangefs_readpages Martin Brandenburg
2018-03-20 17:02 ` [PATCH 18/24] orangefs: service ops done for writeback are not killable Martin Brandenburg
2018-03-20 17:02 ` [PATCH 19/24] orangefs: migrate to generic_file_read_iter Martin Brandenburg
2018-03-20 17:02 ` [PATCH 20/24] orangefs: implement writepage Martin Brandenburg
2018-03-20 17:02 ` [PATCH 21/24] orangefs: skip inode writeout if nothing to write Martin Brandenburg
2018-03-20 17:02 ` [PATCH 22/24] orangefs: write range tracking Martin Brandenburg
2018-03-20 17:02 ` [PATCH 23/24] orangefs: tracepoints for readpage and writeback Martin Brandenburg
2018-03-20 17:02 ` [PATCH 24/24] orangefs: tracepoints for getattr, setattr, and write_inode Martin Brandenburg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180320170234.1412-14-martin@omnibond.com \
--to=martin@omnibond.com \
--cc=hubcap@omnibond.com \
--cc=linux-fsdevel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).