All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/12] lazytime fix and cleanups
@ 2021-01-09  7:58 ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, linux-f2fs-devel, Theodore Ts'o,
	Christoph Hellwig

Hello,

Patch 1 fixes a bug in how __writeback_single_inode() handles lazytime
expirations.  I originally reported this last year
(https://lore.kernel.org/r/20200306004555.GB225345@gmail.com) because it
causes the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl to not work properly, as
the bug causes inodes to remain dirty after a sync.

It also turns out that lazytime on XFS is partially broken because it
doesn't actually write timestamps to disk after a sync() or after
dirtytime_expire_interval.  This is fixed by the same fix.

This supersedes previously proposed fixes, including
https://lore.kernel.org/r/20200307020043.60118-1-tytso@mit.edu and
https://lore.kernel.org/r/20200325122825.1086872-3-hch@lst.de from last
year (which had some issues and didn't fix the XFS bug), and v1 of this
patchset which took a different approach
(https://lore.kernel.org/r/20210105005452.92521-1-ebiggers@kernel.org).

Patches 2-12 then clean up various things related to lazytime and
writeback, such as clarifying the semantics of ->dirty_inode() and the
inode dirty flags, and improving comments.  Most of these patches could
be applied independently if needed.

This patchset applies to v5.11-rc2.

Changed since v1:
  - Switched to the fix suggested by Jan Kara, and dropped the
    patches which introduced ->lazytime_expired().
  - Fixed bugs in the fat and ext4 patches.
  - Added patch "fs: improve comments for writeback_single_inode()".
  - Reordered the patches a bit.
  - Added Reviewed-by's.

Eric Biggers (12):
  fs: fix lazytime expiration handling in __writeback_single_inode()
  fs: correctly document the inode dirty flags
  fs: only specify I_DIRTY_TIME when needed in generic_update_time()
  fat: only specify I_DIRTY_TIME when needed in fat_update_time()
  fs: don't call ->dirty_inode for lazytime timestamp updates
  fs: pass only I_DIRTY_INODE flags to ->dirty_inode
  fs: clean up __mark_inode_dirty() a bit
  fs: drop redundant check from __writeback_single_inode()
  fs: improve comments for writeback_single_inode()
  gfs2: don't worry about I_DIRTY_TIME in gfs2_fsync()
  ext4: simplify i_state checks in __ext4_update_other_inode_time()
  xfs: remove a stale comment from xfs_file_aio_write_checks()

 Documentation/filesystems/vfs.rst |   5 +-
 fs/ext4/inode.c                   |  20 +----
 fs/f2fs/super.c                   |   3 -
 fs/fat/misc.c                     |  23 +++---
 fs/fs-writeback.c                 | 132 +++++++++++++++++-------------
 fs/gfs2/file.c                    |   4 +-
 fs/gfs2/super.c                   |   2 -
 fs/inode.c                        |  38 +++++----
 fs/xfs/xfs_file.c                 |   6 --
 include/linux/fs.h                |  18 ++--
 10 files changed, 132 insertions(+), 119 deletions(-)


base-commit: e71ba9452f0b5b2e8dc8aa5445198cd9214a6a62
-- 
2.30.0


^ permalink raw reply	[flat|nested] 82+ messages in thread

* [f2fs-dev] [PATCH v2 00/12] lazytime fix and cleanups
@ 2021-01-09  7:58 ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, Theodore Ts'o, Christoph Hellwig,
	linux-f2fs-devel

Hello,

Patch 1 fixes a bug in how __writeback_single_inode() handles lazytime
expirations.  I originally reported this last year
(https://lore.kernel.org/r/20200306004555.GB225345@gmail.com) because it
causes the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl to not work properly, as
the bug causes inodes to remain dirty after a sync.

It also turns out that lazytime on XFS is partially broken because it
doesn't actually write timestamps to disk after a sync() or after
dirtytime_expire_interval.  This is fixed by the same fix.

This supersedes previously proposed fixes, including
https://lore.kernel.org/r/20200307020043.60118-1-tytso@mit.edu and
https://lore.kernel.org/r/20200325122825.1086872-3-hch@lst.de from last
year (which had some issues and didn't fix the XFS bug), and v1 of this
patchset which took a different approach
(https://lore.kernel.org/r/20210105005452.92521-1-ebiggers@kernel.org).

Patches 2-12 then clean up various things related to lazytime and
writeback, such as clarifying the semantics of ->dirty_inode() and the
inode dirty flags, and improving comments.  Most of these patches could
be applied independently if needed.

This patchset applies to v5.11-rc2.

Changed since v1:
  - Switched to the fix suggested by Jan Kara, and dropped the
    patches which introduced ->lazytime_expired().
  - Fixed bugs in the fat and ext4 patches.
  - Added patch "fs: improve comments for writeback_single_inode()".
  - Reordered the patches a bit.
  - Added Reviewed-by's.

Eric Biggers (12):
  fs: fix lazytime expiration handling in __writeback_single_inode()
  fs: correctly document the inode dirty flags
  fs: only specify I_DIRTY_TIME when needed in generic_update_time()
  fat: only specify I_DIRTY_TIME when needed in fat_update_time()
  fs: don't call ->dirty_inode for lazytime timestamp updates
  fs: pass only I_DIRTY_INODE flags to ->dirty_inode
  fs: clean up __mark_inode_dirty() a bit
  fs: drop redundant check from __writeback_single_inode()
  fs: improve comments for writeback_single_inode()
  gfs2: don't worry about I_DIRTY_TIME in gfs2_fsync()
  ext4: simplify i_state checks in __ext4_update_other_inode_time()
  xfs: remove a stale comment from xfs_file_aio_write_checks()

 Documentation/filesystems/vfs.rst |   5 +-
 fs/ext4/inode.c                   |  20 +----
 fs/f2fs/super.c                   |   3 -
 fs/fat/misc.c                     |  23 +++---
 fs/fs-writeback.c                 | 132 +++++++++++++++++-------------
 fs/gfs2/file.c                    |   4 +-
 fs/gfs2/super.c                   |   2 -
 fs/inode.c                        |  38 +++++----
 fs/xfs/xfs_file.c                 |   6 --
 include/linux/fs.h                |  18 ++--
 10 files changed, 132 insertions(+), 119 deletions(-)


base-commit: e71ba9452f0b5b2e8dc8aa5445198cd9214a6a62
-- 
2.30.0



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* [PATCH v2 01/12] fs: fix lazytime expiration handling in __writeback_single_inode()
  2021-01-09  7:58 ` [f2fs-dev] " Eric Biggers
@ 2021-01-09  7:58   ` Eric Biggers
  -1 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, linux-f2fs-devel, Theodore Ts'o,
	Christoph Hellwig, stable, Jan Kara

From: Eric Biggers <ebiggers@google.com>

When lazytime is enabled and an inode is being written due to its
in-memory updated timestamps having expired, either due to a sync() or
syncfs() system call or due to dirtytime_expire_interval having elapsed,
the VFS needs to inform the filesystem so that the filesystem can copy
the inode's timestamps out to the on-disk data structures.

This is done by __writeback_single_inode() calling
mark_inode_dirty_sync(), which then calls ->dirty_inode(I_DIRTY_SYNC).

However, this occurs after __writeback_single_inode() has already
cleared the dirty flags from ->i_state.  This causes two bugs:

- mark_inode_dirty_sync() redirties the inode, causing it to remain
  dirty.  This wastefully causes the inode to be written twice.  But
  more importantly, it breaks cases where sync_filesystem() is expected
  to clean dirty inodes.  This includes the FS_IOC_REMOVE_ENCRYPTION_KEY
  ioctl (as reported at
  https://lore.kernel.org/r/20200306004555.GB225345@gmail.com), as well
  as possibly filesystem freezing (freeze_super()).

- Since ->i_state doesn't contain I_DIRTY_TIME when ->dirty_inode() is
  called from __writeback_single_inode() for lazytime expiration,
  xfs_fs_dirty_inode() ignores the notification.  (XFS only cares about
  lazytime expirations, and it assumes that I_DIRTY_TIME will contain
  i_state during those.)  Therefore, lazy timestamps aren't persisted by
  sync(), syncfs(), or dirtytime_expire_interval on XFS.

Fix this by moving the call to mark_inode_dirty_sync() to earlier in
__writeback_single_inode(), before the dirty flags are cleared from
i_state.  This makes filesystems be properly notified of the timestamp
expiration, and it avoids incorrectly redirtying the inode.

This fixes xfstest generic/580 (which tests
FS_IOC_REMOVE_ENCRYPTION_KEY) when run on ext4 or f2fs with lazytime
enabled.  It also fixes the new lazytime xfstest I've proposed, which
reproduces the above-mentioned XFS bug
(https://lore.kernel.org/r/20210105005818.92978-1-ebiggers@kernel.org).

Alternatively, we could call ->dirty_inode(I_DIRTY_SYNC) directly.  But
due to the introduction of I_SYNC_QUEUED, mark_inode_dirty_sync() is the
right thing to do because mark_inode_dirty_sync() now knows not to move
the inode to a writeback list if it is currently queued for sync.

Fixes: 0ae45f63d4ef ("vfs: add support for a lazytime mount option")
Cc: stable@vger.kernel.org
Depends-on: 5afced3bf281 ("writeback: Avoid skipping inode writeback")
Suggested-by: Jan Kara <jack@suse.cz>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/fs-writeback.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index acfb55834af23..c41cb887eb7d3 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1474,21 +1474,25 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 	}
 
 	/*
-	 * Some filesystems may redirty the inode during the writeback
-	 * due to delalloc, clear dirty metadata flags right before
-	 * write_inode()
+	 * If the inode has dirty timestamps and we need to write them, call
+	 * mark_inode_dirty_sync() to notify the filesystem about it and to
+	 * change I_DIRTY_TIME into I_DIRTY_SYNC.
 	 */
-	spin_lock(&inode->i_lock);
-
-	dirty = inode->i_state & I_DIRTY;
 	if ((inode->i_state & I_DIRTY_TIME) &&
-	    ((dirty & I_DIRTY_INODE) ||
-	     wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
+	    (wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
 	     time_after(jiffies, inode->dirtied_time_when +
 			dirtytime_expire_interval * HZ))) {
-		dirty |= I_DIRTY_TIME;
 		trace_writeback_lazytime(inode);
+		mark_inode_dirty_sync(inode);
 	}
+
+	/*
+	 * Some filesystems may redirty the inode during the writeback
+	 * due to delalloc, clear dirty metadata flags right before
+	 * write_inode()
+	 */
+	spin_lock(&inode->i_lock);
+	dirty = inode->i_state & I_DIRTY;
 	inode->i_state &= ~dirty;
 
 	/*
@@ -1509,8 +1513,6 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 
 	spin_unlock(&inode->i_lock);
 
-	if (dirty & I_DIRTY_TIME)
-		mark_inode_dirty_sync(inode);
 	/* Don't write the inode if only I_DIRTY_PAGES was set */
 	if (dirty & ~I_DIRTY_PAGES) {
 		int err = write_inode(inode, wbc);
-- 
2.30.0


^ permalink raw reply	[flat|nested] 82+ messages in thread

* [f2fs-dev] [PATCH v2 01/12] fs: fix lazytime expiration handling in __writeback_single_inode()
@ 2021-01-09  7:58   ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: Theodore Ts'o, stable, linux-f2fs-devel, linux-xfs, Jan Kara,
	linux-ext4, Christoph Hellwig

From: Eric Biggers <ebiggers@google.com>

When lazytime is enabled and an inode is being written due to its
in-memory updated timestamps having expired, either due to a sync() or
syncfs() system call or due to dirtytime_expire_interval having elapsed,
the VFS needs to inform the filesystem so that the filesystem can copy
the inode's timestamps out to the on-disk data structures.

This is done by __writeback_single_inode() calling
mark_inode_dirty_sync(), which then calls ->dirty_inode(I_DIRTY_SYNC).

However, this occurs after __writeback_single_inode() has already
cleared the dirty flags from ->i_state.  This causes two bugs:

- mark_inode_dirty_sync() redirties the inode, causing it to remain
  dirty.  This wastefully causes the inode to be written twice.  But
  more importantly, it breaks cases where sync_filesystem() is expected
  to clean dirty inodes.  This includes the FS_IOC_REMOVE_ENCRYPTION_KEY
  ioctl (as reported at
  https://lore.kernel.org/r/20200306004555.GB225345@gmail.com), as well
  as possibly filesystem freezing (freeze_super()).

- Since ->i_state doesn't contain I_DIRTY_TIME when ->dirty_inode() is
  called from __writeback_single_inode() for lazytime expiration,
  xfs_fs_dirty_inode() ignores the notification.  (XFS only cares about
  lazytime expirations, and it assumes that I_DIRTY_TIME will contain
  i_state during those.)  Therefore, lazy timestamps aren't persisted by
  sync(), syncfs(), or dirtytime_expire_interval on XFS.

Fix this by moving the call to mark_inode_dirty_sync() to earlier in
__writeback_single_inode(), before the dirty flags are cleared from
i_state.  This makes filesystems be properly notified of the timestamp
expiration, and it avoids incorrectly redirtying the inode.

This fixes xfstest generic/580 (which tests
FS_IOC_REMOVE_ENCRYPTION_KEY) when run on ext4 or f2fs with lazytime
enabled.  It also fixes the new lazytime xfstest I've proposed, which
reproduces the above-mentioned XFS bug
(https://lore.kernel.org/r/20210105005818.92978-1-ebiggers@kernel.org).

Alternatively, we could call ->dirty_inode(I_DIRTY_SYNC) directly.  But
due to the introduction of I_SYNC_QUEUED, mark_inode_dirty_sync() is the
right thing to do because mark_inode_dirty_sync() now knows not to move
the inode to a writeback list if it is currently queued for sync.

Fixes: 0ae45f63d4ef ("vfs: add support for a lazytime mount option")
Cc: stable@vger.kernel.org
Depends-on: 5afced3bf281 ("writeback: Avoid skipping inode writeback")
Suggested-by: Jan Kara <jack@suse.cz>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/fs-writeback.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index acfb55834af23..c41cb887eb7d3 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1474,21 +1474,25 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 	}
 
 	/*
-	 * Some filesystems may redirty the inode during the writeback
-	 * due to delalloc, clear dirty metadata flags right before
-	 * write_inode()
+	 * If the inode has dirty timestamps and we need to write them, call
+	 * mark_inode_dirty_sync() to notify the filesystem about it and to
+	 * change I_DIRTY_TIME into I_DIRTY_SYNC.
 	 */
-	spin_lock(&inode->i_lock);
-
-	dirty = inode->i_state & I_DIRTY;
 	if ((inode->i_state & I_DIRTY_TIME) &&
-	    ((dirty & I_DIRTY_INODE) ||
-	     wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
+	    (wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
 	     time_after(jiffies, inode->dirtied_time_when +
 			dirtytime_expire_interval * HZ))) {
-		dirty |= I_DIRTY_TIME;
 		trace_writeback_lazytime(inode);
+		mark_inode_dirty_sync(inode);
 	}
+
+	/*
+	 * Some filesystems may redirty the inode during the writeback
+	 * due to delalloc, clear dirty metadata flags right before
+	 * write_inode()
+	 */
+	spin_lock(&inode->i_lock);
+	dirty = inode->i_state & I_DIRTY;
 	inode->i_state &= ~dirty;
 
 	/*
@@ -1509,8 +1513,6 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 
 	spin_unlock(&inode->i_lock);
 
-	if (dirty & I_DIRTY_TIME)
-		mark_inode_dirty_sync(inode);
 	/* Don't write the inode if only I_DIRTY_PAGES was set */
 	if (dirty & ~I_DIRTY_PAGES) {
 		int err = write_inode(inode, wbc);
-- 
2.30.0



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* [PATCH v2 02/12] fs: correctly document the inode dirty flags
  2021-01-09  7:58 ` [f2fs-dev] " Eric Biggers
@ 2021-01-09  7:58   ` Eric Biggers
  -1 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, linux-f2fs-devel, Theodore Ts'o,
	Christoph Hellwig

From: Eric Biggers <ebiggers@google.com>

The documentation for I_DIRTY_SYNC and I_DIRTY_DATASYNC is a bit
misleading, and I_DIRTY_TIME isn't documented at all.  Fix this.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 include/linux/fs.h | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index fd47deea7c176..45a0303b2aeb6 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2084,8 +2084,8 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
 /*
  * Inode state bits.  Protected by inode->i_lock
  *
- * Three bits determine the dirty state of the inode, I_DIRTY_SYNC,
- * I_DIRTY_DATASYNC and I_DIRTY_PAGES.
+ * Four bits determine the dirty state of the inode: I_DIRTY_SYNC,
+ * I_DIRTY_DATASYNC, I_DIRTY_PAGES, and I_DIRTY_TIME.
  *
  * Four bits define the lifetime of an inode.  Initially, inodes are I_NEW,
  * until that flag is cleared.  I_WILL_FREE, I_FREEING and I_CLEAR are set at
@@ -2094,12 +2094,20 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
  * Two bits are used for locking and completion notification, I_NEW and I_SYNC.
  *
  * I_DIRTY_SYNC		Inode is dirty, but doesn't have to be written on
- *			fdatasync().  i_atime is the usual cause.
- * I_DIRTY_DATASYNC	Data-related inode changes pending. We keep track of
+ *			fdatasync() (unless I_DIRTY_DATASYNC is also set).
+ *			Timestamp updates are the usual cause.
+ * I_DIRTY_DATASYNC	Data-related inode changes pending.  We keep track of
  *			these changes separately from I_DIRTY_SYNC so that we
  *			don't have to write inode on fdatasync() when only
- *			mtime has changed in it.
+ *			e.g. the timestamps have changed.
  * I_DIRTY_PAGES	Inode has dirty pages.  Inode itself may be clean.
+ * I_DIRTY_TIME		The inode itself only has dirty timestamps, and the
+ *			lazytime mount option is enabled.  We keep track of this
+ *			separately from I_DIRTY_SYNC in order to implement
+ *			lazytime.  This gets cleared if I_DIRTY_INODE
+ *			(I_DIRTY_SYNC and/or I_DIRTY_DATASYNC) gets set.  I.e.
+ *			either I_DIRTY_TIME *or* I_DIRTY_INODE can be set in
+ *			i_state, but not both.  I_DIRTY_PAGES may still be set.
  * I_NEW		Serves as both a mutex and completion notification.
  *			New inodes set I_NEW.  If two processes both create
  *			the same inode, one of them will release its inode and
-- 
2.30.0


^ permalink raw reply	[flat|nested] 82+ messages in thread

* [f2fs-dev] [PATCH v2 02/12] fs: correctly document the inode dirty flags
@ 2021-01-09  7:58   ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, Theodore Ts'o, Christoph Hellwig,
	linux-f2fs-devel

From: Eric Biggers <ebiggers@google.com>

The documentation for I_DIRTY_SYNC and I_DIRTY_DATASYNC is a bit
misleading, and I_DIRTY_TIME isn't documented at all.  Fix this.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 include/linux/fs.h | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index fd47deea7c176..45a0303b2aeb6 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2084,8 +2084,8 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
 /*
  * Inode state bits.  Protected by inode->i_lock
  *
- * Three bits determine the dirty state of the inode, I_DIRTY_SYNC,
- * I_DIRTY_DATASYNC and I_DIRTY_PAGES.
+ * Four bits determine the dirty state of the inode: I_DIRTY_SYNC,
+ * I_DIRTY_DATASYNC, I_DIRTY_PAGES, and I_DIRTY_TIME.
  *
  * Four bits define the lifetime of an inode.  Initially, inodes are I_NEW,
  * until that flag is cleared.  I_WILL_FREE, I_FREEING and I_CLEAR are set at
@@ -2094,12 +2094,20 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
  * Two bits are used for locking and completion notification, I_NEW and I_SYNC.
  *
  * I_DIRTY_SYNC		Inode is dirty, but doesn't have to be written on
- *			fdatasync().  i_atime is the usual cause.
- * I_DIRTY_DATASYNC	Data-related inode changes pending. We keep track of
+ *			fdatasync() (unless I_DIRTY_DATASYNC is also set).
+ *			Timestamp updates are the usual cause.
+ * I_DIRTY_DATASYNC	Data-related inode changes pending.  We keep track of
  *			these changes separately from I_DIRTY_SYNC so that we
  *			don't have to write inode on fdatasync() when only
- *			mtime has changed in it.
+ *			e.g. the timestamps have changed.
  * I_DIRTY_PAGES	Inode has dirty pages.  Inode itself may be clean.
+ * I_DIRTY_TIME		The inode itself only has dirty timestamps, and the
+ *			lazytime mount option is enabled.  We keep track of this
+ *			separately from I_DIRTY_SYNC in order to implement
+ *			lazytime.  This gets cleared if I_DIRTY_INODE
+ *			(I_DIRTY_SYNC and/or I_DIRTY_DATASYNC) gets set.  I.e.
+ *			either I_DIRTY_TIME *or* I_DIRTY_INODE can be set in
+ *			i_state, but not both.  I_DIRTY_PAGES may still be set.
  * I_NEW		Serves as both a mutex and completion notification.
  *			New inodes set I_NEW.  If two processes both create
  *			the same inode, one of them will release its inode and
-- 
2.30.0



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* [PATCH v2 03/12] fs: only specify I_DIRTY_TIME when needed in generic_update_time()
  2021-01-09  7:58 ` [f2fs-dev] " Eric Biggers
@ 2021-01-09  7:58   ` Eric Biggers
  -1 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, linux-f2fs-devel, Theodore Ts'o,
	Christoph Hellwig

From: Eric Biggers <ebiggers@google.com>

generic_update_time() always passes I_DIRTY_TIME to
__mark_inode_dirty(), which doesn't really make sense because (a)
generic_update_time() might be asked to do only an i_version update, not
also a timestamps update; and (b) I_DIRTY_TIME is only supposed to be
set in i_state if the filesystem has lazytime enabled, so using it
unconditionally in generic_update_time() is inconsistent.

As a result there is a weird edge case where if only an i_version update
was requested (not also a timestamps update) but it is no longer needed
(i.e. inode_maybe_inc_iversion() returns false), then I_DIRTY_TIME will
be set in i_state even if the filesystem isn't mounted with lazytime.

Fix this by only passing I_DIRTY_TIME to __mark_inode_dirty() if the
timestamps were updated and the filesystem has lazytime enabled.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/inode.c | 38 ++++++++++++++++++++------------------
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/fs/inode.c b/fs/inode.c
index 6442d97d9a4ab..d0fa43d8e9d5c 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1743,24 +1743,26 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
 
 int generic_update_time(struct inode *inode, struct timespec64 *time, int flags)
 {
-	int iflags = I_DIRTY_TIME;
-	bool dirty = false;
-
-	if (flags & S_ATIME)
-		inode->i_atime = *time;
-	if (flags & S_VERSION)
-		dirty = inode_maybe_inc_iversion(inode, false);
-	if (flags & S_CTIME)
-		inode->i_ctime = *time;
-	if (flags & S_MTIME)
-		inode->i_mtime = *time;
-	if ((flags & (S_ATIME | S_CTIME | S_MTIME)) &&
-	    !(inode->i_sb->s_flags & SB_LAZYTIME))
-		dirty = true;
-
-	if (dirty)
-		iflags |= I_DIRTY_SYNC;
-	__mark_inode_dirty(inode, iflags);
+	int dirty_flags = 0;
+
+	if (flags & (S_ATIME | S_CTIME | S_MTIME)) {
+		if (flags & S_ATIME)
+			inode->i_atime = *time;
+		if (flags & S_CTIME)
+			inode->i_ctime = *time;
+		if (flags & S_MTIME)
+			inode->i_mtime = *time;
+
+		if (inode->i_sb->s_flags & SB_LAZYTIME)
+			dirty_flags |= I_DIRTY_TIME;
+		else
+			dirty_flags |= I_DIRTY_SYNC;
+	}
+
+	if ((flags & S_VERSION) && inode_maybe_inc_iversion(inode, false))
+		dirty_flags |= I_DIRTY_SYNC;
+
+	__mark_inode_dirty(inode, dirty_flags);
 	return 0;
 }
 EXPORT_SYMBOL(generic_update_time);
-- 
2.30.0


^ permalink raw reply	[flat|nested] 82+ messages in thread

* [f2fs-dev] [PATCH v2 03/12] fs: only specify I_DIRTY_TIME when needed in generic_update_time()
@ 2021-01-09  7:58   ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, Theodore Ts'o, Christoph Hellwig,
	linux-f2fs-devel

From: Eric Biggers <ebiggers@google.com>

generic_update_time() always passes I_DIRTY_TIME to
__mark_inode_dirty(), which doesn't really make sense because (a)
generic_update_time() might be asked to do only an i_version update, not
also a timestamps update; and (b) I_DIRTY_TIME is only supposed to be
set in i_state if the filesystem has lazytime enabled, so using it
unconditionally in generic_update_time() is inconsistent.

As a result there is a weird edge case where if only an i_version update
was requested (not also a timestamps update) but it is no longer needed
(i.e. inode_maybe_inc_iversion() returns false), then I_DIRTY_TIME will
be set in i_state even if the filesystem isn't mounted with lazytime.

Fix this by only passing I_DIRTY_TIME to __mark_inode_dirty() if the
timestamps were updated and the filesystem has lazytime enabled.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/inode.c | 38 ++++++++++++++++++++------------------
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/fs/inode.c b/fs/inode.c
index 6442d97d9a4ab..d0fa43d8e9d5c 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1743,24 +1743,26 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
 
 int generic_update_time(struct inode *inode, struct timespec64 *time, int flags)
 {
-	int iflags = I_DIRTY_TIME;
-	bool dirty = false;
-
-	if (flags & S_ATIME)
-		inode->i_atime = *time;
-	if (flags & S_VERSION)
-		dirty = inode_maybe_inc_iversion(inode, false);
-	if (flags & S_CTIME)
-		inode->i_ctime = *time;
-	if (flags & S_MTIME)
-		inode->i_mtime = *time;
-	if ((flags & (S_ATIME | S_CTIME | S_MTIME)) &&
-	    !(inode->i_sb->s_flags & SB_LAZYTIME))
-		dirty = true;
-
-	if (dirty)
-		iflags |= I_DIRTY_SYNC;
-	__mark_inode_dirty(inode, iflags);
+	int dirty_flags = 0;
+
+	if (flags & (S_ATIME | S_CTIME | S_MTIME)) {
+		if (flags & S_ATIME)
+			inode->i_atime = *time;
+		if (flags & S_CTIME)
+			inode->i_ctime = *time;
+		if (flags & S_MTIME)
+			inode->i_mtime = *time;
+
+		if (inode->i_sb->s_flags & SB_LAZYTIME)
+			dirty_flags |= I_DIRTY_TIME;
+		else
+			dirty_flags |= I_DIRTY_SYNC;
+	}
+
+	if ((flags & S_VERSION) && inode_maybe_inc_iversion(inode, false))
+		dirty_flags |= I_DIRTY_SYNC;
+
+	__mark_inode_dirty(inode, dirty_flags);
 	return 0;
 }
 EXPORT_SYMBOL(generic_update_time);
-- 
2.30.0



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* [PATCH v2 04/12] fat: only specify I_DIRTY_TIME when needed in fat_update_time()
  2021-01-09  7:58 ` [f2fs-dev] " Eric Biggers
@ 2021-01-09  7:58   ` Eric Biggers
  -1 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, linux-f2fs-devel, Theodore Ts'o,
	Christoph Hellwig

From: Eric Biggers <ebiggers@google.com>

As was done for generic_update_time(), only pass I_DIRTY_TIME to
__mark_inode_dirty() when the inode's timestamps were actually updated
and lazytime is enabled.  This avoids a weird edge case where
I_DIRTY_TIME could be set in i_state when lazytime isn't enabled.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/fat/misc.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/fs/fat/misc.c b/fs/fat/misc.c
index f1b2a1fc2a6a4..18a50a46b57f8 100644
--- a/fs/fat/misc.c
+++ b/fs/fat/misc.c
@@ -329,22 +329,23 @@ EXPORT_SYMBOL_GPL(fat_truncate_time);
 
 int fat_update_time(struct inode *inode, struct timespec64 *now, int flags)
 {
-	int iflags = I_DIRTY_TIME;
-	bool dirty = false;
+	int dirty_flags = 0;
 
 	if (inode->i_ino == MSDOS_ROOT_INO)
 		return 0;
 
-	fat_truncate_time(inode, now, flags);
-	if (flags & S_VERSION)
-		dirty = inode_maybe_inc_iversion(inode, false);
-	if ((flags & (S_ATIME | S_CTIME | S_MTIME)) &&
-	    !(inode->i_sb->s_flags & SB_LAZYTIME))
-		dirty = true;
+	if (flags & (S_ATIME | S_CTIME | S_MTIME)) {
+		fat_truncate_time(inode, now, flags);
+		if (inode->i_sb->s_flags & SB_LAZYTIME)
+			dirty_flags |= I_DIRTY_TIME;
+		else
+			dirty_flags |= I_DIRTY_SYNC;
+	}
+
+	if ((flags & S_VERSION) && inode_maybe_inc_iversion(inode, false))
+		dirty_flags |= I_DIRTY_SYNC;
 
-	if (dirty)
-		iflags |= I_DIRTY_SYNC;
-	__mark_inode_dirty(inode, iflags);
+	__mark_inode_dirty(inode, dirty_flags);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(fat_update_time);
-- 
2.30.0


^ permalink raw reply	[flat|nested] 82+ messages in thread

* [f2fs-dev] [PATCH v2 04/12] fat: only specify I_DIRTY_TIME when needed in fat_update_time()
@ 2021-01-09  7:58   ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, Theodore Ts'o, Christoph Hellwig,
	linux-f2fs-devel

From: Eric Biggers <ebiggers@google.com>

As was done for generic_update_time(), only pass I_DIRTY_TIME to
__mark_inode_dirty() when the inode's timestamps were actually updated
and lazytime is enabled.  This avoids a weird edge case where
I_DIRTY_TIME could be set in i_state when lazytime isn't enabled.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/fat/misc.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/fs/fat/misc.c b/fs/fat/misc.c
index f1b2a1fc2a6a4..18a50a46b57f8 100644
--- a/fs/fat/misc.c
+++ b/fs/fat/misc.c
@@ -329,22 +329,23 @@ EXPORT_SYMBOL_GPL(fat_truncate_time);
 
 int fat_update_time(struct inode *inode, struct timespec64 *now, int flags)
 {
-	int iflags = I_DIRTY_TIME;
-	bool dirty = false;
+	int dirty_flags = 0;
 
 	if (inode->i_ino == MSDOS_ROOT_INO)
 		return 0;
 
-	fat_truncate_time(inode, now, flags);
-	if (flags & S_VERSION)
-		dirty = inode_maybe_inc_iversion(inode, false);
-	if ((flags & (S_ATIME | S_CTIME | S_MTIME)) &&
-	    !(inode->i_sb->s_flags & SB_LAZYTIME))
-		dirty = true;
+	if (flags & (S_ATIME | S_CTIME | S_MTIME)) {
+		fat_truncate_time(inode, now, flags);
+		if (inode->i_sb->s_flags & SB_LAZYTIME)
+			dirty_flags |= I_DIRTY_TIME;
+		else
+			dirty_flags |= I_DIRTY_SYNC;
+	}
+
+	if ((flags & S_VERSION) && inode_maybe_inc_iversion(inode, false))
+		dirty_flags |= I_DIRTY_SYNC;
 
-	if (dirty)
-		iflags |= I_DIRTY_SYNC;
-	__mark_inode_dirty(inode, iflags);
+	__mark_inode_dirty(inode, dirty_flags);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(fat_update_time);
-- 
2.30.0



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* [PATCH v2 05/12] fs: don't call ->dirty_inode for lazytime timestamp updates
  2021-01-09  7:58 ` [f2fs-dev] " Eric Biggers
@ 2021-01-09  7:58   ` Eric Biggers
  -1 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, linux-f2fs-devel, Theodore Ts'o,
	Christoph Hellwig

From: Eric Biggers <ebiggers@google.com>

There is no need to call ->dirty_inode for lazytime timestamp updates
(i.e. for __mark_inode_dirty(I_DIRTY_TIME)), since by the definition of
lazytime, filesystems must ignore these updates.  Filesystems only need
to care about the updated timestamps when they expire.

Therefore, only call ->dirty_inode when I_DIRTY_INODE is set.

Based on a patch from Christoph Hellwig:
https://lore.kernel.org/r/20200325122825.1086872-4-hch@lst.de

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/ext4/inode.c   | 12 +-----------
 fs/f2fs/super.c   |  3 ---
 fs/fs-writeback.c |  6 +++---
 fs/gfs2/super.c   |  2 --
 4 files changed, 4 insertions(+), 19 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 27946882d4ce4..4cc6c7834312f 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5933,26 +5933,16 @@ int __ext4_mark_inode_dirty(handle_t *handle, struct inode *inode,
  * If the inode is marked synchronous, we don't honour that here - doing
  * so would cause a commit on atime updates, which we don't bother doing.
  * We handle synchronous inodes at the highest possible level.
- *
- * If only the I_DIRTY_TIME flag is set, we can skip everything.  If
- * I_DIRTY_TIME and I_DIRTY_SYNC is set, the only inode fields we need
- * to copy into the on-disk inode structure are the timestamp files.
  */
 void ext4_dirty_inode(struct inode *inode, int flags)
 {
 	handle_t *handle;
 
-	if (flags == I_DIRTY_TIME)
-		return;
 	handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
 	if (IS_ERR(handle))
-		goto out;
-
+		return;
 	ext4_mark_inode_dirty(handle, inode);
-
 	ext4_journal_stop(handle);
-out:
-	return;
 }
 
 int ext4_change_inode_journal_flag(struct inode *inode, int val)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index b4a07fe62d1a5..cc98dc49f4a26 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1196,9 +1196,6 @@ static void f2fs_dirty_inode(struct inode *inode, int flags)
 			inode->i_ino == F2FS_META_INO(sbi))
 		return;
 
-	if (flags == I_DIRTY_TIME)
-		return;
-
 	if (is_inode_flag_set(inode, FI_AUTO_RECOVER))
 		clear_inode_flag(inode, FI_AUTO_RECOVER);
 
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index c41cb887eb7d3..b7616bbd55336 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -2255,16 +2255,16 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 	 * Don't do this for I_DIRTY_PAGES - that doesn't actually
 	 * dirty the inode itself
 	 */
-	if (flags & (I_DIRTY_INODE | I_DIRTY_TIME)) {
+	if (flags & I_DIRTY_INODE) {
 		trace_writeback_dirty_inode_start(inode, flags);
 
 		if (sb->s_op->dirty_inode)
 			sb->s_op->dirty_inode(inode, flags);
 
 		trace_writeback_dirty_inode(inode, flags);
-	}
-	if (flags & I_DIRTY_INODE)
+
 		flags &= ~I_DIRTY_TIME;
+	}
 	dirtytime = flags & I_DIRTY_TIME;
 
 	/*
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 2f56acc41c049..042b94288ff11 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -562,8 +562,6 @@ static void gfs2_dirty_inode(struct inode *inode, int flags)
 	int need_endtrans = 0;
 	int ret;
 
-	if (!(flags & I_DIRTY_INODE))
-		return;
 	if (unlikely(gfs2_withdrawn(sdp)))
 		return;
 	if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
-- 
2.30.0


^ permalink raw reply	[flat|nested] 82+ messages in thread

* [f2fs-dev] [PATCH v2 05/12] fs: don't call ->dirty_inode for lazytime timestamp updates
@ 2021-01-09  7:58   ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, Theodore Ts'o, Christoph Hellwig,
	linux-f2fs-devel

From: Eric Biggers <ebiggers@google.com>

There is no need to call ->dirty_inode for lazytime timestamp updates
(i.e. for __mark_inode_dirty(I_DIRTY_TIME)), since by the definition of
lazytime, filesystems must ignore these updates.  Filesystems only need
to care about the updated timestamps when they expire.

Therefore, only call ->dirty_inode when I_DIRTY_INODE is set.

Based on a patch from Christoph Hellwig:
https://lore.kernel.org/r/20200325122825.1086872-4-hch@lst.de

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/ext4/inode.c   | 12 +-----------
 fs/f2fs/super.c   |  3 ---
 fs/fs-writeback.c |  6 +++---
 fs/gfs2/super.c   |  2 --
 4 files changed, 4 insertions(+), 19 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 27946882d4ce4..4cc6c7834312f 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5933,26 +5933,16 @@ int __ext4_mark_inode_dirty(handle_t *handle, struct inode *inode,
  * If the inode is marked synchronous, we don't honour that here - doing
  * so would cause a commit on atime updates, which we don't bother doing.
  * We handle synchronous inodes at the highest possible level.
- *
- * If only the I_DIRTY_TIME flag is set, we can skip everything.  If
- * I_DIRTY_TIME and I_DIRTY_SYNC is set, the only inode fields we need
- * to copy into the on-disk inode structure are the timestamp files.
  */
 void ext4_dirty_inode(struct inode *inode, int flags)
 {
 	handle_t *handle;
 
-	if (flags == I_DIRTY_TIME)
-		return;
 	handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
 	if (IS_ERR(handle))
-		goto out;
-
+		return;
 	ext4_mark_inode_dirty(handle, inode);
-
 	ext4_journal_stop(handle);
-out:
-	return;
 }
 
 int ext4_change_inode_journal_flag(struct inode *inode, int val)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index b4a07fe62d1a5..cc98dc49f4a26 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1196,9 +1196,6 @@ static void f2fs_dirty_inode(struct inode *inode, int flags)
 			inode->i_ino == F2FS_META_INO(sbi))
 		return;
 
-	if (flags == I_DIRTY_TIME)
-		return;
-
 	if (is_inode_flag_set(inode, FI_AUTO_RECOVER))
 		clear_inode_flag(inode, FI_AUTO_RECOVER);
 
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index c41cb887eb7d3..b7616bbd55336 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -2255,16 +2255,16 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 	 * Don't do this for I_DIRTY_PAGES - that doesn't actually
 	 * dirty the inode itself
 	 */
-	if (flags & (I_DIRTY_INODE | I_DIRTY_TIME)) {
+	if (flags & I_DIRTY_INODE) {
 		trace_writeback_dirty_inode_start(inode, flags);
 
 		if (sb->s_op->dirty_inode)
 			sb->s_op->dirty_inode(inode, flags);
 
 		trace_writeback_dirty_inode(inode, flags);
-	}
-	if (flags & I_DIRTY_INODE)
+
 		flags &= ~I_DIRTY_TIME;
+	}
 	dirtytime = flags & I_DIRTY_TIME;
 
 	/*
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 2f56acc41c049..042b94288ff11 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -562,8 +562,6 @@ static void gfs2_dirty_inode(struct inode *inode, int flags)
 	int need_endtrans = 0;
 	int ret;
 
-	if (!(flags & I_DIRTY_INODE))
-		return;
 	if (unlikely(gfs2_withdrawn(sdp)))
 		return;
 	if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
-- 
2.30.0



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* [PATCH v2 06/12] fs: pass only I_DIRTY_INODE flags to ->dirty_inode
  2021-01-09  7:58 ` [f2fs-dev] " Eric Biggers
@ 2021-01-09  7:58   ` Eric Biggers
  -1 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, linux-f2fs-devel, Theodore Ts'o,
	Christoph Hellwig

From: Eric Biggers <ebiggers@google.com>

->dirty_inode is now only called when I_DIRTY_INODE (I_DIRTY_SYNC and/or
I_DIRTY_DATASYNC) is set.  However it may still be passed other dirty
flags at the same time, provided that these other flags happened to be
passed to __mark_inode_dirty() at the same time as I_DIRTY_INODE.

This doesn't make sense because there is no reason for filesystems to
care about these extra flags.  Nor are filesystems notified about all
updates to these other flags.

Therefore, mask the flags before passing them to ->dirty_inode.

Also properly document ->dirty_inode in vfs.rst.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 Documentation/filesystems/vfs.rst | 5 ++++-
 fs/fs-writeback.c                 | 2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
index ca52c82e5bb54..287b80948a40b 100644
--- a/Documentation/filesystems/vfs.rst
+++ b/Documentation/filesystems/vfs.rst
@@ -270,7 +270,10 @@ or bottom half).
 	->alloc_inode.
 
 ``dirty_inode``
-	this method is called by the VFS to mark an inode dirty.
+	this method is called by the VFS when an inode is marked dirty.
+	This is specifically for the inode itself being marked dirty,
+	not its data.  If the update needs to be persisted by fdatasync(),
+	then I_DIRTY_DATASYNC will be set in the flags argument.
 
 ``write_inode``
 	this method is called when the VFS needs to write an inode to
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index b7616bbd55336..2e6064012f7d3 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -2259,7 +2259,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 		trace_writeback_dirty_inode_start(inode, flags);
 
 		if (sb->s_op->dirty_inode)
-			sb->s_op->dirty_inode(inode, flags);
+			sb->s_op->dirty_inode(inode, flags & I_DIRTY_INODE);
 
 		trace_writeback_dirty_inode(inode, flags);
 
-- 
2.30.0


^ permalink raw reply	[flat|nested] 82+ messages in thread

* [f2fs-dev] [PATCH v2 06/12] fs: pass only I_DIRTY_INODE flags to ->dirty_inode
@ 2021-01-09  7:58   ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, Theodore Ts'o, Christoph Hellwig,
	linux-f2fs-devel

From: Eric Biggers <ebiggers@google.com>

->dirty_inode is now only called when I_DIRTY_INODE (I_DIRTY_SYNC and/or
I_DIRTY_DATASYNC) is set.  However it may still be passed other dirty
flags at the same time, provided that these other flags happened to be
passed to __mark_inode_dirty() at the same time as I_DIRTY_INODE.

This doesn't make sense because there is no reason for filesystems to
care about these extra flags.  Nor are filesystems notified about all
updates to these other flags.

Therefore, mask the flags before passing them to ->dirty_inode.

Also properly document ->dirty_inode in vfs.rst.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 Documentation/filesystems/vfs.rst | 5 ++++-
 fs/fs-writeback.c                 | 2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
index ca52c82e5bb54..287b80948a40b 100644
--- a/Documentation/filesystems/vfs.rst
+++ b/Documentation/filesystems/vfs.rst
@@ -270,7 +270,10 @@ or bottom half).
 	->alloc_inode.
 
 ``dirty_inode``
-	this method is called by the VFS to mark an inode dirty.
+	this method is called by the VFS when an inode is marked dirty.
+	This is specifically for the inode itself being marked dirty,
+	not its data.  If the update needs to be persisted by fdatasync(),
+	then I_DIRTY_DATASYNC will be set in the flags argument.
 
 ``write_inode``
 	this method is called when the VFS needs to write an inode to
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index b7616bbd55336..2e6064012f7d3 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -2259,7 +2259,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 		trace_writeback_dirty_inode_start(inode, flags);
 
 		if (sb->s_op->dirty_inode)
-			sb->s_op->dirty_inode(inode, flags);
+			sb->s_op->dirty_inode(inode, flags & I_DIRTY_INODE);
 
 		trace_writeback_dirty_inode(inode, flags);
 
-- 
2.30.0



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* [PATCH v2 07/12] fs: clean up __mark_inode_dirty() a bit
  2021-01-09  7:58 ` [f2fs-dev] " Eric Biggers
@ 2021-01-09  7:58   ` Eric Biggers
  -1 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, linux-f2fs-devel, Theodore Ts'o,
	Christoph Hellwig

From: Eric Biggers <ebiggers@google.com>

Improve some comments, and don't bother checking for the I_DIRTY_TIME
flag in the case where we just cleared it.

Also, warn if I_DIRTY_TIME and I_DIRTY_PAGES are passed to
__mark_inode_dirty() at the same time, as this case isn't handled.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/fs-writeback.c | 49 +++++++++++++++++++++++++++++------------------
 1 file changed, 30 insertions(+), 19 deletions(-)

diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 2e6064012f7d3..80ee9816d9df5 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -2219,23 +2219,24 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode)
 }
 
 /**
- * __mark_inode_dirty -	internal function
+ * __mark_inode_dirty -	internal function to mark an inode dirty
  *
  * @inode: inode to mark
- * @flags: what kind of dirty (i.e. I_DIRTY_SYNC)
+ * @flags: what kind of dirty, e.g. I_DIRTY_SYNC.  This can be a combination of
+ *	   multiple I_DIRTY_* flags, except that I_DIRTY_TIME can't be combined
+ *	   with I_DIRTY_PAGES.
  *
- * Mark an inode as dirty. Callers should use mark_inode_dirty or
- * mark_inode_dirty_sync.
+ * Mark an inode as dirty.  We notify the filesystem, then update the inode's
+ * dirty flags.  Then, if needed we add the inode to the appropriate dirty list.
  *
- * Put the inode on the super block's dirty list.
+ * Most callers should use mark_inode_dirty() or mark_inode_dirty_sync()
+ * instead of calling this directly.
  *
- * CAREFUL! We mark it dirty unconditionally, but move it onto the
- * dirty list only if it is hashed or if it refers to a blockdev.
- * If it was not hashed, it will never be added to the dirty list
- * even if it is later hashed, as it will have been marked dirty already.
+ * CAREFUL!  We only add the inode to the dirty list if it is hashed or if it
+ * refers to a blockdev.  Unhashed inodes will never be added to the dirty list
+ * even if they are later hashed, as they will have been marked dirty already.
  *
- * In short, make sure you hash any inodes _before_ you start marking
- * them dirty.
+ * In short, ensure you hash any inodes _before_ you start marking them dirty.
  *
  * Note that for blockdevs, inode->dirtied_when represents the dirtying time of
  * the block-special inode (/dev/hda1) itself.  And the ->dirtied_when field of
@@ -2247,25 +2248,34 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode)
 void __mark_inode_dirty(struct inode *inode, int flags)
 {
 	struct super_block *sb = inode->i_sb;
-	int dirtytime;
+	int dirtytime = 0;
 
 	trace_writeback_mark_inode_dirty(inode, flags);
 
-	/*
-	 * Don't do this for I_DIRTY_PAGES - that doesn't actually
-	 * dirty the inode itself
-	 */
 	if (flags & I_DIRTY_INODE) {
+		/*
+		 * Notify the filesystem about the inode being dirtied, so that
+		 * (if needed) it can update on-disk fields and journal the
+		 * inode.  This is only needed when the inode itself is being
+		 * dirtied now.  I.e. it's only needed for I_DIRTY_INODE, not
+		 * for just I_DIRTY_PAGES or I_DIRTY_TIME.
+		 */
 		trace_writeback_dirty_inode_start(inode, flags);
-
 		if (sb->s_op->dirty_inode)
 			sb->s_op->dirty_inode(inode, flags & I_DIRTY_INODE);
-
 		trace_writeback_dirty_inode(inode, flags);
 
+		/* I_DIRTY_INODE supersedes I_DIRTY_TIME. */
 		flags &= ~I_DIRTY_TIME;
+	} else {
+		/*
+		 * Else it's either I_DIRTY_PAGES, I_DIRTY_TIME, or nothing.
+		 * (We don't support setting both I_DIRTY_PAGES and I_DIRTY_TIME
+		 * in one call to __mark_inode_dirty().)
+		 */
+		dirtytime = flags & I_DIRTY_TIME;
+		WARN_ON_ONCE(dirtytime && flags != I_DIRTY_TIME);
 	}
-	dirtytime = flags & I_DIRTY_TIME;
 
 	/*
 	 * Paired with smp_mb() in __writeback_single_inode() for the
@@ -2288,6 +2298,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 
 		inode_attach_wb(inode, NULL);
 
+		/* I_DIRTY_INODE supersedes I_DIRTY_TIME. */
 		if (flags & I_DIRTY_INODE)
 			inode->i_state &= ~I_DIRTY_TIME;
 		inode->i_state |= flags;
-- 
2.30.0


^ permalink raw reply	[flat|nested] 82+ messages in thread

* [f2fs-dev] [PATCH v2 07/12] fs: clean up __mark_inode_dirty() a bit
@ 2021-01-09  7:58   ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, Theodore Ts'o, Christoph Hellwig,
	linux-f2fs-devel

From: Eric Biggers <ebiggers@google.com>

Improve some comments, and don't bother checking for the I_DIRTY_TIME
flag in the case where we just cleared it.

Also, warn if I_DIRTY_TIME and I_DIRTY_PAGES are passed to
__mark_inode_dirty() at the same time, as this case isn't handled.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/fs-writeback.c | 49 +++++++++++++++++++++++++++++------------------
 1 file changed, 30 insertions(+), 19 deletions(-)

diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 2e6064012f7d3..80ee9816d9df5 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -2219,23 +2219,24 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode)
 }
 
 /**
- * __mark_inode_dirty -	internal function
+ * __mark_inode_dirty -	internal function to mark an inode dirty
  *
  * @inode: inode to mark
- * @flags: what kind of dirty (i.e. I_DIRTY_SYNC)
+ * @flags: what kind of dirty, e.g. I_DIRTY_SYNC.  This can be a combination of
+ *	   multiple I_DIRTY_* flags, except that I_DIRTY_TIME can't be combined
+ *	   with I_DIRTY_PAGES.
  *
- * Mark an inode as dirty. Callers should use mark_inode_dirty or
- * mark_inode_dirty_sync.
+ * Mark an inode as dirty.  We notify the filesystem, then update the inode's
+ * dirty flags.  Then, if needed we add the inode to the appropriate dirty list.
  *
- * Put the inode on the super block's dirty list.
+ * Most callers should use mark_inode_dirty() or mark_inode_dirty_sync()
+ * instead of calling this directly.
  *
- * CAREFUL! We mark it dirty unconditionally, but move it onto the
- * dirty list only if it is hashed or if it refers to a blockdev.
- * If it was not hashed, it will never be added to the dirty list
- * even if it is later hashed, as it will have been marked dirty already.
+ * CAREFUL!  We only add the inode to the dirty list if it is hashed or if it
+ * refers to a blockdev.  Unhashed inodes will never be added to the dirty list
+ * even if they are later hashed, as they will have been marked dirty already.
  *
- * In short, make sure you hash any inodes _before_ you start marking
- * them dirty.
+ * In short, ensure you hash any inodes _before_ you start marking them dirty.
  *
  * Note that for blockdevs, inode->dirtied_when represents the dirtying time of
  * the block-special inode (/dev/hda1) itself.  And the ->dirtied_when field of
@@ -2247,25 +2248,34 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode)
 void __mark_inode_dirty(struct inode *inode, int flags)
 {
 	struct super_block *sb = inode->i_sb;
-	int dirtytime;
+	int dirtytime = 0;
 
 	trace_writeback_mark_inode_dirty(inode, flags);
 
-	/*
-	 * Don't do this for I_DIRTY_PAGES - that doesn't actually
-	 * dirty the inode itself
-	 */
 	if (flags & I_DIRTY_INODE) {
+		/*
+		 * Notify the filesystem about the inode being dirtied, so that
+		 * (if needed) it can update on-disk fields and journal the
+		 * inode.  This is only needed when the inode itself is being
+		 * dirtied now.  I.e. it's only needed for I_DIRTY_INODE, not
+		 * for just I_DIRTY_PAGES or I_DIRTY_TIME.
+		 */
 		trace_writeback_dirty_inode_start(inode, flags);
-
 		if (sb->s_op->dirty_inode)
 			sb->s_op->dirty_inode(inode, flags & I_DIRTY_INODE);
-
 		trace_writeback_dirty_inode(inode, flags);
 
+		/* I_DIRTY_INODE supersedes I_DIRTY_TIME. */
 		flags &= ~I_DIRTY_TIME;
+	} else {
+		/*
+		 * Else it's either I_DIRTY_PAGES, I_DIRTY_TIME, or nothing.
+		 * (We don't support setting both I_DIRTY_PAGES and I_DIRTY_TIME
+		 * in one call to __mark_inode_dirty().)
+		 */
+		dirtytime = flags & I_DIRTY_TIME;
+		WARN_ON_ONCE(dirtytime && flags != I_DIRTY_TIME);
 	}
-	dirtytime = flags & I_DIRTY_TIME;
 
 	/*
 	 * Paired with smp_mb() in __writeback_single_inode() for the
@@ -2288,6 +2298,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
 
 		inode_attach_wb(inode, NULL);
 
+		/* I_DIRTY_INODE supersedes I_DIRTY_TIME. */
 		if (flags & I_DIRTY_INODE)
 			inode->i_state &= ~I_DIRTY_TIME;
 		inode->i_state |= flags;
-- 
2.30.0



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* [PATCH v2 08/12] fs: drop redundant check from __writeback_single_inode()
  2021-01-09  7:58 ` [f2fs-dev] " Eric Biggers
@ 2021-01-09  7:58   ` Eric Biggers
  -1 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, linux-f2fs-devel, Theodore Ts'o,
	Christoph Hellwig

From: Eric Biggers <ebiggers@google.com>

wbc->for_sync implies wbc->sync_mode == WB_SYNC_ALL, so there's no need
to check for both.  Just check for WB_SYNC_ALL.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/fs-writeback.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 80ee9816d9df5..cee1df6e3bd43 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1479,7 +1479,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 	 * change I_DIRTY_TIME into I_DIRTY_SYNC.
 	 */
 	if ((inode->i_state & I_DIRTY_TIME) &&
-	    (wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
+	    (wbc->sync_mode == WB_SYNC_ALL ||
 	     time_after(jiffies, inode->dirtied_time_when +
 			dirtytime_expire_interval * HZ))) {
 		trace_writeback_lazytime(inode);
-- 
2.30.0


^ permalink raw reply	[flat|nested] 82+ messages in thread

* [f2fs-dev] [PATCH v2 08/12] fs: drop redundant check from __writeback_single_inode()
@ 2021-01-09  7:58   ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:58 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, Theodore Ts'o, Christoph Hellwig,
	linux-f2fs-devel

From: Eric Biggers <ebiggers@google.com>

wbc->for_sync implies wbc->sync_mode == WB_SYNC_ALL, so there's no need
to check for both.  Just check for WB_SYNC_ALL.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/fs-writeback.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 80ee9816d9df5..cee1df6e3bd43 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1479,7 +1479,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 	 * change I_DIRTY_TIME into I_DIRTY_SYNC.
 	 */
 	if ((inode->i_state & I_DIRTY_TIME) &&
-	    (wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
+	    (wbc->sync_mode == WB_SYNC_ALL ||
 	     time_after(jiffies, inode->dirtied_time_when +
 			dirtytime_expire_interval * HZ))) {
 		trace_writeback_lazytime(inode);
-- 
2.30.0



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* [PATCH v2 09/12] fs: improve comments for writeback_single_inode()
  2021-01-09  7:58 ` [f2fs-dev] " Eric Biggers
@ 2021-01-09  7:59   ` Eric Biggers
  -1 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:59 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, linux-f2fs-devel, Theodore Ts'o,
	Christoph Hellwig

From: Eric Biggers <ebiggers@google.com>

Some comments for writeback_single_inode() and
__writeback_single_inode() are outdated or not very helpful, especially
with regards to writeback list handling.  Update them.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/fs-writeback.c | 57 +++++++++++++++++++++++++++--------------------
 1 file changed, 33 insertions(+), 24 deletions(-)

diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index cee1df6e3bd43..e91980f493884 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1442,9 +1442,15 @@ static void requeue_inode(struct inode *inode, struct bdi_writeback *wb,
 }
 
 /*
- * Write out an inode and its dirty pages. Do not update the writeback list
- * linkage. That is left to the caller. The caller is also responsible for
- * setting I_SYNC flag and calling inode_sync_complete() to clear it.
+ * Write out an inode and its dirty pages (or some of its dirty pages, depending
+ * on @wbc->nr_to_write), and clear the relevant dirty flags from i_state.
+ *
+ * This doesn't remove the inode from the writeback list it is on, except
+ * potentially to move it from b_dirty_time to b_dirty due to timestamp
+ * expiration.  The caller is otherwise responsible for writeback list handling.
+ *
+ * The caller is also responsible for setting the I_SYNC flag beforehand and
+ * calling inode_sync_complete() to clear it afterwards.
  */
 static int
 __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
@@ -1487,9 +1493,10 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 	}
 
 	/*
-	 * Some filesystems may redirty the inode during the writeback
-	 * due to delalloc, clear dirty metadata flags right before
-	 * write_inode()
+	 * Get and clear the dirty flags from i_state.  This needs to be done
+	 * after calling writepages because some filesystems may redirty the
+	 * inode during writepages due to delalloc.  It also needs to be done
+	 * after handling timestamp expiration, as that may dirty the inode too.
 	 */
 	spin_lock(&inode->i_lock);
 	dirty = inode->i_state & I_DIRTY;
@@ -1524,12 +1531,13 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 }
 
 /*
- * Write out an inode's dirty pages. Either the caller has an active reference
- * on the inode or the inode has I_WILL_FREE set.
+ * Write out an inode's dirty data and metadata on-demand, i.e. separately from
+ * the regular batched writeback done by the flusher threads in
+ * writeback_sb_inodes().  @wbc controls various aspects of the write, such as
+ * whether it is a data-integrity sync (%WB_SYNC_ALL) or not (%WB_SYNC_NONE).
  *
- * This function is designed to be called for writing back one inode which
- * we go e.g. from filesystem. Flusher thread uses __writeback_single_inode()
- * and does more profound writeback list handling in writeback_sb_inodes().
+ * To prevent the inode from going away, either the caller must have a reference
+ * to the inode, or the inode must have I_WILL_FREE or I_FREEING set.
  */
 static int writeback_single_inode(struct inode *inode,
 				  struct writeback_control *wbc)
@@ -1544,23 +1552,23 @@ static int writeback_single_inode(struct inode *inode,
 		WARN_ON(inode->i_state & I_WILL_FREE);
 
 	if (inode->i_state & I_SYNC) {
-		if (wbc->sync_mode != WB_SYNC_ALL)
-			goto out;
 		/*
-		 * It's a data-integrity sync. We must wait. Since callers hold
-		 * inode reference or inode has I_WILL_FREE set, it cannot go
-		 * away under us.
+		 * Writeback is already running on the inode.  For WB_SYNC_NONE,
+		 * that's enough and we can just return.  For WB_SYNC_ALL, we
+		 * must wait for the existing writeback to complete, then do
+		 * writeback again if there's anything left.
 		 */
+		if (wbc->sync_mode != WB_SYNC_ALL)
+			goto out;
 		__inode_wait_for_writeback(inode);
 	}
 	WARN_ON(inode->i_state & I_SYNC);
 	/*
-	 * Skip inode if it is clean and we have no outstanding writeback in
-	 * WB_SYNC_ALL mode. We don't want to mess with writeback lists in this
-	 * function since flusher thread may be doing for example sync in
-	 * parallel and if we move the inode, it could get skipped. So here we
-	 * make sure inode is on some writeback list and leave it there unless
-	 * we have completely cleaned the inode.
+	 * If the inode is already fully clean, then there's nothing to do.
+	 *
+	 * For data-integrity syncs we also need to check whether any pages are
+	 * still under writeback, e.g. due to prior WB_SYNC_NONE writeback.  If
+	 * there are any such pages, we'll need to wait for them.
 	 */
 	if (!(inode->i_state & I_DIRTY_ALL) &&
 	    (wbc->sync_mode != WB_SYNC_ALL ||
@@ -1576,8 +1584,9 @@ static int writeback_single_inode(struct inode *inode,
 	wb = inode_to_wb_and_lock_list(inode);
 	spin_lock(&inode->i_lock);
 	/*
-	 * If inode is clean, remove it from writeback lists. Otherwise don't
-	 * touch it. See comment above for explanation.
+	 * If the inode is now fully clean, then it can be safely removed from
+	 * its writeback list (if any).  Otherwise the flusher threads are
+	 * responsible for the writeback lists.
 	 */
 	if (!(inode->i_state & I_DIRTY_ALL))
 		inode_io_list_del_locked(inode, wb);
-- 
2.30.0


^ permalink raw reply	[flat|nested] 82+ messages in thread

* [f2fs-dev] [PATCH v2 09/12] fs: improve comments for writeback_single_inode()
@ 2021-01-09  7:59   ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:59 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, Theodore Ts'o, Christoph Hellwig,
	linux-f2fs-devel

From: Eric Biggers <ebiggers@google.com>

Some comments for writeback_single_inode() and
__writeback_single_inode() are outdated or not very helpful, especially
with regards to writeback list handling.  Update them.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/fs-writeback.c | 57 +++++++++++++++++++++++++++--------------------
 1 file changed, 33 insertions(+), 24 deletions(-)

diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index cee1df6e3bd43..e91980f493884 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1442,9 +1442,15 @@ static void requeue_inode(struct inode *inode, struct bdi_writeback *wb,
 }
 
 /*
- * Write out an inode and its dirty pages. Do not update the writeback list
- * linkage. That is left to the caller. The caller is also responsible for
- * setting I_SYNC flag and calling inode_sync_complete() to clear it.
+ * Write out an inode and its dirty pages (or some of its dirty pages, depending
+ * on @wbc->nr_to_write), and clear the relevant dirty flags from i_state.
+ *
+ * This doesn't remove the inode from the writeback list it is on, except
+ * potentially to move it from b_dirty_time to b_dirty due to timestamp
+ * expiration.  The caller is otherwise responsible for writeback list handling.
+ *
+ * The caller is also responsible for setting the I_SYNC flag beforehand and
+ * calling inode_sync_complete() to clear it afterwards.
  */
 static int
 __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
@@ -1487,9 +1493,10 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 	}
 
 	/*
-	 * Some filesystems may redirty the inode during the writeback
-	 * due to delalloc, clear dirty metadata flags right before
-	 * write_inode()
+	 * Get and clear the dirty flags from i_state.  This needs to be done
+	 * after calling writepages because some filesystems may redirty the
+	 * inode during writepages due to delalloc.  It also needs to be done
+	 * after handling timestamp expiration, as that may dirty the inode too.
 	 */
 	spin_lock(&inode->i_lock);
 	dirty = inode->i_state & I_DIRTY;
@@ -1524,12 +1531,13 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 }
 
 /*
- * Write out an inode's dirty pages. Either the caller has an active reference
- * on the inode or the inode has I_WILL_FREE set.
+ * Write out an inode's dirty data and metadata on-demand, i.e. separately from
+ * the regular batched writeback done by the flusher threads in
+ * writeback_sb_inodes().  @wbc controls various aspects of the write, such as
+ * whether it is a data-integrity sync (%WB_SYNC_ALL) or not (%WB_SYNC_NONE).
  *
- * This function is designed to be called for writing back one inode which
- * we go e.g. from filesystem. Flusher thread uses __writeback_single_inode()
- * and does more profound writeback list handling in writeback_sb_inodes().
+ * To prevent the inode from going away, either the caller must have a reference
+ * to the inode, or the inode must have I_WILL_FREE or I_FREEING set.
  */
 static int writeback_single_inode(struct inode *inode,
 				  struct writeback_control *wbc)
@@ -1544,23 +1552,23 @@ static int writeback_single_inode(struct inode *inode,
 		WARN_ON(inode->i_state & I_WILL_FREE);
 
 	if (inode->i_state & I_SYNC) {
-		if (wbc->sync_mode != WB_SYNC_ALL)
-			goto out;
 		/*
-		 * It's a data-integrity sync. We must wait. Since callers hold
-		 * inode reference or inode has I_WILL_FREE set, it cannot go
-		 * away under us.
+		 * Writeback is already running on the inode.  For WB_SYNC_NONE,
+		 * that's enough and we can just return.  For WB_SYNC_ALL, we
+		 * must wait for the existing writeback to complete, then do
+		 * writeback again if there's anything left.
 		 */
+		if (wbc->sync_mode != WB_SYNC_ALL)
+			goto out;
 		__inode_wait_for_writeback(inode);
 	}
 	WARN_ON(inode->i_state & I_SYNC);
 	/*
-	 * Skip inode if it is clean and we have no outstanding writeback in
-	 * WB_SYNC_ALL mode. We don't want to mess with writeback lists in this
-	 * function since flusher thread may be doing for example sync in
-	 * parallel and if we move the inode, it could get skipped. So here we
-	 * make sure inode is on some writeback list and leave it there unless
-	 * we have completely cleaned the inode.
+	 * If the inode is already fully clean, then there's nothing to do.
+	 *
+	 * For data-integrity syncs we also need to check whether any pages are
+	 * still under writeback, e.g. due to prior WB_SYNC_NONE writeback.  If
+	 * there are any such pages, we'll need to wait for them.
 	 */
 	if (!(inode->i_state & I_DIRTY_ALL) &&
 	    (wbc->sync_mode != WB_SYNC_ALL ||
@@ -1576,8 +1584,9 @@ static int writeback_single_inode(struct inode *inode,
 	wb = inode_to_wb_and_lock_list(inode);
 	spin_lock(&inode->i_lock);
 	/*
-	 * If inode is clean, remove it from writeback lists. Otherwise don't
-	 * touch it. See comment above for explanation.
+	 * If the inode is now fully clean, then it can be safely removed from
+	 * its writeback list (if any).  Otherwise the flusher threads are
+	 * responsible for the writeback lists.
 	 */
 	if (!(inode->i_state & I_DIRTY_ALL))
 		inode_io_list_del_locked(inode, wb);
-- 
2.30.0



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* [PATCH v2 10/12] gfs2: don't worry about I_DIRTY_TIME in gfs2_fsync()
  2021-01-09  7:58 ` [f2fs-dev] " Eric Biggers
@ 2021-01-09  7:59   ` Eric Biggers
  -1 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:59 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, linux-f2fs-devel, Theodore Ts'o,
	Christoph Hellwig

From: Eric Biggers <ebiggers@google.com>

The I_DIRTY_TIME flag is primary used within the VFS, and there's no
reason for ->fsync() implementations to do anything with it.  This is
because when !datasync, the VFS will expire dirty timestamps before
calling ->fsync().  (See vfs_fsync_range().)  This turns I_DIRTY_TIME
into I_DIRTY_SYNC.

Therefore, change gfs2_fsync() to not check for I_DIRTY_TIME.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/gfs2/file.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index b39b339feddc9..7fe2497755a37 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -749,7 +749,7 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
 {
 	struct address_space *mapping = file->f_mapping;
 	struct inode *inode = mapping->host;
-	int sync_state = inode->i_state & I_DIRTY_ALL;
+	int sync_state = inode->i_state & I_DIRTY;
 	struct gfs2_inode *ip = GFS2_I(inode);
 	int ret = 0, ret1 = 0;
 
@@ -762,7 +762,7 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
 	if (!gfs2_is_jdata(ip))
 		sync_state &= ~I_DIRTY_PAGES;
 	if (datasync)
-		sync_state &= ~(I_DIRTY_SYNC | I_DIRTY_TIME);
+		sync_state &= ~I_DIRTY_SYNC;
 
 	if (sync_state) {
 		ret = sync_inode_metadata(inode, 1);
-- 
2.30.0


^ permalink raw reply	[flat|nested] 82+ messages in thread

* [f2fs-dev] [PATCH v2 10/12] gfs2: don't worry about I_DIRTY_TIME in gfs2_fsync()
@ 2021-01-09  7:59   ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:59 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, Theodore Ts'o, Christoph Hellwig,
	linux-f2fs-devel

From: Eric Biggers <ebiggers@google.com>

The I_DIRTY_TIME flag is primary used within the VFS, and there's no
reason for ->fsync() implementations to do anything with it.  This is
because when !datasync, the VFS will expire dirty timestamps before
calling ->fsync().  (See vfs_fsync_range().)  This turns I_DIRTY_TIME
into I_DIRTY_SYNC.

Therefore, change gfs2_fsync() to not check for I_DIRTY_TIME.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/gfs2/file.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index b39b339feddc9..7fe2497755a37 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -749,7 +749,7 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
 {
 	struct address_space *mapping = file->f_mapping;
 	struct inode *inode = mapping->host;
-	int sync_state = inode->i_state & I_DIRTY_ALL;
+	int sync_state = inode->i_state & I_DIRTY;
 	struct gfs2_inode *ip = GFS2_I(inode);
 	int ret = 0, ret1 = 0;
 
@@ -762,7 +762,7 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
 	if (!gfs2_is_jdata(ip))
 		sync_state &= ~I_DIRTY_PAGES;
 	if (datasync)
-		sync_state &= ~(I_DIRTY_SYNC | I_DIRTY_TIME);
+		sync_state &= ~I_DIRTY_SYNC;
 
 	if (sync_state) {
 		ret = sync_inode_metadata(inode, 1);
-- 
2.30.0



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* [PATCH v2 11/12] ext4: simplify i_state checks in __ext4_update_other_inode_time()
  2021-01-09  7:58 ` [f2fs-dev] " Eric Biggers
@ 2021-01-09  7:59   ` Eric Biggers
  -1 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:59 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, linux-f2fs-devel, Theodore Ts'o,
	Christoph Hellwig

From: Eric Biggers <ebiggers@google.com>

Since I_DIRTY_TIME and I_DIRTY_INODE are mutually exclusive in i_state,
there's no need to check for I_DIRTY_TIME && !I_DIRTY_INODE.  Just check
for I_DIRTY_TIME.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/ext4/inode.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 4cc6c7834312f..00bca5c18eb65 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4962,14 +4962,12 @@ static void __ext4_update_other_inode_time(struct super_block *sb,
 		return;
 
 	if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
-			       I_DIRTY_INODE)) ||
-	    ((inode->i_state & I_DIRTY_TIME) == 0))
+			       I_DIRTY_TIME)) != I_DIRTY_TIME)
 		return;
 
 	spin_lock(&inode->i_lock);
-	if (((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
-				I_DIRTY_INODE)) == 0) &&
-	    (inode->i_state & I_DIRTY_TIME)) {
+	if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
+			       I_DIRTY_TIME)) == I_DIRTY_TIME) {
 		struct ext4_inode_info	*ei = EXT4_I(inode);
 
 		inode->i_state &= ~I_DIRTY_TIME;
-- 
2.30.0


^ permalink raw reply	[flat|nested] 82+ messages in thread

* [f2fs-dev] [PATCH v2 11/12] ext4: simplify i_state checks in __ext4_update_other_inode_time()
@ 2021-01-09  7:59   ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:59 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, Theodore Ts'o, Christoph Hellwig,
	linux-f2fs-devel

From: Eric Biggers <ebiggers@google.com>

Since I_DIRTY_TIME and I_DIRTY_INODE are mutually exclusive in i_state,
there's no need to check for I_DIRTY_TIME && !I_DIRTY_INODE.  Just check
for I_DIRTY_TIME.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/ext4/inode.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 4cc6c7834312f..00bca5c18eb65 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4962,14 +4962,12 @@ static void __ext4_update_other_inode_time(struct super_block *sb,
 		return;
 
 	if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
-			       I_DIRTY_INODE)) ||
-	    ((inode->i_state & I_DIRTY_TIME) == 0))
+			       I_DIRTY_TIME)) != I_DIRTY_TIME)
 		return;
 
 	spin_lock(&inode->i_lock);
-	if (((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
-				I_DIRTY_INODE)) == 0) &&
-	    (inode->i_state & I_DIRTY_TIME)) {
+	if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
+			       I_DIRTY_TIME)) == I_DIRTY_TIME) {
 		struct ext4_inode_info	*ei = EXT4_I(inode);
 
 		inode->i_state &= ~I_DIRTY_TIME;
-- 
2.30.0



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* [PATCH v2 12/12] xfs: remove a stale comment from xfs_file_aio_write_checks()
  2021-01-09  7:58 ` [f2fs-dev] " Eric Biggers
@ 2021-01-09  7:59   ` Eric Biggers
  -1 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:59 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, linux-f2fs-devel, Theodore Ts'o,
	Christoph Hellwig

From: Eric Biggers <ebiggers@google.com>

The comment in xfs_file_aio_write_checks() about calling file_modified()
after dropping the ilock doesn't make sense, because the code that
unconditionally acquires and drops the ilock was removed by
commit 467f78992a07 ("xfs: reduce ilock hold times in
xfs_file_aio_write_checks").

Remove this outdated comment.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/xfs/xfs_file.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 5b0f93f738372..4927c6653f15d 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -389,12 +389,6 @@ xfs_file_aio_write_checks(
 	} else
 		spin_unlock(&ip->i_flags_lock);
 
-	/*
-	 * Updating the timestamps will grab the ilock again from
-	 * xfs_fs_dirty_inode, so we have to call it after dropping the
-	 * lock above.  Eventually we should look into a way to avoid
-	 * the pointless lock roundtrip.
-	 */
 	return file_modified(file);
 }
 
-- 
2.30.0


^ permalink raw reply	[flat|nested] 82+ messages in thread

* [f2fs-dev] [PATCH v2 12/12] xfs: remove a stale comment from xfs_file_aio_write_checks()
@ 2021-01-09  7:59   ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-09  7:59 UTC (permalink / raw)
  To: linux-fsdevel
  Cc: linux-xfs, linux-ext4, Theodore Ts'o, Christoph Hellwig,
	linux-f2fs-devel

From: Eric Biggers <ebiggers@google.com>

The comment in xfs_file_aio_write_checks() about calling file_modified()
after dropping the ilock doesn't make sense, because the code that
unconditionally acquires and drops the ilock was removed by
commit 467f78992a07 ("xfs: reduce ilock hold times in
xfs_file_aio_write_checks").

Remove this outdated comment.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/xfs/xfs_file.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 5b0f93f738372..4927c6653f15d 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -389,12 +389,6 @@ xfs_file_aio_write_checks(
 	} else
 		spin_unlock(&ip->i_flags_lock);
 
-	/*
-	 * Updating the timestamps will grab the ilock again from
-	 * xfs_fs_dirty_inode, so we have to call it after dropping the
-	 * lock above.  Eventually we should look into a way to avoid
-	 * the pointless lock roundtrip.
-	 */
 	return file_modified(file);
 }
 
-- 
2.30.0



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 01/12] fs: fix lazytime expiration handling in __writeback_single_inode()
  2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 10:48     ` Christoph Hellwig
  -1 siblings, 0 replies; 82+ messages in thread
From: Christoph Hellwig @ 2021-01-11 10:48 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig, stable, Jan Kara

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 01/12] fs: fix lazytime expiration handling in __writeback_single_inode()
@ 2021-01-11 10:48     ` Christoph Hellwig
  0 siblings, 0 replies; 82+ messages in thread
From: Christoph Hellwig @ 2021-01-11 10:48 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, stable, linux-f2fs-devel, linux-xfs,
	linux-fsdevel, Jan Kara, linux-ext4, Christoph Hellwig

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 04/12] fat: only specify I_DIRTY_TIME when needed in fat_update_time()
  2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 10:52     ` Christoph Hellwig
  -1 siblings, 0 replies; 82+ messages in thread
From: Christoph Hellwig @ 2021-01-11 10:52 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

On Fri, Jan 08, 2021 at 11:58:55PM -0800, Eric Biggers wrote:
> +	if ((flags & S_VERSION) && inode_maybe_inc_iversion(inode, false))
> +		dirty_flags |= I_DIRTY_SYNC;

fat does not support i_version updates, so this bit can be skipped.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 04/12] fat: only specify I_DIRTY_TIME when needed in fat_update_time()
@ 2021-01-11 10:52     ` Christoph Hellwig
  0 siblings, 0 replies; 82+ messages in thread
From: Christoph Hellwig @ 2021-01-11 10:52 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Fri, Jan 08, 2021 at 11:58:55PM -0800, Eric Biggers wrote:
> +	if ((flags & S_VERSION) && inode_maybe_inc_iversion(inode, false))
> +		dirty_flags |= I_DIRTY_SYNC;

fat does not support i_version updates, so this bit can be skipped.


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 08/12] fs: drop redundant check from __writeback_single_inode()
  2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 10:52     ` Christoph Hellwig
  -1 siblings, 0 replies; 82+ messages in thread
From: Christoph Hellwig @ 2021-01-11 10:52 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

On Fri, Jan 08, 2021 at 11:58:59PM -0800, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> wbc->for_sync implies wbc->sync_mode == WB_SYNC_ALL, so there's no need
> to check for both.  Just check for WB_SYNC_ALL.
> 
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 08/12] fs: drop redundant check from __writeback_single_inode()
@ 2021-01-11 10:52     ` Christoph Hellwig
  0 siblings, 0 replies; 82+ messages in thread
From: Christoph Hellwig @ 2021-01-11 10:52 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Fri, Jan 08, 2021 at 11:58:59PM -0800, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> wbc->for_sync implies wbc->sync_mode == WB_SYNC_ALL, so there's no need
> to check for both.  Just check for WB_SYNC_ALL.
> 
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 09/12] fs: improve comments for writeback_single_inode()
  2021-01-09  7:59   ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 10:53     ` Christoph Hellwig
  -1 siblings, 0 replies; 82+ messages in thread
From: Christoph Hellwig @ 2021-01-11 10:53 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 09/12] fs: improve comments for writeback_single_inode()
@ 2021-01-11 10:53     ` Christoph Hellwig
  0 siblings, 0 replies; 82+ messages in thread
From: Christoph Hellwig @ 2021-01-11 10:53 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 11/12] ext4: simplify i_state checks in __ext4_update_other_inode_time()
  2021-01-09  7:59   ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 10:53     ` Christoph Hellwig
  -1 siblings, 0 replies; 82+ messages in thread
From: Christoph Hellwig @ 2021-01-11 10:53 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

On Fri, Jan 08, 2021 at 11:59:02PM -0800, Eric Biggers wrote:
>  	if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> -			       I_DIRTY_INODE)) ||
> -	    ((inode->i_state & I_DIRTY_TIME) == 0))
> +			       I_DIRTY_TIME)) != I_DIRTY_TIME)
>  		return;
>  
>  	spin_lock(&inode->i_lock);
> -	if (((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> -				I_DIRTY_INODE)) == 0) &&
> -	    (inode->i_state & I_DIRTY_TIME)) {
> +	if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> +			       I_DIRTY_TIME)) == I_DIRTY_TIME) {

I think a descriptively named inline helper in fs.h would really improve
this..

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 11/12] ext4: simplify i_state checks in __ext4_update_other_inode_time()
@ 2021-01-11 10:53     ` Christoph Hellwig
  0 siblings, 0 replies; 82+ messages in thread
From: Christoph Hellwig @ 2021-01-11 10:53 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Fri, Jan 08, 2021 at 11:59:02PM -0800, Eric Biggers wrote:
>  	if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> -			       I_DIRTY_INODE)) ||
> -	    ((inode->i_state & I_DIRTY_TIME) == 0))
> +			       I_DIRTY_TIME)) != I_DIRTY_TIME)
>  		return;
>  
>  	spin_lock(&inode->i_lock);
> -	if (((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> -				I_DIRTY_INODE)) == 0) &&
> -	    (inode->i_state & I_DIRTY_TIME)) {
> +	if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> +			       I_DIRTY_TIME)) == I_DIRTY_TIME) {

I think a descriptively named inline helper in fs.h would really improve
this..


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 01/12] fs: fix lazytime expiration handling in __writeback_single_inode()
  2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 14:46     ` Jan Kara
  -1 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 14:46 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig, stable, Jan Kara

On Fri 08-01-21 23:58:52, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> When lazytime is enabled and an inode is being written due to its
> in-memory updated timestamps having expired, either due to a sync() or
> syncfs() system call or due to dirtytime_expire_interval having elapsed,
> the VFS needs to inform the filesystem so that the filesystem can copy
> the inode's timestamps out to the on-disk data structures.
> 
> This is done by __writeback_single_inode() calling
> mark_inode_dirty_sync(), which then calls ->dirty_inode(I_DIRTY_SYNC).
> 
> However, this occurs after __writeback_single_inode() has already
> cleared the dirty flags from ->i_state.  This causes two bugs:
> 
> - mark_inode_dirty_sync() redirties the inode, causing it to remain
>   dirty.  This wastefully causes the inode to be written twice.  But
>   more importantly, it breaks cases where sync_filesystem() is expected
>   to clean dirty inodes.  This includes the FS_IOC_REMOVE_ENCRYPTION_KEY
>   ioctl (as reported at
>   https://lore.kernel.org/r/20200306004555.GB225345@gmail.com), as well
>   as possibly filesystem freezing (freeze_super()).
> 
> - Since ->i_state doesn't contain I_DIRTY_TIME when ->dirty_inode() is
>   called from __writeback_single_inode() for lazytime expiration,
>   xfs_fs_dirty_inode() ignores the notification.  (XFS only cares about
>   lazytime expirations, and it assumes that I_DIRTY_TIME will contain
>   i_state during those.)  Therefore, lazy timestamps aren't persisted by
>   sync(), syncfs(), or dirtytime_expire_interval on XFS.
> 
> Fix this by moving the call to mark_inode_dirty_sync() to earlier in
> __writeback_single_inode(), before the dirty flags are cleared from
> i_state.  This makes filesystems be properly notified of the timestamp
> expiration, and it avoids incorrectly redirtying the inode.
> 
> This fixes xfstest generic/580 (which tests
> FS_IOC_REMOVE_ENCRYPTION_KEY) when run on ext4 or f2fs with lazytime
> enabled.  It also fixes the new lazytime xfstest I've proposed, which
> reproduces the above-mentioned XFS bug
> (https://lore.kernel.org/r/20210105005818.92978-1-ebiggers@kernel.org).
> 
> Alternatively, we could call ->dirty_inode(I_DIRTY_SYNC) directly.  But
> due to the introduction of I_SYNC_QUEUED, mark_inode_dirty_sync() is the
> right thing to do because mark_inode_dirty_sync() now knows not to move
> the inode to a writeback list if it is currently queued for sync.
> 
> Fixes: 0ae45f63d4ef ("vfs: add support for a lazytime mount option")
> Cc: stable@vger.kernel.org
> Depends-on: 5afced3bf281 ("writeback: Avoid skipping inode writeback")
> Suggested-by: Jan Kara <jack@suse.cz>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Thanks for writing this fix! It looks good to me. You can add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/fs-writeback.c | 24 +++++++++++++-----------
>  1 file changed, 13 insertions(+), 11 deletions(-)
> 
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index acfb55834af23..c41cb887eb7d3 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -1474,21 +1474,25 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
>  	}
>  
>  	/*
> -	 * Some filesystems may redirty the inode during the writeback
> -	 * due to delalloc, clear dirty metadata flags right before
> -	 * write_inode()
> +	 * If the inode has dirty timestamps and we need to write them, call
> +	 * mark_inode_dirty_sync() to notify the filesystem about it and to
> +	 * change I_DIRTY_TIME into I_DIRTY_SYNC.
>  	 */
> -	spin_lock(&inode->i_lock);
> -
> -	dirty = inode->i_state & I_DIRTY;
>  	if ((inode->i_state & I_DIRTY_TIME) &&
> -	    ((dirty & I_DIRTY_INODE) ||
> -	     wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
> +	    (wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
>  	     time_after(jiffies, inode->dirtied_time_when +
>  			dirtytime_expire_interval * HZ))) {
> -		dirty |= I_DIRTY_TIME;
>  		trace_writeback_lazytime(inode);
> +		mark_inode_dirty_sync(inode);
>  	}
> +
> +	/*
> +	 * Some filesystems may redirty the inode during the writeback
> +	 * due to delalloc, clear dirty metadata flags right before
> +	 * write_inode()
> +	 */
> +	spin_lock(&inode->i_lock);
> +	dirty = inode->i_state & I_DIRTY;
>  	inode->i_state &= ~dirty;
>  
>  	/*
> @@ -1509,8 +1513,6 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
>  
>  	spin_unlock(&inode->i_lock);
>  
> -	if (dirty & I_DIRTY_TIME)
> -		mark_inode_dirty_sync(inode);
>  	/* Don't write the inode if only I_DIRTY_PAGES was set */
>  	if (dirty & ~I_DIRTY_PAGES) {
>  		int err = write_inode(inode, wbc);
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 01/12] fs: fix lazytime expiration handling in __writeback_single_inode()
@ 2021-01-11 14:46     ` Jan Kara
  0 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 14:46 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, stable, linux-f2fs-devel, linux-xfs,
	linux-fsdevel, Jan Kara, linux-ext4, Christoph Hellwig

