linux-xfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@kernel.org>
To: Alexander Viro <viro@zeniv.linux.org.uk>,
	Christian Brauner <brauner@kernel.org>,
	Chuck Lever <chuck.lever@oracle.com>, Neil Brown <neilb@suse.de>,
	Olga Kornievskaia <kolga@netapp.com>,
	Dai Ngo <Dai.Ngo@oracle.com>, Tom Talpey <tom@talpey.com>,
	Chandan Babu R <chandan.babu@oracle.com>,
	"Darrick J. Wong" <djwong@kernel.org>,
	Dave Chinner <david@fromorbit.com>, Jan Kara <jack@suse.cz>,
	Linus Torvalds <torvalds@linux-foundation.org>
Cc: Kent Overstreet <kent.overstreet@linux.dev>,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-nfs@vger.kernel.org, linux-xfs@vger.kernel.org,
	Jeff Layton <jlayton@kernel.org>
Subject: [PATCH v8 3/5] fs: have setattr_copy handle multigrain timestamps appropriately
Date: Fri, 22 Sep 2023 13:14:42 -0400	[thread overview]
Message-ID: <20230922-ctime-v8-3-45f0c236ede1@kernel.org> (raw)
In-Reply-To: <20230922-ctime-v8-0-45f0c236ede1@kernel.org>

The setattr codepath is still using coarse-grained timestamps, even on
multigrain filesystems. To fix this, we need to fetch the timestamp for
ctime updates later, at the point where the assignment occurs in
setattr_copy.

On a multigrain inode, ignore the ia_ctime in the attrs, and always
update the ctime to the current clock value. Update the atime and mtime
with the same value (if needed) unless they are being set to other
specific values, a'la utimes().

Note that we don't want to do this universally however, as some
filesystems (e.g. most networked fs) want to do an explicit update
elsewhere before updating the local inode.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 fs/attr.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 46 insertions(+), 6 deletions(-)

diff --git a/fs/attr.c b/fs/attr.c
index a8ae5f6d9b16..8ba330e6a582 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -275,6 +275,42 @@ int inode_newsize_ok(const struct inode *inode, loff_t offset)
 }
 EXPORT_SYMBOL(inode_newsize_ok);
 
