From: Sasha Levin Date: Wed, 20 Apr 2022 14:51:24 +0000 (-0400) Subject: Fixes for 5.15 X-Git-Tag: v4.9.312~94 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5faefd3e84294b4a3de053772f4761faf65a5daa;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.15 Signed-off-by: Sasha Levin --- diff --git a/queue-5.15/block-remove-__sync_blockdev.patch b/queue-5.15/block-remove-__sync_blockdev.patch new file mode 100644 index 00000000000..c6a0b353605 --- /dev/null +++ b/queue-5.15/block-remove-__sync_blockdev.patch @@ -0,0 +1,143 @@ +From 0f5da9dac07c4bf3add7da401bbe39893143480f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Oct 2021 08:25:25 +0200 +Subject: block: remove __sync_blockdev + +From: Christoph Hellwig + +[ 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 +Link: https://lore.kernel.org/r/20211019062530.2174626-3-hch@lst.de +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + 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 + #include + #include + #include +@@ -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 index 00000000000..225d559a848 --- /dev/null +++ b/queue-5.15/block-simplify-the-block-device-syncing-code.patch @@ -0,0 +1,155 @@ +From 22110c694ece8b06a1f0625f9b1b5656726005f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Oct 2021 08:25:30 +0200 +Subject: block: simplify the block device syncing code + +From: Christoph Hellwig + +[ 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 +Link: https://lore.kernel.org/r/20211019062530.2174626-8-hch@lst.de +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..537389a2a57 --- /dev/null +++ b/queue-5.15/fs-remove-__sync_filesystem.patch @@ -0,0 +1,81 @@ +From 7370977fefdc738478af84515fdc1dcdc44f201e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Oct 2021 08:25:24 +0200 +Subject: fs: remove __sync_filesystem + +From: Christoph Hellwig + +[ Upstream commit 9a208ba5c9afa62c7b1e9c6f5e783066e84e2d3c ] + +There is no clear benefit in having this helper vs just open coding it. + +Signed-off-by: Christoph Hellwig +Reviewed-by: Chaitanya Kulkarni +Link: https://lore.kernel.org/r/20211019062530.2174626-2-hch@lst.de +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..43de1f33fc3 --- /dev/null +++ b/queue-5.15/series @@ -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 index 00000000000..b30fe137aac --- /dev/null +++ b/queue-5.15/vfs-make-sync_filesystem-return-errors-from-sync_fs.patch @@ -0,0 +1,65 @@ +From 81a1f9ff222929053aa8dda60021a5350e667da4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 30 Jan 2022 08:53:16 -0800 +Subject: vfs: make sync_filesystem return errors from ->sync_fs + +From: Darrick J. Wong + +[ 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 +Reviewed-by: Jan Kara +Reviewed-by: Christoph Hellwig +Acked-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..64eeffd47a2 --- /dev/null +++ b/queue-5.15/xfs-return-errors-in-xfs_fs_sync_fs.patch @@ -0,0 +1,48 @@ +From 1325aa6868b83e6ae24efc43f0897f0faf50389d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 30 Jan 2022 08:53:17 -0800 +Subject: xfs: return errors in xfs_fs_sync_fs + +From: Darrick J. Wong + +[ 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 +Reviewed-by: Jan Kara +Reviewed-by: Christoph Hellwig +Acked-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + 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 +