On Fri 08-01-21 23:58:52, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> When lazytime is enabled and an inode is being written due to its
> in-memory updated timestamps having expired, either due to a sync() or
> syncfs() system call or due to dirtytime_expire_interval having elapsed,
> the VFS needs to inform the filesystem so that the filesystem can copy
> the inode's timestamps out to the on-disk data structures.
> 
> This is done by __writeback_single_inode() calling
> mark_inode_dirty_sync(), which then calls ->dirty_inode(I_DIRTY_SYNC).
> 
> However, this occurs after __writeback_single_inode() has already
> cleared the dirty flags from ->i_state.  This causes two bugs:
> 
> - mark_inode_dirty_sync() redirties the inode, causing it to remain
>   dirty.  This wastefully causes the inode to be written twice.  But
>   more importantly, it breaks cases where sync_filesystem() is expected
>   to clean dirty inodes.  This includes the FS_IOC_REMOVE_ENCRYPTION_KEY
>   ioctl (as reported at
>   https://lore.kernel.org/r/20200306004555.GB225345@gmail.com), as well
>   as possibly filesystem freezing (freeze_super()).
> 
> - Since ->i_state doesn't contain I_DIRTY_TIME when ->dirty_inode() is
>   called from __writeback_single_inode() for lazytime expiration,
>   xfs_fs_dirty_inode() ignores the notification.  (XFS only cares about
>   lazytime expirations, and it assumes that I_DIRTY_TIME will contain
>   i_state during those.)  Therefore, lazy timestamps aren't persisted by
>   sync(), syncfs(), or dirtytime_expire_interval on XFS.
> 
> Fix this by moving the call to mark_inode_dirty_sync() to earlier in
> __writeback_single_inode(), before the dirty flags are cleared from
> i_state.  This makes filesystems be properly notified of the timestamp
> expiration, and it avoids incorrectly redirtying the inode.
> 
> This fixes xfstest generic/580 (which tests
> FS_IOC_REMOVE_ENCRYPTION_KEY) when run on ext4 or f2fs with lazytime
> enabled.  It also fixes the new lazytime xfstest I've proposed, which
> reproduces the above-mentioned XFS bug
> (https://lore.kernel.org/r/20210105005818.92978-1-ebiggers@kernel.org).
> 
> Alternatively, we could call ->dirty_inode(I_DIRTY_SYNC) directly.  But
> due to the introduction of I_SYNC_QUEUED, mark_inode_dirty_sync() is the
> right thing to do because mark_inode_dirty_sync() now knows not to move
> the inode to a writeback list if it is currently queued for sync.
> 
> Fixes: 0ae45f63d4ef ("vfs: add support for a lazytime mount option")
> Cc: stable@vger.kernel.org
> Depends-on: 5afced3bf281 ("writeback: Avoid skipping inode writeback")
> Suggested-by: Jan Kara <jack@suse.cz>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Thanks for writing this fix! It looks good to me. You can add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/fs-writeback.c | 24 +++++++++++++-----------
>  1 file changed, 13 insertions(+), 11 deletions(-)
> 
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index acfb55834af23..c41cb887eb7d3 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -1474,21 +1474,25 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
>  	}
>  
>  	/*
> -	 * Some filesystems may redirty the inode during the writeback
> -	 * due to delalloc, clear dirty metadata flags right before
> -	 * write_inode()
> +	 * If the inode has dirty timestamps and we need to write them, call
> +	 * mark_inode_dirty_sync() to notify the filesystem about it and to
> +	 * change I_DIRTY_TIME into I_DIRTY_SYNC.
>  	 */
> -	spin_lock(&inode->i_lock);
> -
> -	dirty = inode->i_state & I_DIRTY;
>  	if ((inode->i_state & I_DIRTY_TIME) &&
> -	    ((dirty & I_DIRTY_INODE) ||
> -	     wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
> +	    (wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
>  	     time_after(jiffies, inode->dirtied_time_when +
>  			dirtytime_expire_interval * HZ))) {
> -		dirty |= I_DIRTY_TIME;
>  		trace_writeback_lazytime(inode);
> +		mark_inode_dirty_sync(inode);
>  	}
> +
> +	/*
> +	 * Some filesystems may redirty the inode during the writeback
> +	 * due to delalloc, clear dirty metadata flags right before
> +	 * write_inode()
> +	 */
> +	spin_lock(&inode->i_lock);
> +	dirty = inode->i_state & I_DIRTY;
>  	inode->i_state &= ~dirty;
>  
>  	/*
> @@ -1509,8 +1513,6 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
>  
>  	spin_unlock(&inode->i_lock);
>  
> -	if (dirty & I_DIRTY_TIME)
> -		mark_inode_dirty_sync(inode);
>  	/* Don't write the inode if only I_DIRTY_PAGES was set */
>  	if (dirty & ~I_DIRTY_PAGES) {
>  		int err = write_inode(inode, wbc);
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 02/12] fs: correctly document the inode dirty flags
  2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 14:48     ` Jan Kara
  -1 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 14:48 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

On Fri 08-01-21 23:58:53, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> The documentation for I_DIRTY_SYNC and I_DIRTY_DATASYNC is a bit
> misleading, and I_DIRTY_TIME isn't documented at all.  Fix this.
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good to me. You can add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  include/linux/fs.h | 18 +++++++++++++-----
>  1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index fd47deea7c176..45a0303b2aeb6 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2084,8 +2084,8 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
>  /*
>   * Inode state bits.  Protected by inode->i_lock
>   *
> - * Three bits determine the dirty state of the inode, I_DIRTY_SYNC,
> - * I_DIRTY_DATASYNC and I_DIRTY_PAGES.
> + * Four bits determine the dirty state of the inode: I_DIRTY_SYNC,
> + * I_DIRTY_DATASYNC, I_DIRTY_PAGES, and I_DIRTY_TIME.
>   *
>   * Four bits define the lifetime of an inode.  Initially, inodes are I_NEW,
>   * until that flag is cleared.  I_WILL_FREE, I_FREEING and I_CLEAR are set at
> @@ -2094,12 +2094,20 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
>   * Two bits are used for locking and completion notification, I_NEW and I_SYNC.
>   *
>   * I_DIRTY_SYNC		Inode is dirty, but doesn't have to be written on
> - *			fdatasync().  i_atime is the usual cause.
> - * I_DIRTY_DATASYNC	Data-related inode changes pending. We keep track of
> + *			fdatasync() (unless I_DIRTY_DATASYNC is also set).
> + *			Timestamp updates are the usual cause.
> + * I_DIRTY_DATASYNC	Data-related inode changes pending.  We keep track of
>   *			these changes separately from I_DIRTY_SYNC so that we
>   *			don't have to write inode on fdatasync() when only
> - *			mtime has changed in it.
> + *			e.g. the timestamps have changed.
>   * I_DIRTY_PAGES	Inode has dirty pages.  Inode itself may be clean.
> + * I_DIRTY_TIME		The inode itself only has dirty timestamps, and the
> + *			lazytime mount option is enabled.  We keep track of this
> + *			separately from I_DIRTY_SYNC in order to implement
> + *			lazytime.  This gets cleared if I_DIRTY_INODE
> + *			(I_DIRTY_SYNC and/or I_DIRTY_DATASYNC) gets set.  I.e.
> + *			either I_DIRTY_TIME *or* I_DIRTY_INODE can be set in
> + *			i_state, but not both.  I_DIRTY_PAGES may still be set.
>   * I_NEW		Serves as both a mutex and completion notification.
>   *			New inodes set I_NEW.  If two processes both create
>   *			the same inode, one of them will release its inode and
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 02/12] fs: correctly document the inode dirty flags
@ 2021-01-11 14:48     ` Jan Kara
  0 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 14:48 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Fri 08-01-21 23:58:53, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> The documentation for I_DIRTY_SYNC and I_DIRTY_DATASYNC is a bit
> misleading, and I_DIRTY_TIME isn't documented at all.  Fix this.
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good to me. You can add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  include/linux/fs.h | 18 +++++++++++++-----
>  1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index fd47deea7c176..45a0303b2aeb6 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2084,8 +2084,8 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
>  /*
>   * Inode state bits.  Protected by inode->i_lock
>   *
> - * Three bits determine the dirty state of the inode, I_DIRTY_SYNC,
> - * I_DIRTY_DATASYNC and I_DIRTY_PAGES.
> + * Four bits determine the dirty state of the inode: I_DIRTY_SYNC,
> + * I_DIRTY_DATASYNC, I_DIRTY_PAGES, and I_DIRTY_TIME.
>   *
>   * Four bits define the lifetime of an inode.  Initially, inodes are I_NEW,
>   * until that flag is cleared.  I_WILL_FREE, I_FREEING and I_CLEAR are set at
> @@ -2094,12 +2094,20 @@ static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
>   * Two bits are used for locking and completion notification, I_NEW and I_SYNC.
>   *
>   * I_DIRTY_SYNC		Inode is dirty, but doesn't have to be written on
> - *			fdatasync().  i_atime is the usual cause.
> - * I_DIRTY_DATASYNC	Data-related inode changes pending. We keep track of
> + *			fdatasync() (unless I_DIRTY_DATASYNC is also set).
> + *			Timestamp updates are the usual cause.
> + * I_DIRTY_DATASYNC	Data-related inode changes pending.  We keep track of
>   *			these changes separately from I_DIRTY_SYNC so that we
>   *			don't have to write inode on fdatasync() when only
> - *			mtime has changed in it.
> + *			e.g. the timestamps have changed.
>   * I_DIRTY_PAGES	Inode has dirty pages.  Inode itself may be clean.
> + * I_DIRTY_TIME		The inode itself only has dirty timestamps, and the
> + *			lazytime mount option is enabled.  We keep track of this
> + *			separately from I_DIRTY_SYNC in order to implement
> + *			lazytime.  This gets cleared if I_DIRTY_INODE
> + *			(I_DIRTY_SYNC and/or I_DIRTY_DATASYNC) gets set.  I.e.
> + *			either I_DIRTY_TIME *or* I_DIRTY_INODE can be set in
> + *			i_state, but not both.  I_DIRTY_PAGES may still be set.
>   * I_NEW		Serves as both a mutex and completion notification.
>   *			New inodes set I_NEW.  If two processes both create
>   *			the same inode, one of them will release its inode and
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 03/12] fs: only specify I_DIRTY_TIME when needed in generic_update_time()
  2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 14:50     ` Jan Kara
  -1 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 14:50 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

On Fri 08-01-21 23:58:54, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> generic_update_time() always passes I_DIRTY_TIME to
> __mark_inode_dirty(), which doesn't really make sense because (a)
> generic_update_time() might be asked to do only an i_version update, not
> also a timestamps update; and (b) I_DIRTY_TIME is only supposed to be
> set in i_state if the filesystem has lazytime enabled, so using it
> unconditionally in generic_update_time() is inconsistent.
> 
> As a result there is a weird edge case where if only an i_version update
> was requested (not also a timestamps update) but it is no longer needed
> (i.e. inode_maybe_inc_iversion() returns false), then I_DIRTY_TIME will
> be set in i_state even if the filesystem isn't mounted with lazytime.
> 
> Fix this by only passing I_DIRTY_TIME to __mark_inode_dirty() if the
> timestamps were updated and the filesystem has lazytime enabled.
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good to me. You can add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza


> ---
>  fs/inode.c | 38 ++++++++++++++++++++------------------
>  1 file changed, 20 insertions(+), 18 deletions(-)
> 
> diff --git a/fs/inode.c b/fs/inode.c
> index 6442d97d9a4ab..d0fa43d8e9d5c 100644
> --- a/fs/inode.c
> +++ b/fs/inode.c
> @@ -1743,24 +1743,26 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
>  
>  int generic_update_time(struct inode *inode, struct timespec64 *time, int flags)
>  {
> -	int iflags = I_DIRTY_TIME;
> -	bool dirty = false;
> -
> -	if (flags & S_ATIME)
> -		inode->i_atime = *time;
> -	if (flags & S_VERSION)
> -		dirty = inode_maybe_inc_iversion(inode, false);
> -	if (flags & S_CTIME)
> -		inode->i_ctime = *time;
> -	if (flags & S_MTIME)
> -		inode->i_mtime = *time;
> -	if ((flags & (S_ATIME | S_CTIME | S_MTIME)) &&
> -	    !(inode->i_sb->s_flags & SB_LAZYTIME))
> -		dirty = true;
> -
> -	if (dirty)
> -		iflags |= I_DIRTY_SYNC;
> -	__mark_inode_dirty(inode, iflags);
> +	int dirty_flags = 0;
> +
> +	if (flags & (S_ATIME | S_CTIME | S_MTIME)) {
> +		if (flags & S_ATIME)
> +			inode->i_atime = *time;
> +		if (flags & S_CTIME)
> +			inode->i_ctime = *time;
> +		if (flags & S_MTIME)
> +			inode->i_mtime = *time;
> +
> +		if (inode->i_sb->s_flags & SB_LAZYTIME)
> +			dirty_flags |= I_DIRTY_TIME;
> +		else
> +			dirty_flags |= I_DIRTY_SYNC;
> +	}
> +
> +	if ((flags & S_VERSION) && inode_maybe_inc_iversion(inode, false))
> +		dirty_flags |= I_DIRTY_SYNC;
> +
> +	__mark_inode_dirty(inode, dirty_flags);
>  	return 0;
>  }
>  EXPORT_SYMBOL(generic_update_time);
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 03/12] fs: only specify I_DIRTY_TIME when needed in generic_update_time()
@ 2021-01-11 14:50     ` Jan Kara
  0 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 14:50 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Fri 08-01-21 23:58:54, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> generic_update_time() always passes I_DIRTY_TIME to
> __mark_inode_dirty(), which doesn't really make sense because (a)
> generic_update_time() might be asked to do only an i_version update, not
> also a timestamps update; and (b) I_DIRTY_TIME is only supposed to be
> set in i_state if the filesystem has lazytime enabled, so using it
> unconditionally in generic_update_time() is inconsistent.
> 
> As a result there is a weird edge case where if only an i_version update
> was requested (not also a timestamps update) but it is no longer needed
> (i.e. inode_maybe_inc_iversion() returns false), then I_DIRTY_TIME will
> be set in i_state even if the filesystem isn't mounted with lazytime.
> 
> Fix this by only passing I_DIRTY_TIME to __mark_inode_dirty() if the
> timestamps were updated and the filesystem has lazytime enabled.
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good to me. You can add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza


> ---
>  fs/inode.c | 38 ++++++++++++++++++++------------------
>  1 file changed, 20 insertions(+), 18 deletions(-)
> 
> diff --git a/fs/inode.c b/fs/inode.c
> index 6442d97d9a4ab..d0fa43d8e9d5c 100644
> --- a/fs/inode.c
> +++ b/fs/inode.c
> @@ -1743,24 +1743,26 @@ static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
>  
>  int generic_update_time(struct inode *inode, struct timespec64 *time, int flags)
>  {
> -	int iflags = I_DIRTY_TIME;
> -	bool dirty = false;
> -
> -	if (flags & S_ATIME)
> -		inode->i_atime = *time;
> -	if (flags & S_VERSION)
> -		dirty = inode_maybe_inc_iversion(inode, false);
> -	if (flags & S_CTIME)
> -		inode->i_ctime = *time;
> -	if (flags & S_MTIME)
> -		inode->i_mtime = *time;
> -	if ((flags & (S_ATIME | S_CTIME | S_MTIME)) &&
> -	    !(inode->i_sb->s_flags & SB_LAZYTIME))
> -		dirty = true;
> -
> -	if (dirty)
> -		iflags |= I_DIRTY_SYNC;
> -	__mark_inode_dirty(inode, iflags);
> +	int dirty_flags = 0;
> +
> +	if (flags & (S_ATIME | S_CTIME | S_MTIME)) {
> +		if (flags & S_ATIME)
> +			inode->i_atime = *time;
> +		if (flags & S_CTIME)
> +			inode->i_ctime = *time;
> +		if (flags & S_MTIME)
> +			inode->i_mtime = *time;
> +
> +		if (inode->i_sb->s_flags & SB_LAZYTIME)
> +			dirty_flags |= I_DIRTY_TIME;
> +		else
> +			dirty_flags |= I_DIRTY_SYNC;
> +	}
> +
> +	if ((flags & S_VERSION) && inode_maybe_inc_iversion(inode, false))
> +		dirty_flags |= I_DIRTY_SYNC;
> +
> +	__mark_inode_dirty(inode, dirty_flags);
>  	return 0;
>  }
>  EXPORT_SYMBOL(generic_update_time);
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 04/12] fat: only specify I_DIRTY_TIME when needed in fat_update_time()
  2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 14:52     ` Jan Kara
  -1 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 14:52 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

On Fri 08-01-21 23:58:55, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> As was done for generic_update_time(), only pass I_DIRTY_TIME to
> __mark_inode_dirty() when the inode's timestamps were actually updated
> and lazytime is enabled.  This avoids a weird edge case where
> I_DIRTY_TIME could be set in i_state when lazytime isn't enabled.
> 
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good to me. You can add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/fat/misc.c | 23 ++++++++++++-----------
>  1 file changed, 12 insertions(+), 11 deletions(-)
> 
> diff --git a/fs/fat/misc.c b/fs/fat/misc.c
> index f1b2a1fc2a6a4..18a50a46b57f8 100644
> --- a/fs/fat/misc.c
> +++ b/fs/fat/misc.c
> @@ -329,22 +329,23 @@ EXPORT_SYMBOL_GPL(fat_truncate_time);
>  
>  int fat_update_time(struct inode *inode, struct timespec64 *now, int flags)
>  {
> -	int iflags = I_DIRTY_TIME;
> -	bool dirty = false;
> +	int dirty_flags = 0;
>  
>  	if (inode->i_ino == MSDOS_ROOT_INO)
>  		return 0;
>  
> -	fat_truncate_time(inode, now, flags);
> -	if (flags & S_VERSION)
> -		dirty = inode_maybe_inc_iversion(inode, false);
> -	if ((flags & (S_ATIME | S_CTIME | S_MTIME)) &&
> -	    !(inode->i_sb->s_flags & SB_LAZYTIME))
> -		dirty = true;
> +	if (flags & (S_ATIME | S_CTIME | S_MTIME)) {
> +		fat_truncate_time(inode, now, flags);
> +		if (inode->i_sb->s_flags & SB_LAZYTIME)
> +			dirty_flags |= I_DIRTY_TIME;
> +		else
> +			dirty_flags |= I_DIRTY_SYNC;
> +	}
> +
> +	if ((flags & S_VERSION) && inode_maybe_inc_iversion(inode, false))
> +		dirty_flags |= I_DIRTY_SYNC;
>  
> -	if (dirty)
> -		iflags |= I_DIRTY_SYNC;
> -	__mark_inode_dirty(inode, iflags);
> +	__mark_inode_dirty(inode, dirty_flags);
>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(fat_update_time);
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 04/12] fat: only specify I_DIRTY_TIME when needed in fat_update_time()
@ 2021-01-11 14:52     ` Jan Kara
  0 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 14:52 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Fri 08-01-21 23:58:55, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> As was done for generic_update_time(), only pass I_DIRTY_TIME to
> __mark_inode_dirty() when the inode's timestamps were actually updated
> and lazytime is enabled.  This avoids a weird edge case where
> I_DIRTY_TIME could be set in i_state when lazytime isn't enabled.
> 
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good to me. You can add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/fat/misc.c | 23 ++++++++++++-----------
>  1 file changed, 12 insertions(+), 11 deletions(-)
> 
> diff --git a/fs/fat/misc.c b/fs/fat/misc.c
> index f1b2a1fc2a6a4..18a50a46b57f8 100644
> --- a/fs/fat/misc.c
> +++ b/fs/fat/misc.c
> @@ -329,22 +329,23 @@ EXPORT_SYMBOL_GPL(fat_truncate_time);
>  
>  int fat_update_time(struct inode *inode, struct timespec64 *now, int flags)
>  {
> -	int iflags = I_DIRTY_TIME;
> -	bool dirty = false;
> +	int dirty_flags = 0;
>  
>  	if (inode->i_ino == MSDOS_ROOT_INO)
>  		return 0;
>  
> -	fat_truncate_time(inode, now, flags);
> -	if (flags & S_VERSION)
> -		dirty = inode_maybe_inc_iversion(inode, false);
> -	if ((flags & (S_ATIME | S_CTIME | S_MTIME)) &&
> -	    !(inode->i_sb->s_flags & SB_LAZYTIME))
> -		dirty = true;
> +	if (flags & (S_ATIME | S_CTIME | S_MTIME)) {
> +		fat_truncate_time(inode, now, flags);
> +		if (inode->i_sb->s_flags & SB_LAZYTIME)
> +			dirty_flags |= I_DIRTY_TIME;
> +		else
> +			dirty_flags |= I_DIRTY_SYNC;
> +	}
> +
> +	if ((flags & S_VERSION) && inode_maybe_inc_iversion(inode, false))
> +		dirty_flags |= I_DIRTY_SYNC;
>  
> -	if (dirty)
> -		iflags |= I_DIRTY_SYNC;
> -	__mark_inode_dirty(inode, iflags);
> +	__mark_inode_dirty(inode, dirty_flags);
>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(fat_update_time);
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 05/12] fs: don't call ->dirty_inode for lazytime timestamp updates
  2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 14:54     ` Jan Kara
  -1 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 14:54 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

On Fri 08-01-21 23:58:56, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> There is no need to call ->dirty_inode for lazytime timestamp updates
> (i.e. for __mark_inode_dirty(I_DIRTY_TIME)), since by the definition of
> lazytime, filesystems must ignore these updates.  Filesystems only need
> to care about the updated timestamps when they expire.
> 
> Therefore, only call ->dirty_inode when I_DIRTY_INODE is set.
> 
> Based on a patch from Christoph Hellwig:
> https://lore.kernel.org/r/20200325122825.1086872-4-hch@lst.de
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good to me. You can add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/ext4/inode.c   | 12 +-----------
>  fs/f2fs/super.c   |  3 ---
>  fs/fs-writeback.c |  6 +++---
>  fs/gfs2/super.c   |  2 --
>  4 files changed, 4 insertions(+), 19 deletions(-)
> 
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index 27946882d4ce4..4cc6c7834312f 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -5933,26 +5933,16 @@ int __ext4_mark_inode_dirty(handle_t *handle, struct inode *inode,
>   * If the inode is marked synchronous, we don't honour that here - doing
>   * so would cause a commit on atime updates, which we don't bother doing.
>   * We handle synchronous inodes at the highest possible level.
> - *
> - * If only the I_DIRTY_TIME flag is set, we can skip everything.  If
> - * I_DIRTY_TIME and I_DIRTY_SYNC is set, the only inode fields we need
> - * to copy into the on-disk inode structure are the timestamp files.
>   */
>  void ext4_dirty_inode(struct inode *inode, int flags)
>  {
>  	handle_t *handle;
>  
> -	if (flags == I_DIRTY_TIME)
> -		return;
>  	handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
>  	if (IS_ERR(handle))
> -		goto out;
> -
> +		return;
>  	ext4_mark_inode_dirty(handle, inode);
> -
>  	ext4_journal_stop(handle);
> -out:
> -	return;
>  }
>  
>  int ext4_change_inode_journal_flag(struct inode *inode, int val)
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index b4a07fe62d1a5..cc98dc49f4a26 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -1196,9 +1196,6 @@ static void f2fs_dirty_inode(struct inode *inode, int flags)
>  			inode->i_ino == F2FS_META_INO(sbi))
>  		return;
>  
> -	if (flags == I_DIRTY_TIME)
> -		return;
> -
>  	if (is_inode_flag_set(inode, FI_AUTO_RECOVER))
>  		clear_inode_flag(inode, FI_AUTO_RECOVER);
>  
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index c41cb887eb7d3..b7616bbd55336 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -2255,16 +2255,16 @@ void __mark_inode_dirty(struct inode *inode, int flags)
>  	 * Don't do this for I_DIRTY_PAGES - that doesn't actually
>  	 * dirty the inode itself
>  	 */
> -	if (flags & (I_DIRTY_INODE | I_DIRTY_TIME)) {
> +	if (flags & I_DIRTY_INODE) {
>  		trace_writeback_dirty_inode_start(inode, flags);
>  
>  		if (sb->s_op->dirty_inode)
>  			sb->s_op->dirty_inode(inode, flags);
>  
>  		trace_writeback_dirty_inode(inode, flags);
> -	}
> -	if (flags & I_DIRTY_INODE)
> +
>  		flags &= ~I_DIRTY_TIME;
> +	}
>  	dirtytime = flags & I_DIRTY_TIME;
>  
>  	/*
> diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
> index 2f56acc41c049..042b94288ff11 100644
> --- a/fs/gfs2/super.c
> +++ b/fs/gfs2/super.c
> @@ -562,8 +562,6 @@ static void gfs2_dirty_inode(struct inode *inode, int flags)
>  	int need_endtrans = 0;
>  	int ret;
>  
> -	if (!(flags & I_DIRTY_INODE))
> -		return;
>  	if (unlikely(gfs2_withdrawn(sdp)))
>  		return;
>  	if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 05/12] fs: don't call ->dirty_inode for lazytime timestamp updates
@ 2021-01-11 14:54     ` Jan Kara
  0 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 14:54 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Fri 08-01-21 23:58:56, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> There is no need to call ->dirty_inode for lazytime timestamp updates
> (i.e. for __mark_inode_dirty(I_DIRTY_TIME)), since by the definition of
> lazytime, filesystems must ignore these updates.  Filesystems only need
> to care about the updated timestamps when they expire.
> 
> Therefore, only call ->dirty_inode when I_DIRTY_INODE is set.
> 
> Based on a patch from Christoph Hellwig:
> https://lore.kernel.org/r/20200325122825.1086872-4-hch@lst.de
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good to me. You can add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/ext4/inode.c   | 12 +-----------
>  fs/f2fs/super.c   |  3 ---
>  fs/fs-writeback.c |  6 +++---
>  fs/gfs2/super.c   |  2 --
>  4 files changed, 4 insertions(+), 19 deletions(-)
> 
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index 27946882d4ce4..4cc6c7834312f 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -5933,26 +5933,16 @@ int __ext4_mark_inode_dirty(handle_t *handle, struct inode *inode,
>   * If the inode is marked synchronous, we don't honour that here - doing
>   * so would cause a commit on atime updates, which we don't bother doing.
>   * We handle synchronous inodes at the highest possible level.
> - *
> - * If only the I_DIRTY_TIME flag is set, we can skip everything.  If
> - * I_DIRTY_TIME and I_DIRTY_SYNC is set, the only inode fields we need
> - * to copy into the on-disk inode structure are the timestamp files.
>   */
>  void ext4_dirty_inode(struct inode *inode, int flags)
>  {
>  	handle_t *handle;
>  
> -	if (flags == I_DIRTY_TIME)
> -		return;
>  	handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
>  	if (IS_ERR(handle))
> -		goto out;
> -
> +		return;
>  	ext4_mark_inode_dirty(handle, inode);
> -
>  	ext4_journal_stop(handle);
> -out:
> -	return;
>  }
>  
>  int ext4_change_inode_journal_flag(struct inode *inode, int val)
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index b4a07fe62d1a5..cc98dc49f4a26 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -1196,9 +1196,6 @@ static void f2fs_dirty_inode(struct inode *inode, int flags)
>  			inode->i_ino == F2FS_META_INO(sbi))
>  		return;
>  
> -	if (flags == I_DIRTY_TIME)
> -		return;
> -
>  	if (is_inode_flag_set(inode, FI_AUTO_RECOVER))
>  		clear_inode_flag(inode, FI_AUTO_RECOVER);
>  
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index c41cb887eb7d3..b7616bbd55336 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -2255,16 +2255,16 @@ void __mark_inode_dirty(struct inode *inode, int flags)
>  	 * Don't do this for I_DIRTY_PAGES - that doesn't actually
>  	 * dirty the inode itself
>  	 */
> -	if (flags & (I_DIRTY_INODE | I_DIRTY_TIME)) {
> +	if (flags & I_DIRTY_INODE) {
>  		trace_writeback_dirty_inode_start(inode, flags);
>  
>  		if (sb->s_op->dirty_inode)
>  			sb->s_op->dirty_inode(inode, flags);
>  
>  		trace_writeback_dirty_inode(inode, flags);
> -	}
> -	if (flags & I_DIRTY_INODE)
> +
>  		flags &= ~I_DIRTY_TIME;
> +	}
>  	dirtytime = flags & I_DIRTY_TIME;
>  
>  	/*
> diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
> index 2f56acc41c049..042b94288ff11 100644
> --- a/fs/gfs2/super.c
> +++ b/fs/gfs2/super.c
> @@ -562,8 +562,6 @@ static void gfs2_dirty_inode(struct inode *inode, int flags)
>  	int need_endtrans = 0;
>  	int ret;
>  
> -	if (!(flags & I_DIRTY_INODE))
> -		return;
>  	if (unlikely(gfs2_withdrawn(sdp)))
>  		return;
>  	if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 06/12] fs: pass only I_DIRTY_INODE flags to ->dirty_inode
  2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 14:56     ` Jan Kara
  -1 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 14:56 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

On Fri 08-01-21 23:58:57, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> ->dirty_inode is now only called when I_DIRTY_INODE (I_DIRTY_SYNC and/or
> I_DIRTY_DATASYNC) is set.  However it may still be passed other dirty
> flags at the same time, provided that these other flags happened to be
> passed to __mark_inode_dirty() at the same time as I_DIRTY_INODE.
> 
> This doesn't make sense because there is no reason for filesystems to
> care about these extra flags.  Nor are filesystems notified about all
> updates to these other flags.
> 
> Therefore, mask the flags before passing them to ->dirty_inode.
> 
> Also properly document ->dirty_inode in vfs.rst.
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good to me. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza 

> ---
>  Documentation/filesystems/vfs.rst | 5 ++++-
>  fs/fs-writeback.c                 | 2 +-
>  2 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
> index ca52c82e5bb54..287b80948a40b 100644
> --- a/Documentation/filesystems/vfs.rst
> +++ b/Documentation/filesystems/vfs.rst
> @@ -270,7 +270,10 @@ or bottom half).
>  	->alloc_inode.
>  
>  ``dirty_inode``
> -	this method is called by the VFS to mark an inode dirty.
> +	this method is called by the VFS when an inode is marked dirty.
> +	This is specifically for the inode itself being marked dirty,
> +	not its data.  If the update needs to be persisted by fdatasync(),
> +	then I_DIRTY_DATASYNC will be set in the flags argument.
>  
>  ``write_inode``
>  	this method is called when the VFS needs to write an inode to
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index b7616bbd55336..2e6064012f7d3 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -2259,7 +2259,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
>  		trace_writeback_dirty_inode_start(inode, flags);
>  
>  		if (sb->s_op->dirty_inode)
> -			sb->s_op->dirty_inode(inode, flags);
> +			sb->s_op->dirty_inode(inode, flags & I_DIRTY_INODE);
>  
>  		trace_writeback_dirty_inode(inode, flags);
>  
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 06/12] fs: pass only I_DIRTY_INODE flags to ->dirty_inode
@ 2021-01-11 14:56     ` Jan Kara
  0 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 14:56 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Fri 08-01-21 23:58:57, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> ->dirty_inode is now only called when I_DIRTY_INODE (I_DIRTY_SYNC and/or
> I_DIRTY_DATASYNC) is set.  However it may still be passed other dirty
> flags at the same time, provided that these other flags happened to be
> passed to __mark_inode_dirty() at the same time as I_DIRTY_INODE.
> 
> This doesn't make sense because there is no reason for filesystems to
> care about these extra flags.  Nor are filesystems notified about all
> updates to these other flags.
> 
> Therefore, mask the flags before passing them to ->dirty_inode.
> 
> Also properly document ->dirty_inode in vfs.rst.
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good to me. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza 

> ---
>  Documentation/filesystems/vfs.rst | 5 ++++-
>  fs/fs-writeback.c                 | 2 +-
>  2 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
> index ca52c82e5bb54..287b80948a40b 100644
> --- a/Documentation/filesystems/vfs.rst
> +++ b/Documentation/filesystems/vfs.rst
> @@ -270,7 +270,10 @@ or bottom half).
>  	->alloc_inode.
>  
>  ``dirty_inode``
> -	this method is called by the VFS to mark an inode dirty.
> +	this method is called by the VFS when an inode is marked dirty.
> +	This is specifically for the inode itself being marked dirty,
> +	not its data.  If the update needs to be persisted by fdatasync(),
> +	then I_DIRTY_DATASYNC will be set in the flags argument.
>  
>  ``write_inode``
>  	this method is called when the VFS needs to write an inode to
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index b7616bbd55336..2e6064012f7d3 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -2259,7 +2259,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
>  		trace_writeback_dirty_inode_start(inode, flags);
>  
>  		if (sb->s_op->dirty_inode)
> -			sb->s_op->dirty_inode(inode, flags);
> +			sb->s_op->dirty_inode(inode, flags & I_DIRTY_INODE);
>  
>  		trace_writeback_dirty_inode(inode, flags);
>  
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 07/12] fs: clean up __mark_inode_dirty() a bit
  2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 14:59     ` Jan Kara
  -1 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 14:59 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

On Fri 08-01-21 23:58:58, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> Improve some comments, and don't bother checking for the I_DIRTY_TIME
> flag in the case where we just cleared it.
> 
> Also, warn if I_DIRTY_TIME and I_DIRTY_PAGES are passed to
> __mark_inode_dirty() at the same time, as this case isn't handled.
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/fs-writeback.c | 49 +++++++++++++++++++++++++++++------------------
>  1 file changed, 30 insertions(+), 19 deletions(-)
> 
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index 2e6064012f7d3..80ee9816d9df5 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -2219,23 +2219,24 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode)
>  }
>  
>  /**
> - * __mark_inode_dirty -	internal function
> + * __mark_inode_dirty -	internal function to mark an inode dirty
>   *
>   * @inode: inode to mark
> - * @flags: what kind of dirty (i.e. I_DIRTY_SYNC)
> + * @flags: what kind of dirty, e.g. I_DIRTY_SYNC.  This can be a combination of
> + *	   multiple I_DIRTY_* flags, except that I_DIRTY_TIME can't be combined
> + *	   with I_DIRTY_PAGES.
>   *
> - * Mark an inode as dirty. Callers should use mark_inode_dirty or
> - * mark_inode_dirty_sync.
> + * Mark an inode as dirty.  We notify the filesystem, then update the inode's
> + * dirty flags.  Then, if needed we add the inode to the appropriate dirty list.
>   *
> - * Put the inode on the super block's dirty list.
> + * Most callers should use mark_inode_dirty() or mark_inode_dirty_sync()
> + * instead of calling this directly.
>   *
> - * CAREFUL! We mark it dirty unconditionally, but move it onto the
> - * dirty list only if it is hashed or if it refers to a blockdev.
> - * If it was not hashed, it will never be added to the dirty list
> - * even if it is later hashed, as it will have been marked dirty already.
> + * CAREFUL!  We only add the inode to the dirty list if it is hashed or if it
> + * refers to a blockdev.  Unhashed inodes will never be added to the dirty list
> + * even if they are later hashed, as they will have been marked dirty already.
>   *
> - * In short, make sure you hash any inodes _before_ you start marking
> - * them dirty.
> + * In short, ensure you hash any inodes _before_ you start marking them dirty.
>   *
>   * Note that for blockdevs, inode->dirtied_when represents the dirtying time of
>   * the block-special inode (/dev/hda1) itself.  And the ->dirtied_when field of
> @@ -2247,25 +2248,34 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode)
>  void __mark_inode_dirty(struct inode *inode, int flags)
>  {
>  	struct super_block *sb = inode->i_sb;
> -	int dirtytime;
> +	int dirtytime = 0;
>  
>  	trace_writeback_mark_inode_dirty(inode, flags);
>  
> -	/*
> -	 * Don't do this for I_DIRTY_PAGES - that doesn't actually
> -	 * dirty the inode itself
> -	 */
>  	if (flags & I_DIRTY_INODE) {
> +		/*
> +		 * Notify the filesystem about the inode being dirtied, so that
> +		 * (if needed) it can update on-disk fields and journal the
> +		 * inode.  This is only needed when the inode itself is being
> +		 * dirtied now.  I.e. it's only needed for I_DIRTY_INODE, not
> +		 * for just I_DIRTY_PAGES or I_DIRTY_TIME.
> +		 */
>  		trace_writeback_dirty_inode_start(inode, flags);
> -
>  		if (sb->s_op->dirty_inode)
>  			sb->s_op->dirty_inode(inode, flags & I_DIRTY_INODE);
> -
>  		trace_writeback_dirty_inode(inode, flags);
>  
> +		/* I_DIRTY_INODE supersedes I_DIRTY_TIME. */
>  		flags &= ~I_DIRTY_TIME;
> +	} else {
> +		/*
> +		 * Else it's either I_DIRTY_PAGES, I_DIRTY_TIME, or nothing.
> +		 * (We don't support setting both I_DIRTY_PAGES and I_DIRTY_TIME
> +		 * in one call to __mark_inode_dirty().)
> +		 */
> +		dirtytime = flags & I_DIRTY_TIME;
> +		WARN_ON_ONCE(dirtytime && flags != I_DIRTY_TIME);
>  	}
> -	dirtytime = flags & I_DIRTY_TIME;
>  
>  	/*
>  	 * Paired with smp_mb() in __writeback_single_inode() for the
> @@ -2288,6 +2298,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
>  
>  		inode_attach_wb(inode, NULL);
>  
> +		/* I_DIRTY_INODE supersedes I_DIRTY_TIME. */
>  		if (flags & I_DIRTY_INODE)
>  			inode->i_state &= ~I_DIRTY_TIME;
>  		inode->i_state |= flags;
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 07/12] fs: clean up __mark_inode_dirty() a bit
@ 2021-01-11 14:59     ` Jan Kara
  0 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 14:59 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Fri 08-01-21 23:58:58, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> Improve some comments, and don't bother checking for the I_DIRTY_TIME
> flag in the case where we just cleared it.
> 
> Also, warn if I_DIRTY_TIME and I_DIRTY_PAGES are passed to
> __mark_inode_dirty() at the same time, as this case isn't handled.
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/fs-writeback.c | 49 +++++++++++++++++++++++++++++------------------
>  1 file changed, 30 insertions(+), 19 deletions(-)
> 
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index 2e6064012f7d3..80ee9816d9df5 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -2219,23 +2219,24 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode)
>  }
>  
>  /**
> - * __mark_inode_dirty -	internal function
> + * __mark_inode_dirty -	internal function to mark an inode dirty
>   *
>   * @inode: inode to mark
> - * @flags: what kind of dirty (i.e. I_DIRTY_SYNC)
> + * @flags: what kind of dirty, e.g. I_DIRTY_SYNC.  This can be a combination of
> + *	   multiple I_DIRTY_* flags, except that I_DIRTY_TIME can't be combined
> + *	   with I_DIRTY_PAGES.
>   *
> - * Mark an inode as dirty. Callers should use mark_inode_dirty or
> - * mark_inode_dirty_sync.
> + * Mark an inode as dirty.  We notify the filesystem, then update the inode's
> + * dirty flags.  Then, if needed we add the inode to the appropriate dirty list.
>   *
> - * Put the inode on the super block's dirty list.
> + * Most callers should use mark_inode_dirty() or mark_inode_dirty_sync()
> + * instead of calling this directly.
>   *
> - * CAREFUL! We mark it dirty unconditionally, but move it onto the
> - * dirty list only if it is hashed or if it refers to a blockdev.
> - * If it was not hashed, it will never be added to the dirty list
> - * even if it is later hashed, as it will have been marked dirty already.
> + * CAREFUL!  We only add the inode to the dirty list if it is hashed or if it
> + * refers to a blockdev.  Unhashed inodes will never be added to the dirty list
> + * even if they are later hashed, as they will have been marked dirty already.
>   *
> - * In short, make sure you hash any inodes _before_ you start marking
> - * them dirty.
> + * In short, ensure you hash any inodes _before_ you start marking them dirty.
>   *
>   * Note that for blockdevs, inode->dirtied_when represents the dirtying time of
>   * the block-special inode (/dev/hda1) itself.  And the ->dirtied_when field of
> @@ -2247,25 +2248,34 @@ static noinline void block_dump___mark_inode_dirty(struct inode *inode)
>  void __mark_inode_dirty(struct inode *inode, int flags)
>  {
>  	struct super_block *sb = inode->i_sb;
> -	int dirtytime;
> +	int dirtytime = 0;
>  
>  	trace_writeback_mark_inode_dirty(inode, flags);
>  
> -	/*
> -	 * Don't do this for I_DIRTY_PAGES - that doesn't actually
> -	 * dirty the inode itself
> -	 */
>  	if (flags & I_DIRTY_INODE) {
> +		/*
> +		 * Notify the filesystem about the inode being dirtied, so that
> +		 * (if needed) it can update on-disk fields and journal the
> +		 * inode.  This is only needed when the inode itself is being
> +		 * dirtied now.  I.e. it's only needed for I_DIRTY_INODE, not
> +		 * for just I_DIRTY_PAGES or I_DIRTY_TIME.
> +		 */
>  		trace_writeback_dirty_inode_start(inode, flags);
> -
>  		if (sb->s_op->dirty_inode)
>  			sb->s_op->dirty_inode(inode, flags & I_DIRTY_INODE);
> -
>  		trace_writeback_dirty_inode(inode, flags);
>  
> +		/* I_DIRTY_INODE supersedes I_DIRTY_TIME. */
>  		flags &= ~I_DIRTY_TIME;
> +	} else {
> +		/*
> +		 * Else it's either I_DIRTY_PAGES, I_DIRTY_TIME, or nothing.
> +		 * (We don't support setting both I_DIRTY_PAGES and I_DIRTY_TIME
> +		 * in one call to __mark_inode_dirty().)
> +		 */
> +		dirtytime = flags & I_DIRTY_TIME;
> +		WARN_ON_ONCE(dirtytime && flags != I_DIRTY_TIME);
>  	}
> -	dirtytime = flags & I_DIRTY_TIME;
>  
>  	/*
>  	 * Paired with smp_mb() in __writeback_single_inode() for the
> @@ -2288,6 +2298,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
>  
>  		inode_attach_wb(inode, NULL);
>  
> +		/* I_DIRTY_INODE supersedes I_DIRTY_TIME. */
>  		if (flags & I_DIRTY_INODE)
>  			inode->i_state &= ~I_DIRTY_TIME;
>  		inode->i_state |= flags;
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 08/12] fs: drop redundant check from __writeback_single_inode()
  2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 15:00     ` Jan Kara
  -1 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 15:00 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

