]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.15
authorSasha Levin <sashal@kernel.org>
Wed, 20 Apr 2022 14:51:24 +0000 (10:51 -0400)
committerSasha Levin <sashal@kernel.org>
Wed, 20 Apr 2022 14:51:24 +0000 (10:51 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.15/block-remove-__sync_blockdev.patch [new file with mode: 0644]
queue-5.15/block-simplify-the-block-device-syncing-code.patch [new file with mode: 0644]
queue-5.15/fs-remove-__sync_filesystem.patch [new file with mode: 0644]
queue-5.15/series [new file with mode: 0644]
queue-5.15/vfs-make-sync_filesystem-return-errors-from-sync_fs.patch [new file with mode: 0644]
queue-5.15/xfs-return-errors-in-xfs_fs_sync_fs.patch [new file with mode: 0644]

diff --git a/queue-5.15/block-remove-__sync_blockdev.patch b/queue-5.15/block-remove-__sync_blockdev.patch
new file mode 100644 (file)
index 0000000..c6a0b35
--- /dev/null
@@ -0,0 +1,143 @@
+From 0f5da9dac07c4bf3add7da401bbe39893143480f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Oct 2021 08:25:25 +0200
+Subject: block: remove __sync_blockdev
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 70164eb6ccb76ab679b016b4b60123bf4ec6c162 ]
+
+Instead offer a new sync_blockdev_nowait helper for the !wait case.
+This new helper is exported as it will grow modular callers in a bit.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20211019062530.2174626-3-hch@lst.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bdev.c           | 11 ++++++-----
+ fs/internal.h          |  5 -----
+ fs/sync.c              |  7 ++++---
+ include/linux/blkdev.h |  5 +++++
+ 4 files changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/block/bdev.c b/block/bdev.c
+index 485a258b0ab3..33cac289302e 100644
+--- a/block/bdev.c
++++ b/block/bdev.c
+@@ -184,14 +184,13 @@ int sb_min_blocksize(struct super_block *sb, int size)
+ EXPORT_SYMBOL(sb_min_blocksize);
+-int __sync_blockdev(struct block_device *bdev, int wait)
++int sync_blockdev_nowait(struct block_device *bdev)
+ {
+       if (!bdev)
+               return 0;
+-      if (!wait)
+-              return filemap_flush(bdev->bd_inode->i_mapping);
+-      return filemap_write_and_wait(bdev->bd_inode->i_mapping);
++      return filemap_flush(bdev->bd_inode->i_mapping);
+ }
++EXPORT_SYMBOL_GPL(sync_blockdev_nowait);
+ /*
+  * Write out and wait upon all the dirty data associated with a block
+@@ -199,7 +198,9 @@ int __sync_blockdev(struct block_device *bdev, int wait)
+  */
+ int sync_blockdev(struct block_device *bdev)
+ {
+-      return __sync_blockdev(bdev, 1);
++      if (!bdev)
++              return 0;
++      return filemap_write_and_wait(bdev->bd_inode->i_mapping);
+ }
+ EXPORT_SYMBOL(sync_blockdev);
+diff --git a/fs/internal.h b/fs/internal.h
+index 3cd065c8a66b..b5caa16f4645 100644
+--- a/fs/internal.h
++++ b/fs/internal.h
+@@ -23,7 +23,6 @@ struct pipe_inode_info;
+ #ifdef CONFIG_BLOCK
+ extern void __init bdev_cache_init(void);
+-extern int __sync_blockdev(struct block_device *bdev, int wait);
+ void iterate_bdevs(void (*)(struct block_device *, void *), void *);
+ void emergency_thaw_bdev(struct super_block *sb);
+ #else
+@@ -31,10 +30,6 @@ static inline void bdev_cache_init(void)
+ {
+ }
+-static inline int __sync_blockdev(struct block_device *bdev, int wait)
+-{
+-      return 0;
+-}
+ static inline void iterate_bdevs(void (*f)(struct block_device *, void *),
+               void *arg)
+ {
+diff --git a/fs/sync.c b/fs/sync.c
+index 0d6cdc507cb9..a621089eb07e 100644
+--- a/fs/sync.c
++++ b/fs/sync.c
+@@ -3,6 +3,7 @@
+  * High-level sync()-related operations
+  */
++#include <linux/blkdev.h>
+ #include <linux/kernel.h>
+ #include <linux/file.h>
+ #include <linux/fs.h>
+@@ -45,7 +46,7 @@ int sync_filesystem(struct super_block *sb)
+       /*
+        * Do the filesystem syncing work.  For simple filesystems
+        * writeback_inodes_sb(sb) just dirties buffers with inodes so we have
+-       * to submit I/O for these buffers via __sync_blockdev().  This also
++       * to submit I/O for these buffers via sync_blockdev().  This also
+        * speeds up the wait == 1 case since in that case write_inode()
+        * methods call sync_dirty_buffer() and thus effectively write one block
+        * at a time.
+@@ -53,14 +54,14 @@ int sync_filesystem(struct super_block *sb)
+       writeback_inodes_sb(sb, WB_REASON_SYNC);
+       if (sb->s_op->sync_fs)
+               sb->s_op->sync_fs(sb, 0);
+-      ret = __sync_blockdev(sb->s_bdev, 0);
++      ret = sync_blockdev_nowait(sb->s_bdev);
+       if (ret < 0)
+               return ret;
+       sync_inodes_sb(sb);
+       if (sb->s_op->sync_fs)
+               sb->s_op->sync_fs(sb, 1);
+-      return __sync_blockdev(sb->s_bdev, 1);
++      return sync_blockdev(sb->s_bdev);
+ }
+ EXPORT_SYMBOL(sync_filesystem);
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 413c0148c0ce..6bbd393e6bcc 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -1999,6 +1999,7 @@ int truncate_bdev_range(struct block_device *bdev, fmode_t mode, loff_t lstart,
+ #ifdef CONFIG_BLOCK
+ void invalidate_bdev(struct block_device *bdev);
+ int sync_blockdev(struct block_device *bdev);
++int sync_blockdev_nowait(struct block_device *bdev);
+ #else
+ static inline void invalidate_bdev(struct block_device *bdev)
+ {
+@@ -2007,6 +2008,10 @@ static inline int sync_blockdev(struct block_device *bdev)
+ {
+       return 0;
+ }
++static inline int sync_blockdev_nowait(struct block_device *bdev)
++{
++      return 0;
++}
+ #endif
+ int fsync_bdev(struct block_device *bdev);
+-- 
+2.35.1
+
diff --git a/queue-5.15/block-simplify-the-block-device-syncing-code.patch b/queue-5.15/block-simplify-the-block-device-syncing-code.patch
new file mode 100644 (file)
index 0000000..225d559
--- /dev/null
@@ -0,0 +1,155 @@
+From 22110c694ece8b06a1f0625f9b1b5656726005f6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Oct 2021 08:25:30 +0200
+Subject: block: simplify the block device syncing code
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 1e03a36bdff4709c1bbf0f57f60ae3f776d51adf ]
+
+Get rid of the indirections and just provide a sync_bdevs
+helper for the generic sync code.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20211019062530.2174626-8-hch@lst.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bdev.c           | 17 ++++++++++++++---
+ fs/internal.h          |  6 ------
+ fs/sync.c              | 23 ++++-------------------
+ include/linux/blkdev.h |  4 ++++
+ 4 files changed, 22 insertions(+), 28 deletions(-)
+
+diff --git a/block/bdev.c b/block/bdev.c
+index 33cac289302e..18abafb135e0 100644
+--- a/block/bdev.c
++++ b/block/bdev.c
+@@ -1017,7 +1017,7 @@ int __invalidate_device(struct block_device *bdev, bool kill_dirty)
+ }
+ EXPORT_SYMBOL(__invalidate_device);
+-void iterate_bdevs(void (*func)(struct block_device *, void *), void *arg)
++void sync_bdevs(bool wait)
+ {
+       struct inode *inode, *old_inode = NULL;
+@@ -1048,8 +1048,19 @@ void iterate_bdevs(void (*func)(struct block_device *, void *), void *arg)
+               bdev = I_BDEV(inode);
+               mutex_lock(&bdev->bd_disk->open_mutex);
+-              if (bdev->bd_openers)
+-                      func(bdev, arg);
++              if (!bdev->bd_openers) {
++                      ; /* skip */
++              } else if (wait) {
++                      /*
++                       * We keep the error status of individual mapping so
++                       * that applications can catch the writeback error using
++                       * fsync(2). See filemap_fdatawait_keep_errors() for
++                       * details.
++                       */
++                      filemap_fdatawait_keep_errors(inode->i_mapping);
++              } else {
++                      filemap_fdatawrite(inode->i_mapping);
++              }
+               mutex_unlock(&bdev->bd_disk->open_mutex);
+               spin_lock(&blockdev_superblock->s_inode_list_lock);
+diff --git a/fs/internal.h b/fs/internal.h
+index b5caa16f4645..cdd83d4899bb 100644
+--- a/fs/internal.h
++++ b/fs/internal.h
+@@ -23,17 +23,11 @@ struct pipe_inode_info;
+ #ifdef CONFIG_BLOCK
+ extern void __init bdev_cache_init(void);
+-void iterate_bdevs(void (*)(struct block_device *, void *), void *);
+ void emergency_thaw_bdev(struct super_block *sb);
+ #else
+ static inline void bdev_cache_init(void)
+ {
+ }
+-
+-static inline void iterate_bdevs(void (*f)(struct block_device *, void *),
+-              void *arg)
+-{
+-}
+ static inline int emergency_thaw_bdev(struct super_block *sb)
+ {
+       return 0;
+diff --git a/fs/sync.c b/fs/sync.c
+index a621089eb07e..3ce8e2137f31 100644
+--- a/fs/sync.c
++++ b/fs/sync.c
+@@ -78,21 +78,6 @@ static void sync_fs_one_sb(struct super_block *sb, void *arg)
+               sb->s_op->sync_fs(sb, *(int *)arg);
+ }
+-static void fdatawrite_one_bdev(struct block_device *bdev, void *arg)
+-{
+-      filemap_fdatawrite(bdev->bd_inode->i_mapping);
+-}
+-
+-static void fdatawait_one_bdev(struct block_device *bdev, void *arg)
+-{
+-      /*
+-       * We keep the error status of individual mapping so that
+-       * applications can catch the writeback error using fsync(2).
+-       * See filemap_fdatawait_keep_errors() for details.
+-       */
+-      filemap_fdatawait_keep_errors(bdev->bd_inode->i_mapping);
+-}
+-
+ /*
+  * Sync everything. We start by waking flusher threads so that most of
+  * writeback runs on all devices in parallel. Then we sync all inodes reliably
+@@ -111,8 +96,8 @@ void ksys_sync(void)
+       iterate_supers(sync_inodes_one_sb, NULL);
+       iterate_supers(sync_fs_one_sb, &nowait);
+       iterate_supers(sync_fs_one_sb, &wait);
+-      iterate_bdevs(fdatawrite_one_bdev, NULL);
+-      iterate_bdevs(fdatawait_one_bdev, NULL);
++      sync_bdevs(false);
++      sync_bdevs(true);
+       if (unlikely(laptop_mode))
+               laptop_sync_completion();
+ }
+@@ -133,10 +118,10 @@ static void do_sync_work(struct work_struct *work)
+        */
+       iterate_supers(sync_inodes_one_sb, &nowait);
+       iterate_supers(sync_fs_one_sb, &nowait);
+-      iterate_bdevs(fdatawrite_one_bdev, NULL);
++      sync_bdevs(false);
+       iterate_supers(sync_inodes_one_sb, &nowait);
+       iterate_supers(sync_fs_one_sb, &nowait);
+-      iterate_bdevs(fdatawrite_one_bdev, NULL);
++      sync_bdevs(false);
+       printk("Emergency Sync complete\n");
+       kfree(work);
+ }
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index 6bbd393e6bcc..aebe67ed7a73 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -2000,6 +2000,7 @@ int truncate_bdev_range(struct block_device *bdev, fmode_t mode, loff_t lstart,
+ void invalidate_bdev(struct block_device *bdev);
+ int sync_blockdev(struct block_device *bdev);
+ int sync_blockdev_nowait(struct block_device *bdev);
++void sync_bdevs(bool wait);
+ #else
+ static inline void invalidate_bdev(struct block_device *bdev)
+ {
+@@ -2012,6 +2013,9 @@ static inline int sync_blockdev_nowait(struct block_device *bdev)
+ {
+       return 0;
+ }
++static inline void sync_bdevs(bool wait)
++{
++}
+ #endif
+ int fsync_bdev(struct block_device *bdev);
+-- 
+2.35.1
+
diff --git a/queue-5.15/fs-remove-__sync_filesystem.patch b/queue-5.15/fs-remove-__sync_filesystem.patch
new file mode 100644 (file)
index 0000000..537389a
--- /dev/null
@@ -0,0 +1,81 @@
+From 7370977fefdc738478af84515fdc1dcdc44f201e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Oct 2021 08:25:24 +0200
+Subject: fs: remove __sync_filesystem
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 9a208ba5c9afa62c7b1e9c6f5e783066e84e2d3c ]
+
+There is no clear benefit in having this helper vs just open coding it.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
+Link: https://lore.kernel.org/r/20211019062530.2174626-2-hch@lst.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/sync.c | 38 +++++++++++++++++---------------------
+ 1 file changed, 17 insertions(+), 21 deletions(-)
+
+diff --git a/fs/sync.c b/fs/sync.c
+index 1373a610dc78..0d6cdc507cb9 100644
+--- a/fs/sync.c
++++ b/fs/sync.c
+@@ -21,25 +21,6 @@
+ #define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \
+                       SYNC_FILE_RANGE_WAIT_AFTER)
+-/*
+- * Do the filesystem syncing work. For simple filesystems
+- * writeback_inodes_sb(sb) just dirties buffers with inodes so we have to
+- * submit IO for these buffers via __sync_blockdev(). This also speeds up the
+- * wait == 1 case since in that case write_inode() functions do
+- * sync_dirty_buffer() and thus effectively write one block at a time.
+- */
+-static int __sync_filesystem(struct super_block *sb, int wait)
+-{
+-      if (wait)
+-              sync_inodes_sb(sb);
+-      else
+-              writeback_inodes_sb(sb, WB_REASON_SYNC);
+-
+-      if (sb->s_op->sync_fs)
+-              sb->s_op->sync_fs(sb, wait);
+-      return __sync_blockdev(sb->s_bdev, wait);
+-}
+-
+ /*
+  * Write out and wait upon all dirty data associated with this
+  * superblock.  Filesystem data as well as the underlying block
+@@ -61,10 +42,25 @@ int sync_filesystem(struct super_block *sb)
+       if (sb_rdonly(sb))
+               return 0;
+-      ret = __sync_filesystem(sb, 0);
++      /*
++       * Do the filesystem syncing work.  For simple filesystems
++       * writeback_inodes_sb(sb) just dirties buffers with inodes so we have
++       * to submit I/O for these buffers via __sync_blockdev().  This also
++       * speeds up the wait == 1 case since in that case write_inode()
++       * methods call sync_dirty_buffer() and thus effectively write one block
++       * at a time.
++       */
++      writeback_inodes_sb(sb, WB_REASON_SYNC);
++      if (sb->s_op->sync_fs)
++              sb->s_op->sync_fs(sb, 0);
++      ret = __sync_blockdev(sb->s_bdev, 0);
+       if (ret < 0)
+               return ret;
+-      return __sync_filesystem(sb, 1);
++
++      sync_inodes_sb(sb);
++      if (sb->s_op->sync_fs)
++              sb->s_op->sync_fs(sb, 1);
++      return __sync_blockdev(sb->s_bdev, 1);
+ }
+ EXPORT_SYMBOL(sync_filesystem);
+-- 
+2.35.1
+
diff --git a/queue-5.15/series b/queue-5.15/series
new file mode 100644 (file)
index 0000000..43de1f3
--- /dev/null
@@ -0,0 +1,5 @@
+fs-remove-__sync_filesystem.patch
+block-remove-__sync_blockdev.patch
+block-simplify-the-block-device-syncing-code.patch
+vfs-make-sync_filesystem-return-errors-from-sync_fs.patch
+xfs-return-errors-in-xfs_fs_sync_fs.patch
diff --git a/queue-5.15/vfs-make-sync_filesystem-return-errors-from-sync_fs.patch b/queue-5.15/vfs-make-sync_filesystem-return-errors-from-sync_fs.patch
new file mode 100644 (file)
index 0000000..b30fe13
--- /dev/null
@@ -0,0 +1,65 @@
+From 81a1f9ff222929053aa8dda60021a5350e667da4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Jan 2022 08:53:16 -0800
+Subject: vfs: make sync_filesystem return errors from ->sync_fs
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+[ Upstream commit 5679897eb104cec9e99609c3f045a0c20603da4c ]
+
+Strangely, sync_filesystem ignores the return code from the ->sync_fs
+call, which means that syscalls like syncfs(2) never see the error.
+This doesn't seem right, so fix that.
+
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Acked-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/sync.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/fs/sync.c b/fs/sync.c
+index 3ce8e2137f31..c7690016453e 100644
+--- a/fs/sync.c
++++ b/fs/sync.c
+@@ -29,7 +29,7 @@
+  */
+ int sync_filesystem(struct super_block *sb)
+ {
+-      int ret;
++      int ret = 0;
+       /*
+        * We need to be protected against the filesystem going from
+@@ -52,15 +52,21 @@ int sync_filesystem(struct super_block *sb)
+        * at a time.
+        */
+       writeback_inodes_sb(sb, WB_REASON_SYNC);
+-      if (sb->s_op->sync_fs)
+-              sb->s_op->sync_fs(sb, 0);
++      if (sb->s_op->sync_fs) {
++              ret = sb->s_op->sync_fs(sb, 0);
++              if (ret)
++                      return ret;
++      }
+       ret = sync_blockdev_nowait(sb->s_bdev);
+-      if (ret < 0)
++      if (ret)
+               return ret;
+       sync_inodes_sb(sb);
+-      if (sb->s_op->sync_fs)
+-              sb->s_op->sync_fs(sb, 1);
++      if (sb->s_op->sync_fs) {
++              ret = sb->s_op->sync_fs(sb, 1);
++              if (ret)
++                      return ret;
++      }
+       return sync_blockdev(sb->s_bdev);
+ }
+ EXPORT_SYMBOL(sync_filesystem);
+-- 
+2.35.1
+
diff --git a/queue-5.15/xfs-return-errors-in-xfs_fs_sync_fs.patch b/queue-5.15/xfs-return-errors-in-xfs_fs_sync_fs.patch
new file mode 100644 (file)
index 0000000..64eeffd
--- /dev/null
@@ -0,0 +1,48 @@
+From 1325aa6868b83e6ae24efc43f0897f0faf50389d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Jan 2022 08:53:17 -0800
+Subject: xfs: return errors in xfs_fs_sync_fs
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+[ Upstream commit 2d86293c70750e4331e9616aded33ab6b47c299d ]
+
+Now that the VFS will do something with the return values from
+->sync_fs, make ours pass on error codes.
+
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Acked-by: Christian Brauner <brauner@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/xfs/xfs_super.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
+index c4e0cd1c1c8c..170fee98c45c 100644
+--- a/fs/xfs/xfs_super.c
++++ b/fs/xfs/xfs_super.c
+@@ -729,6 +729,7 @@ xfs_fs_sync_fs(
+       int                     wait)
+ {
+       struct xfs_mount        *mp = XFS_M(sb);
++      int                     error;
+       trace_xfs_fs_sync_fs(mp, __return_address);
+@@ -738,7 +739,10 @@ xfs_fs_sync_fs(
+       if (!wait)
+               return 0;
+-      xfs_log_force(mp, XFS_LOG_SYNC);
++      error = xfs_log_force(mp, XFS_LOG_SYNC);
++      if (error)
++              return error;
++
+       if (laptop_mode) {
+               /*
+                * The disk must be active because we're syncing.
+-- 
+2.35.1
+