Skip to content

Commit 9ef40c2

Browse files
josefbacikkdave
authored andcommitted
btrfs: split out ro->rw and rw->ro helpers into their own functions
When we remount ro->rw or rw->ro we have some cleanup tasks that have to be managed. Split these out into their own function to make btrfs_remount smaller. Reviewed-by: Johannes Thumshirn <[email protected]> Reviewed-by: Anand Jain <[email protected]> Acked-by: Christian Brauner <[email protected]> Signed-off-by: Josef Bacik <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 272efa3 commit 9ef40c2

File tree

1 file changed

+116
-113
lines changed

1 file changed

+116
-113
lines changed

fs/btrfs/super.c

Lines changed: 116 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1676,6 +1676,115 @@ static inline void btrfs_remount_cleanup(struct btrfs_fs_info *fs_info,
16761676
btrfs_set_free_space_cache_v1_active(fs_info, cache_opt);
16771677
}
16781678

1679+
static int btrfs_remount_rw(struct btrfs_fs_info *fs_info)
1680+
{
1681+
int ret;
1682+
1683+
if (BTRFS_FS_ERROR(fs_info)) {
1684+
btrfs_err(fs_info,
1685+
"remounting read-write after error is not allowed");
1686+
return -EINVAL;
1687+
}
1688+
1689+
if (fs_info->fs_devices->rw_devices == 0)
1690+
return -EACCES;
1691+
1692+
if (!btrfs_check_rw_degradable(fs_info, NULL)) {
1693+
btrfs_warn(fs_info,
1694+
"too many missing devices, writable remount is not allowed");
1695+
return -EACCES;
1696+
}
1697+
1698+
if (btrfs_super_log_root(fs_info->super_copy) != 0) {
1699+
btrfs_warn(fs_info,
1700+
"mount required to replay tree-log, cannot remount read-write");
1701+
return -EINVAL;
1702+
}
1703+
1704+
/*
1705+
* NOTE: when remounting with a change that does writes, don't put it
1706+
* anywhere above this point, as we are not sure to be safe to write
1707+
* until we pass the above checks.
1708+
*/
1709+
ret = btrfs_start_pre_rw_mount(fs_info);
1710+
if (ret)
1711+
return ret;
1712+
1713+
btrfs_clear_sb_rdonly(fs_info->sb);
1714+
1715+
set_bit(BTRFS_FS_OPEN, &fs_info->flags);
1716+
1717+
/*
1718+
* If we've gone from readonly -> read-write, we need to get our
1719+
* sync/async discard lists in the right state.
1720+
*/
1721+
btrfs_discard_resume(fs_info);
1722+
1723+
return 0;
1724+
}
1725+
1726+
static int btrfs_remount_ro(struct btrfs_fs_info *fs_info)
1727+
{
1728+
/*
1729+
* This also happens on 'umount -rf' or on shutdown, when the
1730+
* filesystem is busy.
1731+
*/
1732+
cancel_work_sync(&fs_info->async_reclaim_work);
1733+
cancel_work_sync(&fs_info->async_data_reclaim_work);
1734+
1735+
btrfs_discard_cleanup(fs_info);
1736+
1737+
/* Wait for the uuid_scan task to finish */
1738+
down(&fs_info->uuid_tree_rescan_sem);
1739+
/* Avoid complains from lockdep et al. */
1740+
up(&fs_info->uuid_tree_rescan_sem);
1741+
1742+
btrfs_set_sb_rdonly(fs_info->sb);
1743+
1744+
/*
1745+
* Setting SB_RDONLY will put the cleaner thread to sleep at the next
1746+
* loop if it's already active. If it's already asleep, we'll leave
1747+
* unused block groups on disk until we're mounted read-write again
1748+
* unless we clean them up here.
1749+
*/
1750+
btrfs_delete_unused_bgs(fs_info);
1751+
1752+
/*
1753+
* The cleaner task could be already running before we set the flag
1754+
* BTRFS_FS_STATE_RO (and SB_RDONLY in the superblock). We must make
1755+
* sure that after we finish the remount, i.e. after we call
1756+
* btrfs_commit_super(), the cleaner can no longer start a transaction
1757+
* - either because it was dropping a dead root, running delayed iputs
1758+
* or deleting an unused block group (the cleaner picked a block
1759+
* group from the list of unused block groups before we were able to
1760+
* in the previous call to btrfs_delete_unused_bgs()).
1761+
*/
1762+
wait_on_bit(&fs_info->flags, BTRFS_FS_CLEANER_RUNNING, TASK_UNINTERRUPTIBLE);
1763+
1764+
/*
1765+
* We've set the superblock to RO mode, so we might have made the
1766+
* cleaner task sleep without running all pending delayed iputs. Go
1767+
* through all the delayed iputs here, so that if an unmount happens
1768+
* without remounting RW we don't end up at finishing close_ctree()
1769+
* with a non-empty list of delayed iputs.
1770+
*/
1771+
btrfs_run_delayed_iputs(fs_info);
1772+
1773+
btrfs_dev_replace_suspend_for_unmount(fs_info);
1774+
btrfs_scrub_cancel(fs_info);
1775+
btrfs_pause_balance(fs_info);
1776+
1777+
/*
1778+
* Pause the qgroup rescan worker if it is running. We don't want it to
1779+
* be still running after we are in RO mode, as after that, by the time
1780+
* we unmount, it might have left a transaction open, so we would leak
1781+
* the transaction and/or crash.
1782+
*/
1783+
btrfs_qgroup_wait_for_completion(fs_info, false);
1784+
1785+
return btrfs_commit_super(fs_info);
1786+
}
1787+
16791788
static int btrfs_remount(struct super_block *sb, int *flags, char *data)
16801789
{
16811790
struct btrfs_fs_info *fs_info = btrfs_sb(sb);
@@ -1729,120 +1838,14 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
17291838
}
17301839
}
17311840