On Fri 08-01-21 23:58:59, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> wbc->for_sync implies wbc->sync_mode == WB_SYNC_ALL, so there's no need
> to check for both.  Just check for WB_SYNC_ALL.
> 
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good to me. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/fs-writeback.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index 80ee9816d9df5..cee1df6e3bd43 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -1479,7 +1479,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
>  	 * change I_DIRTY_TIME into I_DIRTY_SYNC.
>  	 */
>  	if ((inode->i_state & I_DIRTY_TIME) &&
> -	    (wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
> +	    (wbc->sync_mode == WB_SYNC_ALL ||
>  	     time_after(jiffies, inode->dirtied_time_when +
>  			dirtytime_expire_interval * HZ))) {
>  		trace_writeback_lazytime(inode);
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 08/12] fs: drop redundant check from __writeback_single_inode()
@ 2021-01-11 15:00     ` Jan Kara
  0 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 15:00 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Fri 08-01-21 23:58:59, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> wbc->for_sync implies wbc->sync_mode == WB_SYNC_ALL, so there's no need
> to check for both.  Just check for WB_SYNC_ALL.
> 
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good to me. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/fs-writeback.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index 80ee9816d9df5..cee1df6e3bd43 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -1479,7 +1479,7 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
>  	 * change I_DIRTY_TIME into I_DIRTY_SYNC.
>  	 */
>  	if ((inode->i_state & I_DIRTY_TIME) &&
> -	    (wbc->sync_mode == WB_SYNC_ALL || wbc->for_sync ||
> +	    (wbc->sync_mode == WB_SYNC_ALL ||
>  	     time_after(jiffies, inode->dirtied_time_when +
>  			dirtytime_expire_interval * HZ))) {
>  		trace_writeback_lazytime(inode);
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 09/12] fs: improve comments for writeback_single_inode()
  2021-01-09  7:59   ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 15:05     ` Jan Kara
  -1 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 15:05 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

On Fri 08-01-21 23:59:00, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> Some comments for writeback_single_inode() and
> __writeback_single_inode() are outdated or not very helpful, especially
> with regards to writeback list handling.  Update them.
> 
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Yeah, looks more comprehensible :). Thanks for the cleanup. Feel free to
add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/fs-writeback.c | 57 +++++++++++++++++++++++++++--------------------
>  1 file changed, 33 insertions(+), 24 deletions(-)
> 
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index cee1df6e3bd43..e91980f493884 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -1442,9 +1442,15 @@ static void requeue_inode(struct inode *inode, struct bdi_writeback *wb,
>  }
>  
>  /*
> - * Write out an inode and its dirty pages. Do not update the writeback list
> - * linkage. That is left to the caller. The caller is also responsible for
> - * setting I_SYNC flag and calling inode_sync_complete() to clear it.
> + * Write out an inode and its dirty pages (or some of its dirty pages, depending
> + * on @wbc->nr_to_write), and clear the relevant dirty flags from i_state.
> + *
> + * This doesn't remove the inode from the writeback list it is on, except
> + * potentially to move it from b_dirty_time to b_dirty due to timestamp
> + * expiration.  The caller is otherwise responsible for writeback list handling.
> + *
> + * The caller is also responsible for setting the I_SYNC flag beforehand and
> + * calling inode_sync_complete() to clear it afterwards.
>   */
>  static int
>  __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
> @@ -1487,9 +1493,10 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
>  	}
>  
>  	/*
> -	 * Some filesystems may redirty the inode during the writeback
> -	 * due to delalloc, clear dirty metadata flags right before
> -	 * write_inode()
> +	 * Get and clear the dirty flags from i_state.  This needs to be done
> +	 * after calling writepages because some filesystems may redirty the
> +	 * inode during writepages due to delalloc.  It also needs to be done
> +	 * after handling timestamp expiration, as that may dirty the inode too.
>  	 */
>  	spin_lock(&inode->i_lock);
>  	dirty = inode->i_state & I_DIRTY;
> @@ -1524,12 +1531,13 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
>  }
>  
>  /*
> - * Write out an inode's dirty pages. Either the caller has an active reference
> - * on the inode or the inode has I_WILL_FREE set.
> + * Write out an inode's dirty data and metadata on-demand, i.e. separately from
> + * the regular batched writeback done by the flusher threads in
> + * writeback_sb_inodes().  @wbc controls various aspects of the write, such as
> + * whether it is a data-integrity sync (%WB_SYNC_ALL) or not (%WB_SYNC_NONE).
>   *
> - * This function is designed to be called for writing back one inode which
> - * we go e.g. from filesystem. Flusher thread uses __writeback_single_inode()
> - * and does more profound writeback list handling in writeback_sb_inodes().
> + * To prevent the inode from going away, either the caller must have a reference
> + * to the inode, or the inode must have I_WILL_FREE or I_FREEING set.
>   */
>  static int writeback_single_inode(struct inode *inode,
>  				  struct writeback_control *wbc)
> @@ -1544,23 +1552,23 @@ static int writeback_single_inode(struct inode *inode,
>  		WARN_ON(inode->i_state & I_WILL_FREE);
>  
>  	if (inode->i_state & I_SYNC) {
> -		if (wbc->sync_mode != WB_SYNC_ALL)
> -			goto out;
>  		/*
> -		 * It's a data-integrity sync. We must wait. Since callers hold
> -		 * inode reference or inode has I_WILL_FREE set, it cannot go
> -		 * away under us.
> +		 * Writeback is already running on the inode.  For WB_SYNC_NONE,
> +		 * that's enough and we can just return.  For WB_SYNC_ALL, we
> +		 * must wait for the existing writeback to complete, then do
> +		 * writeback again if there's anything left.
>  		 */
> +		if (wbc->sync_mode != WB_SYNC_ALL)
> +			goto out;
>  		__inode_wait_for_writeback(inode);
>  	}
>  	WARN_ON(inode->i_state & I_SYNC);
>  	/*
> -	 * Skip inode if it is clean and we have no outstanding writeback in
> -	 * WB_SYNC_ALL mode. We don't want to mess with writeback lists in this
> -	 * function since flusher thread may be doing for example sync in
> -	 * parallel and if we move the inode, it could get skipped. So here we
> -	 * make sure inode is on some writeback list and leave it there unless
> -	 * we have completely cleaned the inode.
> +	 * If the inode is already fully clean, then there's nothing to do.
> +	 *
> +	 * For data-integrity syncs we also need to check whether any pages are
> +	 * still under writeback, e.g. due to prior WB_SYNC_NONE writeback.  If
> +	 * there are any such pages, we'll need to wait for them.
>  	 */
>  	if (!(inode->i_state & I_DIRTY_ALL) &&
>  	    (wbc->sync_mode != WB_SYNC_ALL ||
> @@ -1576,8 +1584,9 @@ static int writeback_single_inode(struct inode *inode,
>  	wb = inode_to_wb_and_lock_list(inode);
>  	spin_lock(&inode->i_lock);
>  	/*
> -	 * If inode is clean, remove it from writeback lists. Otherwise don't
> -	 * touch it. See comment above for explanation.
> +	 * If the inode is now fully clean, then it can be safely removed from
> +	 * its writeback list (if any).  Otherwise the flusher threads are
> +	 * responsible for the writeback lists.
>  	 */
>  	if (!(inode->i_state & I_DIRTY_ALL))
>  		inode_io_list_del_locked(inode, wb);
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 09/12] fs: improve comments for writeback_single_inode()
@ 2021-01-11 15:05     ` Jan Kara
  0 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 15:05 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Fri 08-01-21 23:59:00, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> Some comments for writeback_single_inode() and
> __writeback_single_inode() are outdated or not very helpful, especially
> with regards to writeback list handling.  Update them.
> 
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Yeah, looks more comprehensible :). Thanks for the cleanup. Feel free to
add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/fs-writeback.c | 57 +++++++++++++++++++++++++++--------------------
>  1 file changed, 33 insertions(+), 24 deletions(-)
> 
> diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
> index cee1df6e3bd43..e91980f493884 100644
> --- a/fs/fs-writeback.c
> +++ b/fs/fs-writeback.c
> @@ -1442,9 +1442,15 @@ static void requeue_inode(struct inode *inode, struct bdi_writeback *wb,
>  }
>  
>  /*
> - * Write out an inode and its dirty pages. Do not update the writeback list
> - * linkage. That is left to the caller. The caller is also responsible for
> - * setting I_SYNC flag and calling inode_sync_complete() to clear it.
> + * Write out an inode and its dirty pages (or some of its dirty pages, depending
> + * on @wbc->nr_to_write), and clear the relevant dirty flags from i_state.
> + *
> + * This doesn't remove the inode from the writeback list it is on, except
> + * potentially to move it from b_dirty_time to b_dirty due to timestamp
> + * expiration.  The caller is otherwise responsible for writeback list handling.
> + *
> + * The caller is also responsible for setting the I_SYNC flag beforehand and
> + * calling inode_sync_complete() to clear it afterwards.
>   */
>  static int
>  __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
> @@ -1487,9 +1493,10 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
>  	}
>  
>  	/*
> -	 * Some filesystems may redirty the inode during the writeback
> -	 * due to delalloc, clear dirty metadata flags right before
> -	 * write_inode()
> +	 * Get and clear the dirty flags from i_state.  This needs to be done
> +	 * after calling writepages because some filesystems may redirty the
> +	 * inode during writepages due to delalloc.  It also needs to be done
> +	 * after handling timestamp expiration, as that may dirty the inode too.
>  	 */
>  	spin_lock(&inode->i_lock);
>  	dirty = inode->i_state & I_DIRTY;
> @@ -1524,12 +1531,13 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
>  }
>  
>  /*
> - * Write out an inode's dirty pages. Either the caller has an active reference
> - * on the inode or the inode has I_WILL_FREE set.
> + * Write out an inode's dirty data and metadata on-demand, i.e. separately from
> + * the regular batched writeback done by the flusher threads in
> + * writeback_sb_inodes().  @wbc controls various aspects of the write, such as
> + * whether it is a data-integrity sync (%WB_SYNC_ALL) or not (%WB_SYNC_NONE).
>   *
> - * This function is designed to be called for writing back one inode which
> - * we go e.g. from filesystem. Flusher thread uses __writeback_single_inode()
> - * and does more profound writeback list handling in writeback_sb_inodes().
> + * To prevent the inode from going away, either the caller must have a reference
> + * to the inode, or the inode must have I_WILL_FREE or I_FREEING set.
>   */
>  static int writeback_single_inode(struct inode *inode,
>  				  struct writeback_control *wbc)
> @@ -1544,23 +1552,23 @@ static int writeback_single_inode(struct inode *inode,
>  		WARN_ON(inode->i_state & I_WILL_FREE);
>  
>  	if (inode->i_state & I_SYNC) {
> -		if (wbc->sync_mode != WB_SYNC_ALL)
> -			goto out;
>  		/*
> -		 * It's a data-integrity sync. We must wait. Since callers hold
> -		 * inode reference or inode has I_WILL_FREE set, it cannot go
> -		 * away under us.
> +		 * Writeback is already running on the inode.  For WB_SYNC_NONE,
> +		 * that's enough and we can just return.  For WB_SYNC_ALL, we
> +		 * must wait for the existing writeback to complete, then do
> +		 * writeback again if there's anything left.
>  		 */
> +		if (wbc->sync_mode != WB_SYNC_ALL)
> +			goto out;
>  		__inode_wait_for_writeback(inode);
>  	}
>  	WARN_ON(inode->i_state & I_SYNC);
>  	/*
> -	 * Skip inode if it is clean and we have no outstanding writeback in
> -	 * WB_SYNC_ALL mode. We don't want to mess with writeback lists in this
> -	 * function since flusher thread may be doing for example sync in
> -	 * parallel and if we move the inode, it could get skipped. So here we
> -	 * make sure inode is on some writeback list and leave it there unless
> -	 * we have completely cleaned the inode.
> +	 * If the inode is already fully clean, then there's nothing to do.
> +	 *
> +	 * For data-integrity syncs we also need to check whether any pages are
> +	 * still under writeback, e.g. due to prior WB_SYNC_NONE writeback.  If
> +	 * there are any such pages, we'll need to wait for them.
>  	 */
>  	if (!(inode->i_state & I_DIRTY_ALL) &&
>  	    (wbc->sync_mode != WB_SYNC_ALL ||
> @@ -1576,8 +1584,9 @@ static int writeback_single_inode(struct inode *inode,
>  	wb = inode_to_wb_and_lock_list(inode);
>  	spin_lock(&inode->i_lock);
>  	/*
> -	 * If inode is clean, remove it from writeback lists. Otherwise don't
> -	 * touch it. See comment above for explanation.
> +	 * If the inode is now fully clean, then it can be safely removed from
> +	 * its writeback list (if any).  Otherwise the flusher threads are
> +	 * responsible for the writeback lists.
>  	 */
>  	if (!(inode->i_state & I_DIRTY_ALL))
>  		inode_io_list_del_locked(inode, wb);
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 10/12] gfs2: don't worry about I_DIRTY_TIME in gfs2_fsync()
  2021-01-09  7:59   ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 15:06     ` Jan Kara
  -1 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 15:06 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

On Fri 08-01-21 23:59:01, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> The I_DIRTY_TIME flag is primary used within the VFS, and there's no
> reason for ->fsync() implementations to do anything with it.  This is
> because when !datasync, the VFS will expire dirty timestamps before
> calling ->fsync().  (See vfs_fsync_range().)  This turns I_DIRTY_TIME
> into I_DIRTY_SYNC.
> 
> Therefore, change gfs2_fsync() to not check for I_DIRTY_TIME.
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good to me. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/gfs2/file.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
> index b39b339feddc9..7fe2497755a37 100644
> --- a/fs/gfs2/file.c
> +++ b/fs/gfs2/file.c
> @@ -749,7 +749,7 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
>  {
>  	struct address_space *mapping = file->f_mapping;
>  	struct inode *inode = mapping->host;
> -	int sync_state = inode->i_state & I_DIRTY_ALL;
> +	int sync_state = inode->i_state & I_DIRTY;
>  	struct gfs2_inode *ip = GFS2_I(inode);
>  	int ret = 0, ret1 = 0;
>  
> @@ -762,7 +762,7 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
>  	if (!gfs2_is_jdata(ip))
>  		sync_state &= ~I_DIRTY_PAGES;
>  	if (datasync)
> -		sync_state &= ~(I_DIRTY_SYNC | I_DIRTY_TIME);
> +		sync_state &= ~I_DIRTY_SYNC;
>  
>  	if (sync_state) {
>  		ret = sync_inode_metadata(inode, 1);
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 10/12] gfs2: don't worry about I_DIRTY_TIME in gfs2_fsync()
@ 2021-01-11 15:06     ` Jan Kara
  0 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 15:06 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Fri 08-01-21 23:59:01, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> The I_DIRTY_TIME flag is primary used within the VFS, and there's no
> reason for ->fsync() implementations to do anything with it.  This is
> because when !datasync, the VFS will expire dirty timestamps before
> calling ->fsync().  (See vfs_fsync_range().)  This turns I_DIRTY_TIME
> into I_DIRTY_SYNC.
> 
> Therefore, change gfs2_fsync() to not check for I_DIRTY_TIME.
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good to me. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/gfs2/file.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
> index b39b339feddc9..7fe2497755a37 100644
> --- a/fs/gfs2/file.c
> +++ b/fs/gfs2/file.c
> @@ -749,7 +749,7 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
>  {
>  	struct address_space *mapping = file->f_mapping;
>  	struct inode *inode = mapping->host;
> -	int sync_state = inode->i_state & I_DIRTY_ALL;
> +	int sync_state = inode->i_state & I_DIRTY;
>  	struct gfs2_inode *ip = GFS2_I(inode);
>  	int ret = 0, ret1 = 0;
>  
> @@ -762,7 +762,7 @@ static int gfs2_fsync(struct file *file, loff_t start, loff_t end,
>  	if (!gfs2_is_jdata(ip))
>  		sync_state &= ~I_DIRTY_PAGES;
>  	if (datasync)
> -		sync_state &= ~(I_DIRTY_SYNC | I_DIRTY_TIME);
> +		sync_state &= ~I_DIRTY_SYNC;
>  
>  	if (sync_state) {
>  		ret = sync_inode_metadata(inode, 1);
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 11/12] ext4: simplify i_state checks in __ext4_update_other_inode_time()
  2021-01-09  7:59   ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 15:11     ` Jan Kara
  -1 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 15:11 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

On Fri 08-01-21 23:59:02, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> Since I_DIRTY_TIME and I_DIRTY_INODE are mutually exclusive in i_state,
> there's no need to check for I_DIRTY_TIME && !I_DIRTY_INODE.  Just check
> for I_DIRTY_TIME.
> 
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good to me. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/ext4/inode.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index 4cc6c7834312f..00bca5c18eb65 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -4962,14 +4962,12 @@ static void __ext4_update_other_inode_time(struct super_block *sb,
>  		return;
>  
>  	if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> -			       I_DIRTY_INODE)) ||
> -	    ((inode->i_state & I_DIRTY_TIME) == 0))
> +			       I_DIRTY_TIME)) != I_DIRTY_TIME)
>  		return;
>  
>  	spin_lock(&inode->i_lock);
> -	if (((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> -				I_DIRTY_INODE)) == 0) &&
> -	    (inode->i_state & I_DIRTY_TIME)) {
> +	if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> +			       I_DIRTY_TIME)) == I_DIRTY_TIME) {
>  		struct ext4_inode_info	*ei = EXT4_I(inode);
>  
>  		inode->i_state &= ~I_DIRTY_TIME;
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 11/12] ext4: simplify i_state checks in __ext4_update_other_inode_time()
@ 2021-01-11 15:11     ` Jan Kara
  0 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 15:11 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Fri 08-01-21 23:59:02, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> Since I_DIRTY_TIME and I_DIRTY_INODE are mutually exclusive in i_state,
> there's no need to check for I_DIRTY_TIME && !I_DIRTY_INODE.  Just check
> for I_DIRTY_TIME.
> 
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Looks good to me. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/ext4/inode.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index 4cc6c7834312f..00bca5c18eb65 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -4962,14 +4962,12 @@ static void __ext4_update_other_inode_time(struct super_block *sb,
>  		return;
>  
>  	if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> -			       I_DIRTY_INODE)) ||
> -	    ((inode->i_state & I_DIRTY_TIME) == 0))
> +			       I_DIRTY_TIME)) != I_DIRTY_TIME)
>  		return;
>  
>  	spin_lock(&inode->i_lock);
> -	if (((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> -				I_DIRTY_INODE)) == 0) &&
> -	    (inode->i_state & I_DIRTY_TIME)) {
> +	if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> +			       I_DIRTY_TIME)) == I_DIRTY_TIME) {
>  		struct ext4_inode_info	*ei = EXT4_I(inode);
>  
>  		inode->i_state &= ~I_DIRTY_TIME;
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 00/12] lazytime fix and cleanups
  2021-01-09  7:58 ` [f2fs-dev] " Eric Biggers
