int f2fs_truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end);
 void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count);
 int f2fs_do_shutdown(struct f2fs_sb_info *sbi, unsigned int flag,
-                                                       bool readonly);
+                                               bool readonly, bool need_lock);
 int f2fs_precache_extents(struct inode *inode);
 int f2fs_fileattr_get(struct dentry *dentry, struct fileattr *fa);
 int f2fs_fileattr_set(struct mnt_idmap *idmap,
 
 }
 
 int f2fs_do_shutdown(struct f2fs_sb_info *sbi, unsigned int flag,
-                                                       bool readonly)
+                                               bool readonly, bool need_lock)
 {
        struct super_block *sb = sbi->sb;
        int ret = 0;
        if (readonly)
                goto out;
 
+       /* grab sb->s_umount to avoid racing w/ remount() */
+       if (need_lock)
+               down_read(&sbi->sb->s_umount);
+
        f2fs_stop_gc_thread(sbi);
        f2fs_stop_discard_thread(sbi);
 
        f2fs_drop_discard_cmd(sbi);
        clear_opt(sbi, DISCARD);
 
+       if (need_lock)
+               up_read(&sbi->sb->s_umount);
+
        f2fs_update_time(sbi, REQ_TIME);
 out:
 
                }
        }
 
-       ret = f2fs_do_shutdown(sbi, in, readonly);
+       ret = f2fs_do_shutdown(sbi, in, readonly, true);
 
        if (need_drop)
                mnt_drop_write_file(filp);
 
 
 static void f2fs_shutdown(struct super_block *sb)
 {
-       f2fs_do_shutdown(F2FS_SB(sb), F2FS_GOING_DOWN_NOSYNC, false);
+       f2fs_do_shutdown(F2FS_SB(sb), F2FS_GOING_DOWN_NOSYNC, false, false);
 }
 
 #ifdef CONFIG_QUOTA