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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'vfs-5.17-fixes-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull vfs fixes from Darrick Wong:
"I was auditing the sync_fs code paths recently and noticed that most
callers of ->sync_fs ignore its return value (and many implementations
never return nonzero even if the fs is broken!), which means that
internal fs errors and corruption are not passed up to userspace
callers of syncfs(2) or FIFREEZE. Hence fixing the common code and
XFS, and I'll start working on the ext4/btrfs folks if this is merged.

Summary:

- Fix a bug where callers of ->sync_fs (e.g. sync_filesystem and
syncfs(2)) ignore the return value.

- Fix a bug where callers of sync_filesystem (e.g. fs freeze) ignore
the return value.

- Fix a bug in XFS where xfs_fs_sync_fs never passed back error
returns"

* tag 'vfs-5.17-fixes-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
xfs: return errors in xfs_fs_sync_fs
quota: make dquot_quota_sync return errors from ->sync_fs
vfs: make sync_filesystem return errors from ->sync_fs
vfs: make freeze_super abort when sync_filesystem returns error

+37 -17
+8 -3
fs/quota/dquot.c
··· 690 690 /* This is not very clever (and fast) but currently I don't know about 691 691 * any other simple way of getting quota data to disk and we must get 692 692 * them there for userspace to be visible... */ 693 - if (sb->s_op->sync_fs) 694 - sb->s_op->sync_fs(sb, 1); 695 - sync_blockdev(sb->s_bdev); 693 + if (sb->s_op->sync_fs) { 694 + ret = sb->s_op->sync_fs(sb, 1); 695 + if (ret) 696 + return ret; 697 + } 698 + ret = sync_blockdev(sb->s_bdev); 699 + if (ret) 700 + return ret; 696 701 697 702 /* 698 703 * Now when everything is written we can discard the pagecache so
+12 -7
fs/super.c
··· 1616 1616 percpu_rwsem_acquire(sb->s_writers.rw_sem + level, 0, _THIS_IP_); 1617 1617 } 1618 1618 1619 - static void sb_freeze_unlock(struct super_block *sb) 1619 + static void sb_freeze_unlock(struct super_block *sb, int level) 1620 1620 { 1621 - int level; 1622 - 1623 - for (level = SB_FREEZE_LEVELS - 1; level >= 0; level--) 1621 + for (level--; level >= 0; level--) 1624 1622 percpu_up_write(sb->s_writers.rw_sem + level); 1625 1623 } 1626 1624 ··· 1689 1691 sb_wait_write(sb, SB_FREEZE_PAGEFAULT); 1690 1692 1691 1693 /* All writers are done so after syncing there won't be dirty data */ 1692 - sync_filesystem(sb); 1694 + ret = sync_filesystem(sb); 1695 + if (ret) { 1696 + sb->s_writers.frozen = SB_UNFROZEN; 1697 + sb_freeze_unlock(sb, SB_FREEZE_PAGEFAULT); 1698 + wake_up(&sb->s_writers.wait_unfrozen); 1699 + deactivate_locked_super(sb); 1700 + return ret; 1701 + } 1693 1702 1694 1703 /* Now wait for internal filesystem counter */ 1695 1704 sb->s_writers.frozen = SB_FREEZE_FS; ··· 1708 1703 printk(KERN_ERR 1709 1704 "VFS:Filesystem freeze failed\n"); 1710 1705 sb->s_writers.frozen = SB_UNFROZEN; 1711 - sb_freeze_unlock(sb); 1706 + sb_freeze_unlock(sb, SB_FREEZE_FS); 1712 1707 wake_up(&sb->s_writers.wait_unfrozen); 1713 1708 deactivate_locked_super(sb); 1714 1709 return ret; ··· 1753 1748 } 1754 1749 1755 1750 sb->s_writers.frozen = SB_UNFROZEN; 1756 - sb_freeze_unlock(sb); 1751 + sb_freeze_unlock(sb, SB_FREEZE_FS); 1757 1752 out: 1758 1753 wake_up(&sb->s_writers.wait_unfrozen); 1759 1754 deactivate_locked_super(sb);
+12 -6
fs/sync.c
··· 29 29 */ 30 30 int sync_filesystem(struct super_block *sb) 31 31 { 32 - int ret; 32 + int ret = 0; 33 33 34 34 /* 35 35 * We need to be protected against the filesystem going from ··· 52 52 * at a time. 53 53 */ 54 54 writeback_inodes_sb(sb, WB_REASON_SYNC); 55 - if (sb->s_op->sync_fs) 56 - sb->s_op->sync_fs(sb, 0); 55 + if (sb->s_op->sync_fs) { 56 + ret = sb->s_op->sync_fs(sb, 0); 57 + if (ret) 58 + return ret; 59 + } 57 60 ret = sync_blockdev_nowait(sb->s_bdev); 58 - if (ret < 0) 61 + if (ret) 59 62 return ret; 60 63 61 64 sync_inodes_sb(sb); 62 - if (sb->s_op->sync_fs) 63 - sb->s_op->sync_fs(sb, 1); 65 + if (sb->s_op->sync_fs) { 66 + ret = sb->s_op->sync_fs(sb, 1); 67 + if (ret) 68 + return ret; 69 + } 64 70 return sync_blockdev(sb->s_bdev); 65 71 } 66 72 EXPORT_SYMBOL(sync_filesystem);
+5 -1
fs/xfs/xfs_super.c
··· 735 735 int wait) 736 736 { 737 737 struct xfs_mount *mp = XFS_M(sb); 738 + int error; 738 739 739 740 trace_xfs_fs_sync_fs(mp, __return_address); 740 741 ··· 745 744 if (!wait) 746 745 return 0; 747 746 748 - xfs_log_force(mp, XFS_LOG_SYNC); 747 + error = xfs_log_force(mp, XFS_LOG_SYNC); 748 + if (error) 749 + return error; 750 + 749 751 if (laptop_mode) { 750 752 /* 751 753 * The disk must be active because we're syncing.