|
@@ -1318,6 +1318,8 @@ xfs_fs_remount(
|
|
|
|
|
|
/* ro -> rw */
|
|
|
if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) {
|
|
|
+ __uint64_t resblks;
|
|
|
+
|
|
|
mp->m_flags &= ~XFS_MOUNT_RDONLY;
|
|
|
if (mp->m_flags & XFS_MOUNT_BARRIER)
|
|
|
xfs_mountfs_check_barriers(mp);
|
|
@@ -1335,11 +1337,37 @@ xfs_fs_remount(
|
|
|
}
|
|
|
mp->m_update_flags = 0;
|
|
|
}
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Fill out the reserve pool if it is empty. Use the stashed
|
|
|
+ * value if it is non-zero, otherwise go with the default.
|
|
|
+ */
|
|
|
+ if (mp->m_resblks_save) {
|
|
|
+ resblks = mp->m_resblks_save;
|
|
|
+ mp->m_resblks_save = 0;
|
|
|
+ } else {
|
|
|
+ resblks = mp->m_sb.sb_dblocks;
|
|
|
+ do_div(resblks, 20);
|
|
|
+ resblks = min_t(__uint64_t, resblks, 1024);
|
|
|
+ }
|
|
|
+ xfs_reserve_blocks(mp, &resblks, NULL);
|
|
|
}
|
|
|
|
|
|
/* rw -> ro */
|
|
|
if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) {
|
|
|
+ /*
|
|
|
+ * After we have synced the data but before we sync the
|
|
|
+ * metadata, we need to free up the reserve block pool so that
|
|
|
+ * the used block count in the superblock on disk is correct at
|
|
|
+ * the end of the remount. Stash the current reserve pool size
|
|
|
+ * so that if we get remounted rw, we can return it to the same
|
|
|
+ * size.
|
|
|
+ */
|
|
|
+ __uint64_t resblks = 0;
|
|
|
+
|
|
|
xfs_quiesce_data(mp);
|
|
|
+ mp->m_resblks_save = mp->m_resblks;
|
|
|
+ xfs_reserve_blocks(mp, &resblks, NULL);
|
|
|
xfs_quiesce_attr(mp);
|
|
|
mp->m_flags |= XFS_MOUNT_RDONLY;
|
|
|
}
|