+/**
+ * setattr_copy_mgtime - update timestamps for mgtime inodes
+ * @inode: inode timestamps to be updated
+ * @attr: attrs for the update
+ *
+ * With multigrain timestamps, we need to take more care to prevent races
+ * when updating the ctime. Always update the ctime to the very latest
+ * using the standard mechanism, and use that to populate the atime and
+ * mtime appropriately (unless we're setting those to specific values).
+ */
+static void setattr_copy_mgtime(struct inode *inode, const struct iattr *attr)
+{
+	unsigned int ia_valid = attr->ia_valid;
+	struct timespec64 now;
+
+	/*
+	 * If the ctime isn't being updated then nothing else should be
+	 * either.
+	 */
+	if (!(ia_valid & ATTR_CTIME)) {
+		WARN_ON_ONCE(ia_valid & (ATTR_ATIME|ATTR_MTIME));
+		return;
+	}
+
+	now = inode_set_ctime_current(inode);
+	if (ia_valid & ATTR_ATIME_SET)
+		inode->i_atime = attr->ia_atime;
+	else if (ia_valid & ATTR_ATIME)
+		inode->i_atime = now;
+
+	if (ia_valid & ATTR_MTIME_SET)
+		inode->i_mtime = attr->ia_mtime;
+	else if (ia_valid & ATTR_MTIME)
+		inode->i_mtime = now;
+}
+
 /**
  * setattr_copy - copy simple metadata updates into the generic inode
  * @idmap:	idmap of the mount the inode was found from
@@ -307,12 +343,6 @@ void setattr_copy(struct mnt_idmap *idmap, struct inode *inode,
 
 	i_uid_update(idmap, attr, inode);
 	i_gid_update(idmap, attr, inode);
-	if (ia_valid & ATTR_ATIME)
-		inode->i_atime = attr->ia_atime;
-	if (ia_valid & ATTR_MTIME)
-		inode->i_mtime = attr->ia_mtime;
-	if (ia_valid & ATTR_CTIME)
-		inode_set_ctime_to_ts(inode, attr->ia_ctime);
 	if (ia_valid & ATTR_MODE) {
 		umode_t mode = attr->ia_mode;
 		if (!in_group_or_capable(idmap, inode,
@@ -320,6 +350,16 @@ void setattr_copy(struct mnt_idmap *idmap, struct inode *inode,
 			mode &= ~S_ISGID;
 		inode->i_mode = mode;
 	}
+
+	if (is_mgtime(inode))
+		return setattr_copy_mgtime(inode, attr);
+
+	if (ia_valid & ATTR_ATIME)
+		inode->i_atime = attr->ia_atime;
+	if (ia_valid & ATTR_MTIME)
+		inode->i_mtime = attr->ia_mtime;
+	if (ia_valid & ATTR_CTIME)
+		inode_set_ctime_to_ts(inode, attr->ia_ctime);
 }
 EXPORT_SYMBOL(setattr_copy);
 

-- 
2.41.0


  parent reply	other threads:[~2023-09-22 17:15 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-22 17:14 [PATCH v8 0/5] fs: multigrain timestamps for XFS's change_cookie Jeff Layton
2023-09-22 17:14 ` [PATCH v8 1/5] fs: add infrastructure for multigrain timestamps Jeff Layton
2023-09-22 17:31   ` Kent Overstreet
2023-09-22 18:22     ` Jeff Layton
2023-09-22 17:14 ` [PATCH v8 2/5] fs: optimize away some fine-grained timestamp updates Jeff Layton
2023-09-22 17:14 ` Jeff Layton [this message]
2023-09-22 17:14 ` [PATCH v8 4/5] fs: add timestamp_truncate_to_gran helper Jeff Layton
2023-09-22 17:14 ` [PATCH v8 5/5] xfs: switch to multigrain timestamps Jeff Layton
2023-09-23  7:15 ` [PATCH v8 0/5] fs: multigrain timestamps for XFS's change_cookie Amir Goldstein
2023-09-23 10:22   ` Jeff Layton
2023-09-23 14:58     ` Amir Goldstein
2023-09-25 10:08       ` Jeff Layton
2023-09-23 10:46   ` Jeff Layton
2023-09-23 14:52     ` Amir Goldstein
2023-09-24 22:18       ` Dave Chinner
2023-09-25 10:14         ` Jeff Layton
2023-09-25 22:32           ` Dave Chinner
2023-09-26 11:31             ` Jeff Layton
2023-09-26 23:33               ` Dave Chinner
2023-09-27 10:26                 ` Jeff Layton
2023-09-23 20:43     ` Amir Goldstein
2023-09-24 11:31 ` Christian Brauner
2023-09-24 22:44   ` NeilBrown
2023-09-25 10:17     ` Jeff Layton
2023-09-26 12:10       ` Christian Brauner
2023-09-26 12:18     ` Christian Brauner
2023-09-26 12:51       ` Jeff Layton
2023-09-26 14:29         ` Christian Brauner

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=20230922-ctime-v8-3-45f0c236ede1@kernel.org \
    --to=jlayton@kernel.org \
    --cc=Dai.Ngo@oracle.com \
    --cc=brauner@kernel.org \
    --cc=chandan.babu@oracle.com \
    --cc=chuck.lever@oracle.com \
    --cc=david@fromorbit.com \
    --cc=djwong@kernel.org \
    --cc=jack@suse.cz \
    --cc=kent.overstreet@linux.dev \
    --cc=kolga@netapp.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=linux-xfs@vger.kernel.org \
    --cc=neilb@suse.de \
    --cc=tom@talpey.com \
    --cc=torvalds@linux-foundation.org \
    --cc=viro@zeniv.linux.org.uk \
    /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).