@ 2021-01-11 15:15   ` Jan Kara
  -1 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 15:15 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

Hi!

On Fri 08-01-21 23:58:51, Eric Biggers wrote:
> Hello,
> 
> Patch 1 fixes a bug in how __writeback_single_inode() handles lazytime
> expirations.  I originally reported this last year
> (https://lore.kernel.org/r/20200306004555.GB225345@gmail.com) because it
> causes the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl to not work properly, as
> the bug causes inodes to remain dirty after a sync.
> 
> It also turns out that lazytime on XFS is partially broken because it
> doesn't actually write timestamps to disk after a sync() or after
> dirtytime_expire_interval.  This is fixed by the same fix.
> 
> This supersedes previously proposed fixes, including
> https://lore.kernel.org/r/20200307020043.60118-1-tytso@mit.edu and
> https://lore.kernel.org/r/20200325122825.1086872-3-hch@lst.de from last
> year (which had some issues and didn't fix the XFS bug), and v1 of this
> patchset which took a different approach
> (https://lore.kernel.org/r/20210105005452.92521-1-ebiggers@kernel.org).
> 
> Patches 2-12 then clean up various things related to lazytime and
> writeback, such as clarifying the semantics of ->dirty_inode() and the
> inode dirty flags, and improving comments.  Most of these patches could
> be applied independently if needed.
> 
> This patchset applies to v5.11-rc2.

The series look good to me. How do you plan to merge it (after resolving
Christoph's remarks)? I guess either Ted can take it through the ext4 tree
or I can take it through my tree...

								Honza

> 
> Changed since v1:
>   - Switched to the fix suggested by Jan Kara, and dropped the
>     patches which introduced ->lazytime_expired().
>   - Fixed bugs in the fat and ext4 patches.
>   - Added patch "fs: improve comments for writeback_single_inode()".
>   - Reordered the patches a bit.
>   - Added Reviewed-by's.
> 
> Eric Biggers (12):
>   fs: fix lazytime expiration handling in __writeback_single_inode()
>   fs: correctly document the inode dirty flags
>   fs: only specify I_DIRTY_TIME when needed in generic_update_time()
>   fat: only specify I_DIRTY_TIME when needed in fat_update_time()
>   fs: don't call ->dirty_inode for lazytime timestamp updates
>   fs: pass only I_DIRTY_INODE flags to ->dirty_inode
>   fs: clean up __mark_inode_dirty() a bit
>   fs: drop redundant check from __writeback_single_inode()
>   fs: improve comments for writeback_single_inode()
>   gfs2: don't worry about I_DIRTY_TIME in gfs2_fsync()
>   ext4: simplify i_state checks in __ext4_update_other_inode_time()
>   xfs: remove a stale comment from xfs_file_aio_write_checks()
> 
>  Documentation/filesystems/vfs.rst |   5 +-
>  fs/ext4/inode.c                   |  20 +----
>  fs/f2fs/super.c                   |   3 -
>  fs/fat/misc.c                     |  23 +++---
>  fs/fs-writeback.c                 | 132 +++++++++++++++++-------------
>  fs/gfs2/file.c                    |   4 +-
>  fs/gfs2/super.c                   |   2 -
>  fs/inode.c                        |  38 +++++----
>  fs/xfs/xfs_file.c                 |   6 --
>  include/linux/fs.h                |  18 ++--
>  10 files changed, 132 insertions(+), 119 deletions(-)
> 
> 
> base-commit: e71ba9452f0b5b2e8dc8aa5445198cd9214a6a62
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 00/12] lazytime fix and cleanups
@ 2021-01-11 15:15   ` Jan Kara
  0 siblings, 0 replies; 82+ messages in thread
