diff mbox series

btrfs: log message when rw remount is attempted with unclean tree-log

Message ID 20200205161228.24378-1-dsterba@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs: log message when rw remount is attempted with unclean tree-log | expand

Commit Message

David Sterba Feb. 5, 2020, 4:12 p.m. UTC
A remount to a read-write filesystem is not safe when there's tree-log
to be replayed. Files that could be opened until now might be affected
by the changes in the tree-log.

A regular mount is needed to replay the log so the filesystem presents
the consistent view with the pending changes included.

CC: stable@vger.kernel.org # 4.4+
Signed-off-by: David Sterba <dsterba@suse.com>
---
 fs/btrfs/super.c | 2 ++
 1 file changed, 2 insertions(+)

Comments

Anand Jain Feb. 6, 2020, 3:51 a.m. UTC | #1
On 2/6/20 12:12 AM, David Sterba wrote:
> A remount to a read-write filesystem is not safe when there's tree-log
> to be replayed. Files that could be opened until now might be affected
> by the changes in the tree-log.
> 
> A regular mount is needed to replay the log so the filesystem presents
> the consistent view with the pending changes included.
> 
> CC: stable@vger.kernel.org # 4.4+
> Signed-off-by: David Sterba <dsterba@suse.com>
> ---
>   fs/btrfs/super.c | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
> index 580ba7db67e5..a2554c651548 100644
> --- a/fs/btrfs/super.c
> +++ b/fs/btrfs/super.c
> @@ -1834,6 +1834,8 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
>   		}
>   
>   		if (btrfs_super_log_root(fs_info->super_copy) != 0) {



> +			btrfs_warn(f_info,

                                  ^^^^
                               fs_info,

Thanks, Anand

> +		"mount required to replay tree-log, cannot remount read-write");
>   			ret = -EINVAL;
>   			goto restore;
>   		}
>
kernel test robot Feb. 6, 2020, 6:16 a.m. UTC | #2
Hi David,

I love your patch! Yet something to improve:

[auto build test ERROR on kdave/for-next]
[also build test ERROR on v5.5]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/David-Sterba/btrfs-log-message-when-rw-remount-is-attempted-with-unclean-tree-log/20200206-115926
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
config: h8300-randconfig-a001-20200206 (attached as .config)
compiler: h8300-linux-gcc (GCC) 7.5.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.5.0 make.cross ARCH=h8300 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from fs/btrfs/delayed-inode.h:17:0,
                    from fs/btrfs/super.c:30:
   fs/btrfs/super.c: In function 'btrfs_remount':