1732-
if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb))
1733-
goto out;
1734-
1735-
if (*flags & SB_RDONLY) {
1736-
/*
1737-
* this also happens on 'umount -rf' or on shutdown, when
1738-
* the filesystem is busy.
1739-
*/
1740-
cancel_work_sync(&fs_info->async_reclaim_work);
1741-
cancel_work_sync(&fs_info->async_data_reclaim_work);
1742-
1743-
btrfs_discard_cleanup(fs_info);
1744-
1745-
/* wait for the uuid_scan task to finish */
1746-
down(&fs_info->uuid_tree_rescan_sem);
1747-
/* avoid complains from lockdep et al. */
1748-
up(&fs_info->uuid_tree_rescan_sem);
1749-
1750-
btrfs_set_sb_rdonly(sb);
1751-
1752-
/*
1753-
* Setting SB_RDONLY will put the cleaner thread to
1754-
* sleep at the next loop if it's already active.
1755-
* If it's already asleep, we'll leave unused block
1756-
* groups on disk until we're mounted read-write again
1757-
* unless we clean them up here.
1758-
*/
1759-
btrfs_delete_unused_bgs(fs_info);
1760-
1761-
/*
1762-
* The cleaner task could be already running before we set the
1763-
* flag BTRFS_FS_STATE_RO (and SB_RDONLY in the superblock).
1764-
* We must make sure that after we finish the remount, i.e. after
1765-
* we call btrfs_commit_super(), the cleaner can no longer start
1766-
* a transaction - either because it was dropping a dead root,
1767-
* running delayed iputs or deleting an unused block group (the
1768-
* cleaner picked a block group from the list of unused block
1769-
* groups before we were able to in the previous call to
1770-
* btrfs_delete_unused_bgs()).
1771-
*/
1772-
wait_on_bit(&fs_info->flags, BTRFS_FS_CLEANER_RUNNING,
1773-
TASK_UNINTERRUPTIBLE);
1774-
1775-
/*
1776-
* We've set the superblock to RO mode, so we might have made
1777-
* the cleaner task sleep without running all pending delayed
1778-
* iputs. Go through all the delayed iputs here, so that if an
1779-
* unmount happens without remounting RW we don't end up at
1780-
* finishing close_ctree() with a non-empty list of delayed
1781-
* iputs.
1782-
*/
1783-
btrfs_run_delayed_iputs(fs_info);
1784-
1785-
btrfs_dev_replace_suspend_for_unmount(fs_info);
1786-
btrfs_scrub_cancel(fs_info);
1787-
btrfs_pause_balance(fs_info);
1788-
1789-
/*
1790-
* Pause the qgroup rescan worker if it is running. We don't want
1791-
* it to be still running after we are in RO mode, as after that,
1792-
* by the time we unmount, it might have left a transaction open,
1793-
* so we would leak the transaction and/or crash.
1794-
*/
1795-
btrfs_qgroup_wait_for_completion(fs_info, false);
1796-
1797-
ret = btrfs_commit_super(fs_info);
1798-
if (ret)
1799-
goto restore;
1800-
} else {
1801-
if (BTRFS_FS_ERROR(fs_info)) {
1802-
btrfs_err(fs_info,
1803-
"Remounting read-write after error is not allowed");
1804-
ret = -EINVAL;
1805-
goto restore;
1806-
}
1807-
if (fs_info->fs_devices->rw_devices == 0) {
1808-
ret = -EACCES;
1809-
goto restore;
1810-
}
1811-
1812-
if (!btrfs_check_rw_degradable(fs_info, NULL)) {
1813-
btrfs_warn(fs_info,
1814-
"too many missing devices, writable remount is not allowed");
1815-
ret = -EACCES;
1816-
goto restore;
1817-
}
1818-
1819-
if (btrfs_super_log_root(fs_info->super_copy) != 0) {
1820-
btrfs_warn(fs_info,
1821-
"mount required to replay tree-log, cannot remount read-write");
1822-
ret = -EINVAL;
1823-
goto restore;
1824-
}
1825-
1826-
/*
1827-
* NOTE: when remounting with a change that does writes, don't
1828-
* put it anywhere above this point, as we are not sure to be
1829-
* safe to write until we pass the above checks.
1830-
*/
1831-
ret = btrfs_start_pre_rw_mount(fs_info);
1832-
if (ret)
1833-
goto restore;
1834-
1835-
btrfs_clear_sb_rdonly(sb);
1836-
1837-
set_bit(BTRFS_FS_OPEN, &fs_info->flags);
1841+
ret = 0;
1842+
if (!sb_rdonly(sb) && (*flags & SB_RDONLY))
1843+
ret = btrfs_remount_ro(fs_info);
1844+
else if (sb_rdonly(sb) && !(*flags & SB_RDONLY))
1845+
ret = btrfs_remount_rw(fs_info);
1846+
if (ret)
1847+
goto restore;
18381848

1839-
/*
1840-
* If we've gone from readonly -> read/write, we need to get
1841-
* our sync/async discard lists in the right state.
1842-
*/
1843-
btrfs_discard_resume(fs_info);
1844-
}
1845-
out:
18461849
/*
18471850
* We need to set SB_I_VERSION here otherwise it'll get cleared by VFS,
18481851
* since the absence of the flag means it can be toggled off by remount.

0 commit comments

Comments
 (0)