From: Jan Kara @ 2021-01-11 15:15 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

Hi!

On Fri 08-01-21 23:58:51, Eric Biggers wrote:
> Hello,
> 
> Patch 1 fixes a bug in how __writeback_single_inode() handles lazytime
> expirations.  I originally reported this last year
> (https://lore.kernel.org/r/20200306004555.GB225345@gmail.com) because it
> causes the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl to not work properly, as
> the bug causes inodes to remain dirty after a sync.
> 
> It also turns out that lazytime on XFS is partially broken because it
> doesn't actually write timestamps to disk after a sync() or after
> dirtytime_expire_interval.  This is fixed by the same fix.
> 
> This supersedes previously proposed fixes, including
> https://lore.kernel.org/r/20200307020043.60118-1-tytso@mit.edu and
> https://lore.kernel.org/r/20200325122825.1086872-3-hch@lst.de from last
> year (which had some issues and didn't fix the XFS bug), and v1 of this
> patchset which took a different approach
> (https://lore.kernel.org/r/20210105005452.92521-1-ebiggers@kernel.org).
> 
> Patches 2-12 then clean up various things related to lazytime and
> writeback, such as clarifying the semantics of ->dirty_inode() and the
> inode dirty flags, and improving comments.  Most of these patches could
> be applied independently if needed.
> 
> This patchset applies to v5.11-rc2.

The series look good to me. How do you plan to merge it (after resolving
Christoph's remarks)? I guess either Ted can take it through the ext4 tree
or I can take it through my tree...

								Honza

> 
> Changed since v1:
>   - Switched to the fix suggested by Jan Kara, and dropped the
>     patches which introduced ->lazytime_expired().
>   - Fixed bugs in the fat and ext4 patches.
>   - Added patch "fs: improve comments for writeback_single_inode()".
>   - Reordered the patches a bit.
>   - Added Reviewed-by's.
> 
> Eric Biggers (12):
>   fs: fix lazytime expiration handling in __writeback_single_inode()
>   fs: correctly document the inode dirty flags
>   fs: only specify I_DIRTY_TIME when needed in generic_update_time()
>   fat: only specify I_DIRTY_TIME when needed in fat_update_time()
>   fs: don't call ->dirty_inode for lazytime timestamp updates
>   fs: pass only I_DIRTY_INODE flags to ->dirty_inode
>   fs: clean up __mark_inode_dirty() a bit
>   fs: drop redundant check from __writeback_single_inode()
>   fs: improve comments for writeback_single_inode()
>   gfs2: don't worry about I_DIRTY_TIME in gfs2_fsync()
>   ext4: simplify i_state checks in __ext4_update_other_inode_time()
>   xfs: remove a stale comment from xfs_file_aio_write_checks()
> 
>  Documentation/filesystems/vfs.rst |   5 +-
>  fs/ext4/inode.c                   |  20 +----
>  fs/f2fs/super.c                   |   3 -
>  fs/fat/misc.c                     |  23 +++---
>  fs/fs-writeback.c                 | 132 +++++++++++++++++-------------
>  fs/gfs2/file.c                    |   4 +-
>  fs/gfs2/super.c                   |   2 -
>  fs/inode.c                        |  38 +++++----
>  fs/xfs/xfs_file.c                 |   6 --
>  include/linux/fs.h                |  18 ++--
>  10 files changed, 132 insertions(+), 119 deletions(-)
> 
> 
> base-commit: e71ba9452f0b5b2e8dc8aa5445198cd9214a6a62
> -- 
> 2.30.0
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 04/12] fat: only specify I_DIRTY_TIME when needed in fat_update_time()
  2021-01-11 10:52     ` [f2fs-dev] " Christoph Hellwig
@ 2021-01-11 19:50       ` Eric Biggers
  -1 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-11 19:50 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o

On Mon, Jan 11, 2021 at 11:52:01AM +0100, Christoph Hellwig wrote:
> On Fri, Jan 08, 2021 at 11:58:55PM -0800, Eric Biggers wrote:
> > +	if ((flags & S_VERSION) && inode_maybe_inc_iversion(inode, false))
> > +		dirty_flags |= I_DIRTY_SYNC;
> 
> fat does not support i_version updates, so this bit can be skipped.

Is that really the case?  Any filesystem (including fat) can be mounted with
"iversion", which causes SB_I_VERSION to be set.

A lot of filesystems (including fat) don't store i_version to disk, but it looks
like it will still get updated in-memory.  Could anything be relying on that?

- Eric

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 04/12] fat: only specify I_DIRTY_TIME when needed in fat_update_time()
@ 2021-01-11 19:50       ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-11 19:50 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-fsdevel, linux-xfs, linux-ext4, Theodore Ts'o,
	linux-f2fs-devel

On Mon, Jan 11, 2021 at 11:52:01AM +0100, Christoph Hellwig wrote:
> On Fri, Jan 08, 2021 at 11:58:55PM -0800, Eric Biggers wrote:
> > +	if ((flags & S_VERSION) && inode_maybe_inc_iversion(inode, false))
> > +		dirty_flags |= I_DIRTY_SYNC;
> 
> fat does not support i_version updates, so this bit can be skipped.

Is that really the case?  Any filesystem (including fat) can be mounted with
"iversion", which causes SB_I_VERSION to be set.

A lot of filesystems (including fat) don't store i_version to disk, but it looks
like it will still get updated in-memory.  Could anything be relying on that?

- Eric


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 11/12] ext4: simplify i_state checks in __ext4_update_other_inode_time()
  2021-01-11 10:53     ` [f2fs-dev] " Christoph Hellwig
@ 2021-01-11 20:23       ` Eric Biggers
  -1 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-11 20:23 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o

On Mon, Jan 11, 2021 at 11:53:42AM +0100, Christoph Hellwig wrote:
> On Fri, Jan 08, 2021 at 11:59:02PM -0800, Eric Biggers wrote:
> >  	if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> > -			       I_DIRTY_INODE)) ||
> > -	    ((inode->i_state & I_DIRTY_TIME) == 0))
> > +			       I_DIRTY_TIME)) != I_DIRTY_TIME)
> >  		return;
> >  
> >  	spin_lock(&inode->i_lock);
> > -	if (((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> > -				I_DIRTY_INODE)) == 0) &&
> > -	    (inode->i_state & I_DIRTY_TIME)) {
> > +	if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> > +			       I_DIRTY_TIME)) == I_DIRTY_TIME) {
> 
> I think a descriptively named inline helper in fs.h would really improve
> this..

Do you want this even though it is specific to how ext4 opportunisticly updates
other inodes in the same inode block as the inode being updated?  That's the
only reason that I_FREEING|I_WILL_FREE|I_NEW need to be checked; everywhere else
justs want I_DIRTY_TIME.

We could add:

	static inline bool other_inode_has_dirtytime(struct inode *inode)
	{
		return (inode->state & (I_FREEING | I_WILL_FREE |
					I_NEW | I_DIRTY_TIME)) == I_DIRTY_TIME;
	}

But it seems a bit weird when it's specific to ext4 at the moment.

Are you thinking that other filesystems will implement the same sort of
opportunistic update, so we should add the helper now?

- Eric

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 11/12] ext4: simplify i_state checks in __ext4_update_other_inode_time()
@ 2021-01-11 20:23       ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-11 20:23 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: linux-fsdevel, linux-xfs, linux-ext4, Theodore Ts'o,
	linux-f2fs-devel