>> fs/btrfs/super.c:1837:15: error: 'f_info' undeclared (first use in this function); did you mean 'fs_info'?
       btrfs_warn(f_info,
                  ^
   fs/btrfs/ctree.h:3035:15: note: in definition of macro 'btrfs_warn'
     btrfs_printk(fs_info, KERN_WARNING fmt, ##args)
                  ^~~~~~~
   fs/btrfs/super.c:1837:15: note: each undeclared identifier is reported only once for each function it appears in
       btrfs_warn(f_info,
                  ^
   fs/btrfs/ctree.h:3035:15: note: in definition of macro 'btrfs_warn'
     btrfs_printk(fs_info, KERN_WARNING fmt, ##args)
                  ^~~~~~~

vim +1837 fs/btrfs/super.c

  1747	
  1748	static int btrfs_remount(struct super_block *sb, int *flags, char *data)
  1749	{
  1750		struct btrfs_fs_info *fs_info = btrfs_sb(sb);
  1751		struct btrfs_root *root = fs_info->tree_root;
  1752		unsigned old_flags = sb->s_flags;
  1753		unsigned long old_opts = fs_info->mount_opt;
  1754		unsigned long old_compress_type = fs_info->compress_type;
  1755		u64 old_max_inline = fs_info->max_inline;
  1756		u32 old_thread_pool_size = fs_info->thread_pool_size;
  1757		u32 old_metadata_ratio = fs_info->metadata_ratio;
  1758		int ret;
  1759	
  1760		sync_filesystem(sb);
  1761		btrfs_remount_prepare(fs_info);
  1762	
  1763		if (data) {
  1764			void *new_sec_opts = NULL;
  1765	
  1766			ret = security_sb_eat_lsm_opts(data, &new_sec_opts);
  1767			if (!ret)
  1768				ret = security_sb_remount(sb, new_sec_opts);
  1769			security_free_mnt_opts(&new_sec_opts);
  1770			if (ret)
  1771				goto restore;
  1772		}
  1773	
  1774		ret = btrfs_parse_options(fs_info, data, *flags);
  1775		if (ret)
  1776			goto restore;
  1777	
  1778		btrfs_remount_begin(fs_info, old_opts, *flags);
  1779		btrfs_resize_thread_pool(fs_info,
  1780			fs_info->thread_pool_size, old_thread_pool_size);
  1781	
  1782		if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb))
  1783			goto out;
  1784	
  1785		if (*flags & SB_RDONLY) {
  1786			/*
  1787			 * this also happens on 'umount -rf' or on shutdown, when
  1788			 * the filesystem is busy.
  1789			 */
  1790			cancel_work_sync(&fs_info->async_reclaim_work);
  1791	
  1792			btrfs_discard_cleanup(fs_info);
  1793	
  1794			/* wait for the uuid_scan task to finish */
  1795			down(&fs_info->uuid_tree_rescan_sem);
  1796			/* avoid complains from lockdep et al. */
  1797			up(&fs_info->uuid_tree_rescan_sem);
  1798	
  1799			sb->s_flags |= SB_RDONLY;
  1800	
  1801			/*
  1802			 * Setting SB_RDONLY will put the cleaner thread to
  1803			 * sleep at the next loop if it's already active.
  1804			 * If it's already asleep, we'll leave unused block
  1805			 * groups on disk until we're mounted read-write again
  1806			 * unless we clean them up here.
  1807			 */
  1808			btrfs_delete_unused_bgs(fs_info);
  1809	
  1810			btrfs_dev_replace_suspend_for_unmount(fs_info);
  1811			btrfs_scrub_cancel(fs_info);
  1812			btrfs_pause_balance(fs_info);
  1813	
  1814			ret = btrfs_commit_super(fs_info);
  1815			if (ret)
  1816				goto restore;
  1817		} else {
  1818			if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
  1819				btrfs_err(fs_info,
  1820					"Remounting read-write after error is not allowed");
  1821				ret = -EINVAL;
  1822				goto restore;
  1823			}
  1824			if (fs_info->fs_devices->rw_devices == 0) {
  1825				ret = -EACCES;
  1826				goto restore;
  1827			}
  1828	
  1829			if (!btrfs_check_rw_degradable(fs_info, NULL)) {
  1830				btrfs_warn(fs_info,
  1831			"too many missing devices, writable remount is not allowed");
  1832				ret = -EACCES;
  1833				goto restore;
  1834			}
  1835	
  1836			if (btrfs_super_log_root(fs_info->super_copy) != 0) {
> 1837				btrfs_warn(f_info,
  1838			"mount required to replay tree-log, cannot remount read-write");
  1839				ret = -EINVAL;
  1840				goto restore;
  1841			}
  1842	
  1843			ret = btrfs_cleanup_fs_roots(fs_info);
  1844			if (ret)
  1845				goto restore;
  1846	
  1847			/* recover relocation */
  1848			mutex_lock(&fs_info->cleaner_mutex);
  1849			ret = btrfs_recover_relocation(root);
  1850			mutex_unlock(&fs_info->cleaner_mutex);
  1851			if (ret)
  1852				goto restore;
  1853	
  1854			ret = btrfs_resume_balance_async(fs_info);
  1855			if (ret)
  1856				goto restore;
  1857	
  1858			ret = btrfs_resume_dev_replace_async(fs_info);
  1859			if (ret) {
  1860				btrfs_warn(fs_info, "failed to resume dev_replace");
  1861				goto restore;
  1862			}
  1863	
  1864			btrfs_qgroup_rescan_resume(fs_info);
  1865	
  1866			if (!fs_info->uuid_root) {
  1867				btrfs_info(fs_info, "creating UUID tree");
  1868				ret = btrfs_create_uuid_tree(fs_info);
  1869				if (ret) {
  1870					btrfs_warn(fs_info,
  1871						   "failed to create the UUID tree %d",
  1872						   ret);
  1873					goto restore;
  1874				}
  1875			}
  1876			sb->s_flags &= ~SB_RDONLY;
  1877	
  1878			set_bit(BTRFS_FS_OPEN, &fs_info->flags);
  1879		}
  1880	out:
  1881		wake_up_process(fs_info->transaction_kthread);
  1882		btrfs_remount_cleanup(fs_info, old_opts);
  1883		return 0;
  1884	
  1885	restore:
  1886		/* We've hit an error - don't reset SB_RDONLY */
  1887		if (sb_rdonly(sb))
  1888			old_flags |= SB_RDONLY;
  1889		sb->s_flags = old_flags;
  1890		fs_info->mount_opt = old_opts;
  1891		fs_info->compress_type = old_compress_type;
  1892		fs_info->max_inline = old_max_inline;
  1893		btrfs_resize_thread_pool(fs_info,
  1894			old_thread_pool_size, fs_info->thread_pool_size);
  1895		fs_info->metadata_ratio = old_metadata_ratio;
  1896		btrfs_remount_cleanup(fs_info, old_opts);
  1897		return ret;
  1898	}
  1899	

---
0-DAY kernel test infrastructure                 Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org Intel Corporation
kernel test robot Feb. 6, 2020, 7:49 a.m. UTC | #3
Hi David,

I love your patch! Yet something to improve:

[auto build test ERROR on kdave/for-next]
[also build test ERROR on v5.5 next-20200206]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/David-Sterba/btrfs-log-message-when-rw-remount-is-attempted-with-unclean-tree-log/20200206-115926
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
config: x86_64-randconfig-s2-20200206 (attached as .config)
compiler: gcc-5 (Ubuntu 5.5.0-12ubuntu1) 5.5.0 20171010
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from fs/btrfs/delayed-inode.h:17:0,
                    from fs/btrfs/super.c:30:
   fs/btrfs/super.c: In function 'btrfs_remount':
>> fs/btrfs/super.c:1837:15: error: 'f_info' undeclared (first use in this function)
       btrfs_warn(f_info,
                  ^
   fs/btrfs/ctree.h:3035:15: note: in definition of macro 'btrfs_warn'
     btrfs_printk(fs_info, KERN_WARNING fmt, ##args)
                  ^
   fs/btrfs/super.c:1837:15: note: each undeclared identifier is reported only once for each function it appears in
       btrfs_warn(f_info,
                  ^
   fs/btrfs/ctree.h:3035:15: note: in definition of macro 'btrfs_warn'
     btrfs_printk(fs_info, KERN_WARNING fmt, ##args)
                  ^

vim +/f_info +1837 fs/btrfs/super.c

  1747	
  1748	static int btrfs_remount(struct super_block *sb, int *flags, char *data)
  1749	{
  1750		struct btrfs_fs_info *fs_info = btrfs_sb(sb);
  1751		struct btrfs_root *root = fs_info->tree_root;
  1752		unsigned old_flags = sb->s_flags;
  1753		unsigned long old_opts = fs_info->mount_opt;
  1754		unsigned long old_compress_type = fs_info->compress_type;
  1755		u64 old_max_inline = fs_info->max_inline;
  1756		u32 old_thread_pool_size = fs_info->thread_pool_size;
  1757		u32 old_metadata_ratio = fs_info->metadata_ratio;
  1758		int ret;
  1759	
  1760		sync_filesystem(sb);
  1761		btrfs_remount_prepare(fs_info);
  1762	
  1763		if (data) {
  1764			void *new_sec_opts = NULL;
  1765	
  1766			ret = security_sb_eat_lsm_opts(data, &new_sec_opts);
  1767			if (!ret)
  1768				ret = security_sb_remount(sb, new_sec_opts);
  1769			security_free_mnt_opts(&new_sec_opts);
  1770			if (ret)
  1771				goto restore;
  1772		}
  1773	
  1774		ret = btrfs_parse_options(fs_info, data, *flags);
  1775		if (ret)
  1776			goto restore;
  1777	
  1778		btrfs_remount_begin(fs_info, old_opts, *flags);
  1779		btrfs_resize_thread_pool(fs_info,
  1780			fs_info->thread_pool_size, old_thread_pool_size);
  1781	
  1782		if ((bool)(*flags & SB_RDONLY) == sb_rdonly(sb))
  1783			goto out;
  1784	
  1785		if (*flags & SB_RDONLY) {
  1786			/*
  1787			 * this also happens on 'umount -rf' or on shutdown, when
  1788			 * the filesystem is busy.
  1789			 */
  1790			cancel_work_sync(&fs_info->async_reclaim_work);
  1791	
  1792			btrfs_discard_cleanup(fs_info);
  1793	
  1794			/* wait for the uuid_scan task to finish */
  1795			down(&fs_info->uuid_tree_rescan_sem);
  1796			/* avoid complains from lockdep et al. */
  1797			up(&fs_info->uuid_tree_rescan_sem);
  1798	
  1799			sb->s_flags |= SB_RDONLY;
  1800	
  1801			/*
  1802			 * Setting SB_RDONLY will put the cleaner thread to
  1803			 * sleep at the next loop if it's already active.
  1804			 * If it's already asleep, we'll leave unused block
  1805			 * groups on disk until we're mounted read-write again
  1806			 * unless we clean them up here.
  1807			 */
  1808			btrfs_delete_unused_bgs(fs_info);
  1809	
  1810			btrfs_dev_replace_suspend_for_unmount(fs_info);
  1811			btrfs_scrub_cancel(fs_info);
  1812			btrfs_pause_balance(fs_info);
  1813	
  1814			ret = btrfs_commit_super(fs_info);
  1815			if (ret)
  1816				goto restore;
  1817		} else {
  1818			if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
  1819				btrfs_err(fs_info,
  1820					"Remounting read-write after error is not allowed");
  1821				ret = -EINVAL;
  1822				goto restore;
  1823			}
  1824			if (fs_info->fs_devices->rw_devices == 0) {
  1825				ret = -EACCES;
  1826				goto restore;
  1827			}
  1828	
  1829			if (!btrfs_check_rw_degradable(fs_info, NULL)) {
  1830				btrfs_warn(fs_info,
  1831			"too many missing devices, writable remount is not allowed");
  1832				ret = -EACCES;
  1833				goto restore;
  1834			}
  1835	
  1836			if (btrfs_super_log_root(fs_info->super_copy) != 0) {
> 1837				btrfs_warn(f_info,
  1838			"mount required to replay tree-log, cannot remount read-write");
  1839				ret = -EINVAL;
  1840				goto restore;
  1841			}
  1842	
  1843			ret = btrfs_cleanup_fs_roots(fs_info);
  1844			if (ret)
  1845				goto restore;
  1846	
  1847			/* recover relocation */
  1848			mutex_lock(&fs_info->cleaner_mutex);
  1849			ret = btrfs_recover_relocation(root);
  1850			mutex_unlock(&fs_info->cleaner_mutex);
  1851			if (ret)
  1852				goto restore;
  1853	
  1854			ret = btrfs_resume_balance_async(fs_info);
  1855			if (ret)
  1856				goto restore;
  1857	
  1858			ret = btrfs_resume_dev_replace_async(fs_info);
  1859			if (ret) {
  1860				btrfs_warn(fs_info, "failed to resume dev_replace");
  1861				goto restore;
  1862			}
  1863	
  1864			btrfs_qgroup_rescan_resume(fs_info);
  1865	
  1866			if (!fs_info->uuid_root) {
  1867				btrfs_info(fs_info, "creating UUID tree");
  1868				ret = btrfs_create_uuid_tree(fs_info);
  1869				if (ret) {
  1870					btrfs_warn(fs_info,
  1871						   "failed to create the UUID tree %d",
  1872						   ret);
  1873					goto restore;
  1874				}
  1875			}
  1876			sb->s_flags &= ~SB_RDONLY;
  1877	
  1878			set_bit(BTRFS_FS_OPEN, &fs_info->flags);
  1879		}
  1880	out:
  1881		wake_up_process(fs_info->transaction_kthread);
  1882		btrfs_remount_cleanup(fs_info, old_opts);
  1883		return 0;
  1884	
  1885	restore:
  1886		/* We've hit an error - don't reset SB_RDONLY */
  1887		if (sb_rdonly(sb))
  1888			old_flags |= SB_RDONLY;
  1889		sb->s_flags = old_flags;
  1890		fs_info->mount_opt = old_opts;
  1891		fs_info->compress_type = old_compress_type;
  1892		fs_info->max_inline = old_max_inline;
  1893		btrfs_resize_thread_pool(fs_info,
  1894			old_thread_pool_size, fs_info->thread_pool_size);
  1895		fs_info->metadata_ratio = old_metadata_ratio;
  1896		btrfs_remount_cleanup(fs_info, old_opts);
  1897		return ret;
  1898	}
  1899	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff mbox series

Patch

diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 580ba7db67e5..a2554c651548 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1834,6 +1834,8 @@  static int btrfs_remount(struct super_block *sb, int *flags, char *data)
 		}
 
 		if (btrfs_super_log_root(fs_info->super_copy) != 0) {
+			btrfs_warn(f_info,
+		"mount required to replay tree-log, cannot remount read-write");
 			ret = -EINVAL;
 			goto restore;
 		}