Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'for-5.16/inode-sync-2021-10-29' of git://git.kernel.dk/linux-block

Pull block inode sync updates from Jens Axboe:
"This contains improvements to how bdev inode syncing is handled,
unifying the API"

* tag 'for-5.16/inode-sync-2021-10-29' of git://git.kernel.dk/linux-block:
block: simplify the block device syncing code
ntfs3: use sync_blockdev_nowait
fat: use sync_blockdev_nowait
btrfs: use sync_blockdev
xen-blkback: use sync_blockdev
block: remove __sync_blockdev
fs: remove __sync_filesystem

+56 -66
+20 -8
block/bdev.c
··· 185 185 186 186 EXPORT_SYMBOL(sb_min_blocksize); 187 187 188 - int __sync_blockdev(struct block_device *bdev, int wait) 188 + int sync_blockdev_nowait(struct block_device *bdev) 189 189 { 190 190 if (!bdev) 191 191 return 0; 192 - if (!wait) 193 - return filemap_flush(bdev->bd_inode->i_mapping); 194 - return filemap_write_and_wait(bdev->bd_inode->i_mapping); 192 + return filemap_flush(bdev->bd_inode->i_mapping); 195 193 } 194 + EXPORT_SYMBOL_GPL(sync_blockdev_nowait); 196 195 197 196 /* 198 197 * Write out and wait upon all the dirty data associated with a block ··· 199 200 */ 200 201 int sync_blockdev(struct block_device *bdev) 201 202 { 202 - return __sync_blockdev(bdev, 1); 203 + if (!bdev) 204 + return 0; 205 + return filemap_write_and_wait(bdev->bd_inode->i_mapping); 203 206 } 204 207 EXPORT_SYMBOL(sync_blockdev); 205 208 ··· 1021 1020 } 1022 1021 EXPORT_SYMBOL(__invalidate_device); 1023 1022 1024 - void iterate_bdevs(void (*func)(struct block_device *, void *), void *arg) 1023 + void sync_bdevs(bool wait) 1025 1024 { 1026 1025 struct inode *inode, *old_inode = NULL; 1027 1026 ··· 1052 1051 bdev = I_BDEV(inode); 1053 1052 1054 1053 mutex_lock(&bdev->bd_disk->open_mutex); 1055 - if (bdev->bd_openers) 1056 - func(bdev, arg); 1054 + if (!bdev->bd_openers) { 1055 + ; /* skip */ 1056 + } else if (wait) { 1057 + /* 1058 + * We keep the error status of individual mapping so 1059 + * that applications can catch the writeback error using 1060 + * fsync(2). See filemap_fdatawait_keep_errors() for 1061 + * details. 1062 + */ 1063 + filemap_fdatawait_keep_errors(inode->i_mapping); 1064 + } else { 1065 + filemap_fdatawrite(inode->i_mapping); 1066 + } 1057 1067 mutex_unlock(&bdev->bd_disk->open_mutex); 1058 1068 1059 1069 spin_lock(&blockdev_superblock->s_inode_list_lock);
+1 -1
drivers/block/xen-blkback/xenbus.c
··· 98 98 return; 99 99 } 100 100 101 - err = filemap_write_and_wait(blkif->vbd.bdev->bd_inode->i_mapping); 101 + err = sync_blockdev(blkif->vbd.bdev); 102 102 if (err) { 103 103 xenbus_dev_error(blkif->be->dev, err, "block flush"); 104 104 return;
+1 -1
fs/btrfs/volumes.c
··· 508 508 } 509 509 510 510 if (flush) 511 - filemap_write_and_wait((*bdev)->bd_inode->i_mapping); 511 + sync_blockdev(*bdev); 512 512 ret = set_blocksize(*bdev, BTRFS_BDEV_BLOCKSIZE); 513 513 if (ret) { 514 514 blkdev_put(*bdev, flags);
+2 -4
fs/fat/inode.c
··· 1940 1940 ret = writeback_inode(i1); 1941 1941 if (!ret && i2) 1942 1942 ret = writeback_inode(i2); 1943 - if (!ret) { 1944 - struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; 1945 - ret = filemap_flush(mapping); 1946 - } 1943 + if (!ret) 1944 + ret = sync_blockdev_nowait(sb->s_bdev); 1947 1945 return ret; 1948 1946 } 1949 1947 EXPORT_SYMBOL_GPL(fat_flush_inodes);
-11
fs/internal.h
··· 23 23 #ifdef CONFIG_BLOCK 24 24 extern void __init bdev_cache_init(void); 25 25 26 - extern int __sync_blockdev(struct block_device *bdev, int wait); 27 - void iterate_bdevs(void (*)(struct block_device *, void *), void *); 28 26 void emergency_thaw_bdev(struct super_block *sb); 29 27 #else 30 28 static inline void bdev_cache_init(void) 31 - { 32 - } 33 - 34 - static inline int __sync_blockdev(struct block_device *bdev, int wait) 35 - { 36 - return 0; 37 - } 38 - static inline void iterate_bdevs(void (*f)(struct block_device *, void *), 39 - void *arg) 40 29 { 41 30 } 42 31 static inline int emergency_thaw_bdev(struct super_block *sb)
+1 -1
fs/ntfs3/inode.c
··· 1046 1046 if (!ret && i2) 1047 1047 ret = writeback_inode(i2); 1048 1048 if (!ret) 1049 - ret = filemap_flush(sb->s_bdev->bd_inode->i_mapping); 1049 + ret = sync_blockdev_nowait(sb->s_bdev); 1050 1050 return ret; 1051 1051 } 1052 1052
+22 -40
fs/sync.c
··· 3 3 * High-level sync()-related operations 4 4 */ 5 5 6 + #include <linux/blkdev.h> 6 7 #include <linux/kernel.h> 7 8 #include <linux/file.h> 8 9 #include <linux/fs.h> ··· 21 20 22 21 #define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \ 23 22 SYNC_FILE_RANGE_WAIT_AFTER) 24 - 25 - /* 26 - * Do the filesystem syncing work. For simple filesystems 27 - * writeback_inodes_sb(sb) just dirties buffers with inodes so we have to 28 - * submit IO for these buffers via __sync_blockdev(). This also speeds up the 29 - * wait == 1 case since in that case write_inode() functions do 30 - * sync_dirty_buffer() and thus effectively write one block at a time. 31 - */ 32 - static int __sync_filesystem(struct super_block *sb, int wait) 33 - { 34 - if (wait) 35 - sync_inodes_sb(sb); 36 - else 37 - writeback_inodes_sb(sb, WB_REASON_SYNC); 38 - 39 - if (sb->s_op->sync_fs) 40 - sb->s_op->sync_fs(sb, wait); 41 - return __sync_blockdev(sb->s_bdev, wait); 42 - } 43 23 44 24 /* 45 25 * Write out and wait upon all dirty data associated with this ··· 43 61 if (sb_rdonly(sb)) 44 62 return 0; 45 63 46 - ret = __sync_filesystem(sb, 0); 64 + /* 65 + * Do the filesystem syncing work. For simple filesystems 66 + * writeback_inodes_sb(sb) just dirties buffers with inodes so we have 67 + * to submit I/O for these buffers via sync_blockdev(). This also 68 + * speeds up the wait == 1 case since in that case write_inode() 69 + * methods call sync_dirty_buffer() and thus effectively write one block 70 + * at a time. 71 + */ 72 + writeback_inodes_sb(sb, WB_REASON_SYNC); 73 + if (sb->s_op->sync_fs) 74 + sb->s_op->sync_fs(sb, 0); 75 + ret = sync_blockdev_nowait(sb->s_bdev); 47 76 if (ret < 0) 48 77 return ret; 49 - return __sync_filesystem(sb, 1); 78 + 79 + sync_inodes_sb(sb); 80 + if (sb->s_op->sync_fs) 81 + sb->s_op->sync_fs(sb, 1); 82 + return sync_blockdev(sb->s_bdev); 50 83 } 51 84 EXPORT_SYMBOL(sync_filesystem); 52 85 ··· 76 79 if (!sb_rdonly(sb) && !(sb->s_iflags & SB_I_SKIP_SYNC) && 77 80 sb->s_op->sync_fs) 78 81 sb->s_op->sync_fs(sb, *(int *)arg); 79 - } 80 - 81 - static void fdatawrite_one_bdev(struct block_device *bdev, void *arg) 82 - { 83 - filemap_fdatawrite(bdev->bd_inode->i_mapping); 84 - } 85 - 86 - static void fdatawait_one_bdev(struct block_device *bdev, void *arg) 87 - { 88 - /* 89 - * We keep the error status of individual mapping so that 90 - * applications can catch the writeback error using fsync(2). 91 - * See filemap_fdatawait_keep_errors() for details. 92 - */ 93 - filemap_fdatawait_keep_errors(bdev->bd_inode->i_mapping); 94 82 } 95 83 96 84 /* ··· 96 114 iterate_supers(sync_inodes_one_sb, NULL); 97 115 iterate_supers(sync_fs_one_sb, &nowait); 98 116 iterate_supers(sync_fs_one_sb, &wait); 99 - iterate_bdevs(fdatawrite_one_bdev, NULL); 100 - iterate_bdevs(fdatawait_one_bdev, NULL); 117 + sync_bdevs(false); 118 + sync_bdevs(true); 101 119 if (unlikely(laptop_mode)) 102 120 laptop_sync_completion(); 103 121 } ··· 118 136 */ 119 137 iterate_supers(sync_inodes_one_sb, &nowait); 120 138 iterate_supers(sync_fs_one_sb, &nowait); 121 - iterate_bdevs(fdatawrite_one_bdev, NULL); 139 + sync_bdevs(false); 122 140 iterate_supers(sync_inodes_one_sb, &nowait); 123 141 iterate_supers(sync_fs_one_sb, &nowait); 124 - iterate_bdevs(fdatawrite_one_bdev, NULL); 142 + sync_bdevs(false); 125 143 printk("Emergency Sync complete\n"); 126 144 kfree(work); 127 145 }
+9
include/linux/blkdev.h
··· 1304 1304 #ifdef CONFIG_BLOCK 1305 1305 void invalidate_bdev(struct block_device *bdev); 1306 1306 int sync_blockdev(struct block_device *bdev); 1307 + int sync_blockdev_nowait(struct block_device *bdev); 1308 + void sync_bdevs(bool wait); 1307 1309 #else 1308 1310 static inline void invalidate_bdev(struct block_device *bdev) 1309 1311 { ··· 1313 1311 static inline int sync_blockdev(struct block_device *bdev) 1314 1312 { 1315 1313 return 0; 1314 + } 1315 + static inline int sync_blockdev_nowait(struct block_device *bdev) 1316 + { 1317 + return 0; 1318 + } 1319 + static inline void sync_bdevs(bool wait) 1320 + { 1316 1321 } 1317 1322 #endif 1318 1323 int fsync_bdev(struct block_device *bdev);