On Mon, Jan 11, 2021 at 11:53:42AM +0100, Christoph Hellwig wrote:
> On Fri, Jan 08, 2021 at 11:59:02PM -0800, Eric Biggers wrote:
> >  	if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> > -			       I_DIRTY_INODE)) ||
> > -	    ((inode->i_state & I_DIRTY_TIME) == 0))
> > +			       I_DIRTY_TIME)) != I_DIRTY_TIME)
> >  		return;
> >  
> >  	spin_lock(&inode->i_lock);
> > -	if (((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> > -				I_DIRTY_INODE)) == 0) &&
> > -	    (inode->i_state & I_DIRTY_TIME)) {
> > +	if ((inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW |
> > +			       I_DIRTY_TIME)) == I_DIRTY_TIME) {
> 
> I think a descriptively named inline helper in fs.h would really improve
> this..

Do you want this even though it is specific to how ext4 opportunisticly updates
other inodes in the same inode block as the inode being updated?  That's the
only reason that I_FREEING|I_WILL_FREE|I_NEW need to be checked; everywhere else
justs want I_DIRTY_TIME.

We could add:

	static inline bool other_inode_has_dirtytime(struct inode *inode)
	{
		return (inode->state & (I_FREEING | I_WILL_FREE |
					I_NEW | I_DIRTY_TIME)) == I_DIRTY_TIME;
	}

But it seems a bit weird when it's specific to ext4 at the moment.

Are you thinking that other filesystems will implement the same sort of
opportunistic update, so we should add the helper now?

- Eric


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 00/12] lazytime fix and cleanups
  2021-01-11 15:15   ` [f2fs-dev] " Jan Kara
@ 2021-01-11 20:44     ` Eric Biggers
  -1 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-11 20:44 UTC (permalink / raw)
  To: Jan Kara
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

