Re: xfs_buf_lock vs aio

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Feb 15, 2018 at 11:36:54AM +0200, Avi Kivity wrote:
> On 02/15/2018 01:56 AM, Dave Chinner wrote:
> A little bird whispered in my ear to try XFS_IOC_OPEN_BY_HANDLE to
> avoid the the time update lock, so we'll be trying that next, to
> emulate lazytime.

Biggest problem with that is it requires root permissions. It's not
a solution that can be deployed in practice, so I haven't bothered
suggesting it as something to try.

If you want to try lazytime, an easier test might be to rebuild the
kernel with this change below to support the lazytime mount option
and not log the timestamp updates. This is essentially the mechanism
that I'll use for this, but it will need to grow more stuff to have
the correct lazytime semantics...

Cheers,

Dave.
-- 
Dave Chinner
david@xxxxxxxxxxxxx


---
 fs/xfs/xfs_iops.c  | 27 +++++++++++++++++++++++----
 fs/xfs/xfs_mount.h |  1 +
 fs/xfs/xfs_super.c | 11 ++++++++++-
 3 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 56475fcd76f2..29082707687b 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -1044,6 +1044,19 @@ xfs_vn_setattr(
 	return error;
 }
 
+/*
+ * When lazytime is enabled, we never do transactional timestamp updates.
+ * That means it will only get updated on disk when some other change unrelated
+ * to timestamps is made, and so pure timestamp changes can be lost.
+ *
+ * XXX: ideally we want to set an inode state bit here so that we can track
+ * inodes that are purely timestamp dirty. And inode radix tree bit would be
+ * ideal so we can do background sweeps to log the inodes and get them written
+ * to disk at some (long) interval.
+ *
+ * XXX: lazytime currently turns off iversion support, so is incompatible with
+ * applications that require it (such as the NFS server).
+ */
 STATIC int
 xfs_vn_update_time(
 	struct inode		*inode,
@@ -1053,15 +1066,18 @@ xfs_vn_update_time(
 	struct xfs_inode	*ip = XFS_I(inode);
 	struct xfs_mount	*mp = ip->i_mount;
 	struct xfs_trans	*tp;
+	bool			lazy = (mp->m_flags & XFS_MOUNT_LAZYTIME);
 	int			error;
 
 	trace_xfs_update_time(ip);
 
-	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp);
-	if (error)
-		return error;
+	if (!lazy) {
+		error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp);
+		if (error)
+			return error;
+		xfs_ilock(ip, XFS_ILOCK_EXCL);
+	}
 
-	xfs_ilock(ip, XFS_ILOCK_EXCL);
 	if (flags & S_CTIME)
 		inode->i_ctime = *now;
 	if (flags & S_MTIME)
@@ -1069,6 +1085,9 @@ xfs_vn_update_time(
 	if (flags & S_ATIME)
 		inode->i_atime = *now;
 
+	if (lazy)
+		return 0;
+
 	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
 	xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP);
 	return xfs_trans_commit(tp);
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 75da058c9456..e085e1e92d18 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -217,6 +217,7 @@ typedef struct xfs_mount {
 						   must be synchronous except
 						   for space allocations */
 #define XFS_MOUNT_UNMOUNTING	(1ULL << 1)	/* filesystem is unmounting */
+#define XFS_MOUNT_LAZYTIME	(1ULL << 2)	/* lazily update [acm]times */
 #define XFS_MOUNT_WAS_CLEAN	(1ULL << 3)
 #define XFS_MOUNT_FS_SHUTDOWN	(1ULL << 4)	/* atomic stop of all filesystem
 						   operations, typically for
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 5a248fd1a96b..ae76d558a934 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -83,7 +83,8 @@ enum {
 	Opt_quota, Opt_noquota, Opt_usrquota, Opt_grpquota, Opt_prjquota,
 	Opt_uquota, Opt_gquota, Opt_pquota,
 	Opt_uqnoenforce, Opt_gqnoenforce, Opt_pqnoenforce, Opt_qnoenforce,
-	Opt_discard, Opt_nodiscard, Opt_dax, Opt_err,
+	Opt_discard, Opt_nodiscard, Opt_dax,
+	Opt_err,
 };
 
 static const match_table_t tokens = {
@@ -216,6 +217,8 @@ xfs_parseargs(
 		mp->m_flags |= XFS_MOUNT_DIRSYNC;
 	if (sb->s_flags & SB_SYNCHRONOUS)
 		mp->m_flags |= XFS_MOUNT_WSYNC;
+	if (sb->s_flags & SB_LAZYTIME)
+		mp->m_flags |= XFS_MOUNT_LAZYTIME;
 
 	/*
 	 * Set some default flags that could be cleared by the mount option
@@ -492,6 +495,7 @@ xfs_showargs(
 		{ XFS_MOUNT_DISCARD,		",discard" },
 		{ XFS_MOUNT_SMALL_INUMS,	",inode32" },
 		{ XFS_MOUNT_DAX,		",dax" },
+		{ XFS_MOUNT_LAZYTIME,		",lazytime" },
 		{ 0, NULL }
 	};
 	static struct proc_xfs_info xfs_info_unset[] = {
@@ -1319,6 +1323,11 @@ xfs_fs_remount(
 		}
 	}
 
+	if (*flags & SB_LAZYTIME)
+		mp->m_flags |= XFS_MOUNT_LAZYTIME;
+	else
+		mp->m_flags &= ~XFS_MOUNT_LAZYTIME;
+
 	/* ro -> rw */
 	if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & SB_RDONLY)) {
 		if (mp->m_flags & XFS_MOUNT_NORECOVERY) {
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux