summary refs log tree commit diff
path: root/block/bdev.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2021-10-19 08:25:30 +0200
committerJens Axboe <axboe@kernel.dk>2021-10-22 08:36:55 -0600
commit1e03a36bdff4709c1bbf0f57f60ae3f776d51adf (patch)
treec0036f9aa7fead90fc9ed6d3c4001a71881898ce /block/bdev.c
parent680e667bc2e4e458a373bbfd367b7174e4972eb5 (diff)
downloadlinux-1e03a36bdff4709c1bbf0f57f60ae3f776d51adf.tar.gz
block: simplify the block device syncing code
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>
Diffstat (limited to 'block/bdev.c')
-rw-r--r--block/bdev.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/block/bdev.c b/block/bdev.c
index 9a33c414f450..b4dab2fb6a74 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -1021,7 +1021,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;
 
@@ -1052,8 +1052,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);