On Mon, Jan 11, 2021 at 04:15:17PM +0100, Jan Kara wrote:
> Hi!
> 
> On Fri 08-01-21 23:58:51, Eric Biggers wrote:
> > Hello,
> > 
> > Patch 1 fixes a bug in how __writeback_single_inode() handles lazytime
> > expirations.  I originally reported this last year
> > (https://lore.kernel.org/r/20200306004555.GB225345@gmail.com) because it
> > causes the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl to not work properly, as
> > the bug causes inodes to remain dirty after a sync.
> > 
> > It also turns out that lazytime on XFS is partially broken because it
> > doesn't actually write timestamps to disk after a sync() or after
> > dirtytime_expire_interval.  This is fixed by the same fix.
> > 
> > This supersedes previously proposed fixes, including
> > https://lore.kernel.org/r/20200307020043.60118-1-tytso@mit.edu and
> > https://lore.kernel.org/r/20200325122825.1086872-3-hch@lst.de from last
> > year (which had some issues and didn't fix the XFS bug), and v1 of this
> > patchset which took a different approach
> > (https://lore.kernel.org/r/20210105005452.92521-1-ebiggers@kernel.org).
> > 
> > Patches 2-12 then clean up various things related to lazytime and
> > writeback, such as clarifying the semantics of ->dirty_inode() and the
> > inode dirty flags, and improving comments.  Most of these patches could
> > be applied independently if needed.
> > 
> > This patchset applies to v5.11-rc2.
> 
> The series look good to me. How do you plan to merge it (after resolving
> Christoph's remarks)? I guess either Ted can take it through the ext4 tree
> or I can take it through my tree...
> 

I think taking it through your tree would be best, unless Al or Ted wants to
take it.

I'll probably separate out
"xfs: remove a stale comment from xfs_file_aio_write_checks()",
since it isn't really related anymore and could go in through the XFS tree.

- Eric

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 00/12] lazytime fix and cleanups
@ 2021-01-11 20:44     ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-01-11 20:44 UTC (permalink / raw)
  To: Jan Kara
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Mon, Jan 11, 2021 at 04:15:17PM +0100, Jan Kara wrote:
> Hi!
> 
> On Fri 08-01-21 23:58:51, Eric Biggers wrote:
> > Hello,
> > 
> > Patch 1 fixes a bug in how __writeback_single_inode() handles lazytime
> > expirations.  I originally reported this last year
> > (https://lore.kernel.org/r/20200306004555.GB225345@gmail.com) because it
> > causes the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl to not work properly, as
> > the bug causes inodes to remain dirty after a sync.
> > 
> > It also turns out that lazytime on XFS is partially broken because it
> > doesn't actually write timestamps to disk after a sync() or after
> > dirtytime_expire_interval.  This is fixed by the same fix.
> > 
> > This supersedes previously proposed fixes, including
> > https://lore.kernel.org/r/20200307020043.60118-1-tytso@mit.edu and
> > https://lore.kernel.org/r/20200325122825.1086872-3-hch@lst.de from last
> > year (which had some issues and didn't fix the XFS bug), and v1 of this
> > patchset which took a different approach
> > (https://lore.kernel.org/r/20210105005452.92521-1-ebiggers@kernel.org).
> > 
> > Patches 2-12 then clean up various things related to lazytime and
> > writeback, such as clarifying the semantics of ->dirty_inode() and the
> > inode dirty flags, and improving comments.  Most of these patches could
> > be applied independently if needed.
> > 
> > This patchset applies to v5.11-rc2.
> 
> The series look good to me. How do you plan to merge it (after resolving
> Christoph's remarks)? I guess either Ted can take it through the ext4 tree
> or I can take it through my tree...
> 

I think taking it through your tree would be best, unless Al or Ted wants to
take it.

I'll probably separate out
"xfs: remove a stale comment from xfs_file_aio_write_checks()",
since it isn't really related anymore and could go in through the XFS tree.

- Eric


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 04/12] fat: only specify I_DIRTY_TIME when needed in fat_update_time()
  2021-01-11 19:50       ` [f2fs-dev] " Eric Biggers
@ 2021-01-12  5:21         ` Dave Chinner
  -1 siblings, 0 replies; 82+ messages in thread
From: Dave Chinner @ 2021-01-12  5:21 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Christoph Hellwig, linux-fsdevel, linux-xfs, linux-ext4,
	linux-f2fs-devel, Theodore Ts'o

On Mon, Jan 11, 2021 at 11:50:27AM -0800, Eric Biggers wrote:
> On Mon, Jan 11, 2021 at 11:52:01AM +0100, Christoph Hellwig wrote:
> > On Fri, Jan 08, 2021 at 11:58:55PM -0800, Eric Biggers wrote:
> > > +	if ((flags & S_VERSION) && inode_maybe_inc_iversion(inode, false))
> > > +		dirty_flags |= I_DIRTY_SYNC;
> > 
> > fat does not support i_version updates, so this bit can be skipped.
> 
> Is that really the case?  Any filesystem (including fat) can be mounted with
> "iversion", which causes SB_I_VERSION to be set.

That's a bug. Filesystems taht don't support persistent i_version on
disk need to clear SB_I_VERSION in their mount and remount paths
because the VFS iversion mount option was a complete screwup from
the start.

> A lot of filesystems (including fat) don't store i_version to disk, but it looks
> like it will still get updated in-memory.  Could anything be relying on that?

If they do, then they are broken by definition. i_version as
reported to observers is defined as monotonically increasing with
every change to the inode. i.e. it never goes backwards. Which, of
course, it will do if you crash or even just unmount/mount a
filesystem that doesn't persist it.

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 04/12] fat: only specify I_DIRTY_TIME when needed in fat_update_time()
@ 2021-01-12  5:21         ` Dave Chinner
  0 siblings, 0 replies; 82+ messages in thread
From: Dave Chinner @ 2021-01-12  5:21 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Mon, Jan 11, 2021 at 11:50:27AM -0800, Eric Biggers wrote:
> On Mon, Jan 11, 2021 at 11:52:01AM +0100, Christoph Hellwig wrote:
> > On Fri, Jan 08, 2021 at 11:58:55PM -0800, Eric Biggers wrote:
> > > +	if ((flags & S_VERSION) && inode_maybe_inc_iversion(inode, false))
> > > +		dirty_flags |= I_DIRTY_SYNC;
> > 
> > fat does not support i_version updates, so this bit can be skipped.
> 
> Is that really the case?  Any filesystem (including fat) can be mounted with
> "iversion", which causes SB_I_VERSION to be set.

That's a bug. Filesystems taht don't support persistent i_version on
disk need to clear SB_I_VERSION in their mount and remount paths
because the VFS iversion mount option was a complete screwup from
the start.

> A lot of filesystems (including fat) don't store i_version to disk, but it looks
> like it will still get updated in-memory.  Could anything be relying on that?

If they do, then they are broken by definition. i_version as
reported to observers is defined as monotonically increasing with
every change to the inode. i.e. it never goes backwards. Which, of
course, it will do if you crash or even just unmount/mount a
filesystem that doesn't persist it.

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 04/12] fat: only specify I_DIRTY_TIME when needed in fat_update_time()
  2021-01-11 19:50       ` [f2fs-dev] " Eric Biggers
@ 2021-01-12 13:23         ` Christoph Hellwig
  -1 siblings, 0 replies; 82+ messages in thread
From: Christoph Hellwig @ 2021-01-12 13:23 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Christoph Hellwig, linux-fsdevel, linux-xfs, linux-ext4,
	linux-f2fs-devel, Theodore Ts'o

On Mon, Jan 11, 2021 at 11:50:27AM -0800, Eric Biggers wrote:
> On Mon, Jan 11, 2021 at 11:52:01AM +0100, Christoph Hellwig wrote:
> > On Fri, Jan 08, 2021 at 11:58:55PM -0800, Eric Biggers wrote:
> > > +	if ((flags & S_VERSION) && inode_maybe_inc_iversion(inode, false))
> > > +		dirty_flags |= I_DIRTY_SYNC;
> > 
> > fat does not support i_version updates, so this bit can be skipped.
> 
> Is that really the case?  Any filesystem (including fat) can be mounted with
> "iversion", which causes SB_I_VERSION to be set.
> 
> A lot of filesystems (including fat) don't store i_version to disk, but it looks
> like it will still get updated in-memory.  Could anything be relying on that?

As Dave pointed out i_version can't really work for fat.  But I guess
that is indeed out of scope for this series, so let's go ahead with this
version for now:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 04/12] fat: only specify I_DIRTY_TIME when needed in fat_update_time()
@ 2021-01-12 13:23         ` Christoph Hellwig
  0 siblings, 0 replies; 82+ messages in thread
From: Christoph Hellwig @ 2021-01-12 13:23 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Mon, Jan 11, 2021 at 11:50:27AM -0800, Eric Biggers wrote:
> On Mon, Jan 11, 2021 at 11:52:01AM +0100, Christoph Hellwig wrote:
> > On Fri, Jan 08, 2021 at 11:58:55PM -0800, Eric Biggers wrote:
> > > +	if ((flags & S_VERSION) && inode_maybe_inc_iversion(inode, false))
> > > +		dirty_flags |= I_DIRTY_SYNC;
> > 
> > fat does not support i_version updates, so this bit can be skipped.
> 
> Is that really the case?  Any filesystem (including fat) can be mounted with
> "iversion", which causes SB_I_VERSION to be set.
> 
> A lot of filesystems (including fat) don't store i_version to disk, but it looks
> like it will still get updated in-memory.  Could anything be relying on that?

As Dave pointed out i_version can't really work for fat.  But I guess
that is indeed out of scope for this series, so let's go ahead with this
version for now:

Reviewed-by: Christoph Hellwig <hch@lst.de>


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 11/12] ext4: simplify i_state checks in __ext4_update_other_inode_time()
  2021-01-11 20:23       ` [f2fs-dev] " Eric Biggers
@ 2021-01-12 13:25         ` Christoph Hellwig
  -1 siblings, 0 replies; 82+ messages in thread
From: Christoph Hellwig @ 2021-01-12 13:25 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Christoph Hellwig, linux-fsdevel, linux-xfs, linux-ext4,
	linux-f2fs-devel, Theodore Ts'o

On Mon, Jan 11, 2021 at 12:23:40PM -0800, Eric Biggers wrote:
> > I think a descriptively named inline helper in fs.h would really improve
> > this..
> 
> Do you want this even though it is specific to how ext4 opportunisticly updates
> other inodes in the same inode block as the inode being updated?  That's the
> only reason that I_FREEING|I_WILL_FREE|I_NEW need to be checked; everywhere else
> justs want I_DIRTY_TIME.
> 
> We could add:
> 
> 	static inline bool other_inode_has_dirtytime(struct inode *inode)
> 	{
> 		return (inode->state & (I_FREEING | I_WILL_FREE |
> 					I_NEW | I_DIRTY_TIME)) == I_DIRTY_TIME;
> 	}
> 
> But it seems a bit weird when it's specific to ext4 at the moment.
> 
> Are you thinking that other filesystems will implement the same sort of
> opportunistic update, so we should add the helper now?

For my taste these checks for flags is way too much black magic and will
trivially break when people add new flags.  So having a helper next to
the definition of the I_* flags that is well documented would be very,
very helpful.  My preferred naming would be something along the lines
of 'inode_is_dirty_lazytime_only()'.

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 11/12] ext4: simplify i_state checks in __ext4_update_other_inode_time()
@ 2021-01-12 13:25         ` Christoph Hellwig
  0 siblings, 0 replies; 82+ messages in thread
From: Christoph Hellwig @ 2021-01-12 13:25 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Mon, Jan 11, 2021 at 12:23:40PM -0800, Eric Biggers wrote:
> > I think a descriptively named inline helper in fs.h would really improve
> > this..
> 
> Do you want this even though it is specific to how ext4 opportunisticly updates
> other inodes in the same inode block as the inode being updated?  That's the
> only reason that I_FREEING|I_WILL_FREE|I_NEW need to be checked; everywhere else
> justs want I_DIRTY_TIME.
> 
> We could add:
> 
> 	static inline bool other_inode_has_dirtytime(struct inode *inode)
> 	{
> 		return (inode->state & (I_FREEING | I_WILL_FREE |
> 					I_NEW | I_DIRTY_TIME)) == I_DIRTY_TIME;
> 	}
> 
> But it seems a bit weird when it's specific to ext4 at the moment.
> 
> Are you thinking that other filesystems will implement the same sort of
> opportunistic update, so we should add the helper now?

For my taste these checks for flags is way too much black magic and will
trivially break when people add new flags.  So having a helper next to
the definition of the I_* flags that is well documented would be very,
very helpful.  My preferred naming would be something along the lines
of 'inode_is_dirty_lazytime_only()'.


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 12/12] xfs: remove a stale comment from xfs_file_aio_write_checks()
  2021-01-09  7:59   ` [f2fs-dev] " Eric Biggers
@ 2021-01-12 17:31     ` Darrick J. Wong
  -1 siblings, 0 replies; 82+ messages in thread
From: Darrick J. Wong @ 2021-01-12 17:31 UTC (permalink / raw)
  To: Eric Biggers
  Cc: linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Theodore Ts'o, Christoph Hellwig

On Fri, Jan 08, 2021 at 11:59:03PM -0800, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> The comment in xfs_file_aio_write_checks() about calling file_modified()
> after dropping the ilock doesn't make sense, because the code that
> unconditionally acquires and drops the ilock was removed by
> commit 467f78992a07 ("xfs: reduce ilock hold times in
> xfs_file_aio_write_checks").
> 
> Remove this outdated comment.
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Yep, thanks for the update. :)

Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

> ---
>  fs/xfs/xfs_file.c | 6 ------
>  1 file changed, 6 deletions(-)
> 
> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> index 5b0f93f738372..4927c6653f15d 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -389,12 +389,6 @@ xfs_file_aio_write_checks(
>  	} else
>  		spin_unlock(&ip->i_flags_lock);
>  
> -	/*
> -	 * Updating the timestamps will grab the ilock again from
> -	 * xfs_fs_dirty_inode, so we have to call it after dropping the
> -	 * lock above.  Eventually we should look into a way to avoid
> -	 * the pointless lock roundtrip.
> -	 */
>  	return file_modified(file);
>  }
>  
> -- 
> 2.30.0
> 

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 12/12] xfs: remove a stale comment from xfs_file_aio_write_checks()
@ 2021-01-12 17:31     ` Darrick J. Wong
  0 siblings, 0 replies; 82+ messages in thread
From: Darrick J. Wong @ 2021-01-12 17:31 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Theodore Ts'o, linux-f2fs-devel, linux-xfs, linux-fsdevel,
	linux-ext4, Christoph Hellwig

On Fri, Jan 08, 2021 at 11:59:03PM -0800, Eric Biggers wrote:
> From: Eric Biggers <ebiggers@google.com>
> 
> The comment in xfs_file_aio_write_checks() about calling file_modified()
> after dropping the ilock doesn't make sense, because the code that
> unconditionally acquires and drops the ilock was removed by
> commit 467f78992a07 ("xfs: reduce ilock hold times in
> xfs_file_aio_write_checks").
> 
> Remove this outdated comment.
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Eric Biggers <ebiggers@google.com>

Yep, thanks for the update. :)

Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

> ---
>  fs/xfs/xfs_file.c | 6 ------
>  1 file changed, 6 deletions(-)
> 
> diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
> index 5b0f93f738372..4927c6653f15d 100644
> --- a/fs/xfs/xfs_file.c
> +++ b/fs/xfs/xfs_file.c
> @@ -389,12 +389,6 @@ xfs_file_aio_write_checks(
>  	} else
>  		spin_unlock(&ip->i_flags_lock);
>  
> -	/*
> -	 * Updating the timestamps will grab the ilock again from
> -	 * xfs_fs_dirty_inode, so we have to call it after dropping the
> -	 * lock above.  Eventually we should look into a way to avoid
> -	 * the pointless lock roundtrip.
> -	 */
>  	return file_modified(file);
>  }
>  
> -- 
> 2.30.0
> 


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 00/12] lazytime fix and cleanups
  2021-01-11 20:44     ` [f2fs-dev] " Eric Biggers
@ 2021-02-03  5:11       ` Theodore Ts'o
  -1 siblings, 0 replies; 82+ messages in thread
From: Theodore Ts'o @ 2021-02-03  5:11 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Jan Kara, linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Christoph Hellwig

On Mon, Jan 11, 2021 at 12:44:35PM -0800, Eric Biggers wrote:
> > 
> > The series look good to me. How do you plan to merge it (after resolving
> > Christoph's remarks)? I guess either Ted can take it through the ext4 tree
> > or I can take it through my tree...
> 
> I think taking it through your tree would be best, unless Al or Ted wants to
> take it.

I'm happy to take it through the ext4 tree.  Are you planning on
issuing a newer version of this patch series to resolve Christoph's
comments?

					- Ted

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 00/12] lazytime fix and cleanups
@ 2021-02-03  5:11       ` Theodore Ts'o
  0 siblings, 0 replies; 82+ messages in thread
From: Theodore Ts'o @ 2021-02-03  5:11 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Jan Kara, linux-f2fs-devel, linux-xfs, linux-fsdevel, linux-ext4,
	Christoph Hellwig

On Mon, Jan 11, 2021 at 12:44:35PM -0800, Eric Biggers wrote:
> > 
> > The series look good to me. How do you plan to merge it (after resolving
> > Christoph's remarks)? I guess either Ted can take it through the ext4 tree
> > or I can take it through my tree...
> 
> I think taking it through your tree would be best, unless Al or Ted wants to
> take it.

I'm happy to take it through the ext4 tree.  Are you planning on
issuing a newer version of this patch series to resolve Christoph's
comments?

					- Ted


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 11/12] ext4: simplify i_state checks in __ext4_update_other_inode_time()
  2021-01-12 13:25         ` [f2fs-dev] " Christoph Hellwig
@ 2021-02-03  5:16           ` Theodore Ts'o
  -1 siblings, 0 replies; 82+ messages in thread
From: Theodore Ts'o @ 2021-02-03  5:16 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Eric Biggers, linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel

On Tue, Jan 12, 2021 at 02:25:21PM +0100, Christoph Hellwig wrote:
> > We could add:
> > 
> > 	static inline bool other_inode_has_dirtytime(struct inode *inode)
> > 	{
> > 		return (inode->state & (I_FREEING | I_WILL_FREE |
> > 					I_NEW | I_DIRTY_TIME)) == I_DIRTY_TIME;
> > 	}
> > 
> > But it seems a bit weird when it's specific to ext4 at the moment.
> > 
> > Are you thinking that other filesystems will implement the same sort of
> > opportunistic update, so we should add the helper now?
> 
> For my taste these checks for flags is way too much black magic and will
> trivially break when people add new flags.  So having a helper next to
> the definition of the I_* flags that is well documented would be very,
> very helpful.  My preferred naming would be something along the lines
> of 'inode_is_dirty_lazytime_only()'.

The name makes sense to me.  I'm not sure it's likely that there will
be new types of dirtiness --- as near I can tell the I_DIRTY_TIME was
the first time there has been any changes in a _really_ long time, but
I agree that how the flags interact (even before we added
I_DIRTY_TIME) involved no small amount of black magic, and it's the
kind of thing that requires deep meditation before trying to make any
changes, and then immediately slips out of one's L1 cache very shortly
afterwards.  :-)

					- Ted

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 11/12] ext4: simplify i_state checks in __ext4_update_other_inode_time()
@ 2021-02-03  5:16           ` Theodore Ts'o
  0 siblings, 0 replies; 82+ messages in thread
From: Theodore Ts'o @ 2021-02-03  5:16 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Eric Biggers, linux-fsdevel, linux-ext4, linux-xfs, linux-f2fs-devel

On Tue, Jan 12, 2021 at 02:25:21PM +0100, Christoph Hellwig wrote:
> > We could add:
> > 
> > 	static inline bool other_inode_has_dirtytime(struct inode *inode)
> > 	{
> > 		return (inode->state & (I_FREEING | I_WILL_FREE |
> > 					I_NEW | I_DIRTY_TIME)) == I_DIRTY_TIME;
> > 	}
> > 
> > But it seems a bit weird when it's specific to ext4 at the moment.
> > 
> > Are you thinking that other filesystems will implement the same sort of
> > opportunistic update, so we should add the helper now?
> 
> For my taste these checks for flags is way too much black magic and will
> trivially break when people add new flags.  So having a helper next to
> the definition of the I_* flags that is well documented would be very,
> very helpful.  My preferred naming would be something along the lines
> of 'inode_is_dirty_lazytime_only()'.

The name makes sense to me.  I'm not sure it's likely that there will
be new types of dirtiness --- as near I can tell the I_DIRTY_TIME was
the first time there has been any changes in a _really_ long time, but
I agree that how the flags interact (even before we added
I_DIRTY_TIME) involved no small amount of black magic, and it's the
kind of thing that requires deep meditation before trying to make any
changes, and then immediately slips out of one's L1 cache very shortly
afterwards.  :-)

					- Ted


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 00/12] lazytime fix and cleanups
  2021-02-03  5:11       ` [f2fs-dev] " Theodore Ts'o
@ 2021-02-03  5:22         ` Eric Biggers
  -1 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-02-03  5:22 UTC (permalink / raw)
  To: Theodore Ts'o
  Cc: Jan Kara, linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Christoph Hellwig

On Wed, Feb 03, 2021 at 12:11:52AM -0500, Theodore Ts'o wrote:
> On Mon, Jan 11, 2021 at 12:44:35PM -0800, Eric Biggers wrote:
> > > 
> > > The series look good to me. How do you plan to merge it (after resolving
> > > Christoph's remarks)? I guess either Ted can take it through the ext4 tree
> > > or I can take it through my tree...
> > 
> > I think taking it through your tree would be best, unless Al or Ted wants to
> > take it.
> 
> I'm happy to take it through the ext4 tree.  Are you planning on
> issuing a newer version of this patch series to resolve Christoph's
> comments?
> 
> 					- Ted

I already sent out v3 of this series several weeks ago
(https://lkml.kernel.org/r/20210112190253.64307-1-ebiggers@kernel.org),
and Jan applied it already.

- Eric

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 00/12] lazytime fix and cleanups
@ 2021-02-03  5:22         ` Eric Biggers
  0 siblings, 0 replies; 82+ messages in thread
From: Eric Biggers @ 2021-02-03  5:22 UTC (permalink / raw)
  To: Theodore Ts'o
  Cc: Jan Kara, linux-f2fs-devel, linux-xfs, linux-fsdevel, linux-ext4,
	Christoph Hellwig

On Wed, Feb 03, 2021 at 12:11:52AM -0500, Theodore Ts'o wrote:
> On Mon, Jan 11, 2021 at 12:44:35PM -0800, Eric Biggers wrote:
> > > 
> > > The series look good to me. How do you plan to merge it (after resolving
> > > Christoph's remarks)? I guess either Ted can take it through the ext4 tree
> > > or I can take it through my tree...
> > 
> > I think taking it through your tree would be best, unless Al or Ted wants to
> > take it.
> 
> I'm happy to take it through the ext4 tree.  Are you planning on
> issuing a newer version of this patch series to resolve Christoph's
> comments?
> 
> 					- Ted

I already sent out v3 of this series several weeks ago
(https://lkml.kernel.org/r/20210112190253.64307-1-ebiggers@kernel.org),
and Jan applied it already.

- Eric


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH v2 00/12] lazytime fix and cleanups
  2021-02-03  5:22         ` [f2fs-dev] " Eric Biggers
@ 2021-02-03 15:49           ` Theodore Ts'o
  -1 siblings, 0 replies; 82+ messages in thread
From: Theodore Ts'o @ 2021-02-03 15:49 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Jan Kara, linux-fsdevel, linux-xfs, linux-ext4, linux-f2fs-devel,
	Christoph Hellwig

On Tue, Feb 02, 2021 at 09:22:16PM -0800, Eric Biggers wrote:
> 
> I already sent out v3 of this series several weeks ago
> (https://lkml.kernel.org/r/20210112190253.64307-1-ebiggers@kernel.org),
> and Jan applied it already.

Great, thanks.  Sorry, I missed it.

       		       	 	- Ted

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [f2fs-dev] [PATCH v2 00/12] lazytime fix and cleanups
@ 2021-02-03 15:49           ` Theodore Ts'o
  0 siblings, 0 replies; 82+ messages in thread
From: Theodore Ts'o @ 2021-02-03 15:49 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Jan Kara, linux-f2fs-devel, linux-xfs, linux-fsdevel, linux-ext4,
	Christoph Hellwig

On Tue, Feb 02, 2021 at 09:22:16PM -0800, Eric Biggers wrote:
> 
> I already sent out v3 of this series several weeks ago
> (https://lkml.kernel.org/r/20210112190253.64307-1-ebiggers@kernel.org),
> and Jan applied it already.

Great, thanks.  Sorry, I missed it.

       		       	 	- Ted


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 82+ messages in thread

end of thread, other threads:[~2021-02-03 15:51 UTC | newest]

Thread overview: 82+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-09  7:58 [PATCH v2 00/12] lazytime fix and cleanups Eric Biggers
2021-01-09  7:58 ` [f2fs-dev] " Eric Biggers
2021-01-09  7:58 ` [PATCH v2 01/12] fs: fix lazytime expiration handling in __writeback_single_inode() Eric Biggers
2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
2021-01-11 10:48   ` Christoph Hellwig
2021-01-11 10:48     ` [f2fs-dev] " Christoph Hellwig
2021-01-11 14:46   ` Jan Kara
2021-01-11 14:46     ` [f2fs-dev] " Jan Kara
2021-01-09  7:58 ` [PATCH v2 02/12] fs: correctly document the inode dirty flags Eric Biggers
2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
2021-01-11 14:48   ` Jan Kara
2021-01-11 14:48     ` [f2fs-dev] " Jan Kara
2021-01-09  7:58 ` [PATCH v2 03/12] fs: only specify I_DIRTY_TIME when needed in generic_update_time() Eric Biggers
2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
2021-01-11 14:50   ` Jan Kara
2021-01-11 14:50     ` [f2fs-dev] " Jan Kara
2021-01-09  7:58 ` [PATCH v2 04/12] fat: only specify I_DIRTY_TIME when needed in fat_update_time() Eric Biggers
2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
2021-01-11 10:52   ` Christoph Hellwig
2021-01-11 10:52     ` [f2fs-dev] " Christoph Hellwig
2021-01-11 19:50     ` Eric Biggers
2021-01-11 19:50       ` [f2fs-dev] " Eric Biggers
2021-01-12  5:21       ` Dave Chinner
2021-01-12  5:21         ` [f2fs-dev] " Dave Chinner
2021-01-12 13:23       ` Christoph Hellwig
2021-01-12 13:23         ` [f2fs-dev] " Christoph Hellwig
2021-01-11 14:52   ` Jan Kara
2021-01-11 14:52     ` [f2fs-dev] " Jan Kara
2021-01-09  7:58 ` [PATCH v2 05/12] fs: don't call ->dirty_inode for lazytime timestamp updates Eric Biggers
2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
2021-01-11 14:54   ` Jan Kara
2021-01-11 14:54     ` [f2fs-dev] " Jan Kara
2021-01-09  7:58 ` [PATCH v2 06/12] fs: pass only I_DIRTY_INODE flags to ->dirty_inode Eric Biggers
2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
2021-01-11 14:56   ` Jan Kara
2021-01-11 14:56     ` [f2fs-dev] " Jan Kara
2021-01-09  7:58 ` [PATCH v2 07/12] fs: clean up __mark_inode_dirty() a bit Eric Biggers
2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
2021-01-11 14:59   ` Jan Kara
2021-01-11 14:59     ` [f2fs-dev] " Jan Kara
2021-01-09  7:58 ` [PATCH v2 08/12] fs: drop redundant check from __writeback_single_inode() Eric Biggers
2021-01-09  7:58   ` [f2fs-dev] " Eric Biggers
2021-01-11 10:52   ` Christoph Hellwig
2021-01-11 10:52     ` [f2fs-dev] " Christoph Hellwig
2021-01-11 15:00   ` Jan Kara
2021-01-11 15:00     ` [f2fs-dev] " Jan Kara
2021-01-09  7:59 ` [PATCH v2 09/12] fs: improve comments for writeback_single_inode() Eric Biggers
2021-01-09  7:59   ` [f2fs-dev] " Eric Biggers
2021-01-11 10:53   ` Christoph Hellwig
2021-01-11 10:53     ` [f2fs-dev] " Christoph Hellwig
2021-01-11 15:05   ` Jan Kara
2021-01-11 15:05     ` [f2fs-dev] " Jan Kara
2021-01-09  7:59 ` [PATCH v2 10/12] gfs2: don't worry about I_DIRTY_TIME in gfs2_fsync() Eric Biggers
2021-01-09  7:59   ` [f2fs-dev] " Eric Biggers
2021-01-11 15:06   ` Jan Kara
2021-01-11 15:06     ` [f2fs-dev] " Jan Kara
2021-01-09  7:59 ` [PATCH v2 11/12] ext4: simplify i_state checks in __ext4_update_other_inode_time() Eric Biggers
2021-01-09  7:59   ` [f2fs-dev] " Eric Biggers
2021-01-11 10:53   ` Christoph Hellwig
2021-01-11 10:53     ` [f2fs-dev] " Christoph Hellwig
2021-01-11 20:23     ` Eric Biggers
2021-01-11 20:23       ` [f2fs-dev] " Eric Biggers
2021-01-12 13:25       ` Christoph Hellwig
2021-01-12 13:25         ` [f2fs-dev] " Christoph Hellwig
2021-02-03  5:16         ` Theodore Ts'o
2021-02-03  5:16           ` [f2fs-dev] " Theodore Ts'o
2021-01-11 15:11   ` Jan Kara
2021-01-11 15:11     ` [f2fs-dev] " Jan Kara
2021-01-09  7:59 ` [PATCH v2 12/12] xfs: remove a stale comment from xfs_file_aio_write_checks() Eric Biggers
2021-01-09  7:59   ` [f2fs-dev] " Eric Biggers
2021-01-12 17:31   ` Darrick J. Wong
2021-01-12 17:31     ` [f2fs-dev] " Darrick J. Wong
2021-01-11 15:15 ` [PATCH v2 00/12] lazytime fix and cleanups Jan Kara
2021-01-11 15:15   ` [f2fs-dev] " Jan Kara
2021-01-11 20:44   ` Eric Biggers
2021-01-11 20:44     ` [f2fs-dev] " Eric Biggers
2021-02-03  5:11     ` Theodore Ts'o
2021-02-03  5:11       ` [f2fs-dev] " Theodore Ts'o
2021-02-03  5:22       ` Eric Biggers
2021-02-03  5:22         ` [f2fs-dev] " Eric Biggers
2021-02-03 15:49         ` Theodore Ts'o
2021-02-03 15:49           ` [f2fs-dev] " Theodore Ts'o

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.