提交 d5db0f97 编写于 作者: E Eric Sandeen 提交者: Alex Elder

xfs: more reserved blocks fixups

This mangles the reserved blocks counts a little more.

1) add a helper function for the default reserved count
2) add helper functions to save/restore counts on ro/rw
3) save/restore reserved blocks on freeze/thaw
4) disallow changing reserved count while readonly

V2: changed field name to match Dave's changes
Signed-off-by: NEric Sandeen <sandeen@sandeen.net>
Signed-off-by: NAlex Elder <aelder@sgi.com>
上级 388f1f0c
...@@ -1431,6 +1431,9 @@ xfs_file_ioctl( ...@@ -1431,6 +1431,9 @@ xfs_file_ioctl(
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
if (mp->m_flags & XFS_MOUNT_RDONLY)
return -XFS_ERROR(EROFS);
if (copy_from_user(&inout, arg, sizeof(inout))) if (copy_from_user(&inout, arg, sizeof(inout)))
return -XFS_ERROR(EFAULT); return -XFS_ERROR(EFAULT);
......
...@@ -1256,6 +1256,29 @@ xfs_fs_statfs( ...@@ -1256,6 +1256,29 @@ xfs_fs_statfs(
return 0; return 0;
} }
STATIC void
xfs_save_resvblks(struct xfs_mount *mp)
{
__uint64_t resblks = 0;
mp->m_resblks_save = mp->m_resblks;
xfs_reserve_blocks(mp, &resblks, NULL);
}
STATIC void
xfs_restore_resvblks(struct xfs_mount *mp)
{
__uint64_t resblks;
if (mp->m_resblks_save) {
resblks = mp->m_resblks_save;
mp->m_resblks_save = 0;
} else
resblks = xfs_default_resblks(mp);
xfs_reserve_blocks(mp, &resblks, NULL);
}
STATIC int STATIC int
xfs_fs_remount( xfs_fs_remount(
struct super_block *sb, struct super_block *sb,
...@@ -1318,8 +1341,6 @@ xfs_fs_remount( ...@@ -1318,8 +1341,6 @@ xfs_fs_remount(
/* ro -> rw */ /* ro -> rw */
if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) { if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) {
__uint64_t resblks;
mp->m_flags &= ~XFS_MOUNT_RDONLY; mp->m_flags &= ~XFS_MOUNT_RDONLY;
if (mp->m_flags & XFS_MOUNT_BARRIER) if (mp->m_flags & XFS_MOUNT_BARRIER)
xfs_mountfs_check_barriers(mp); xfs_mountfs_check_barriers(mp);
...@@ -1342,15 +1363,7 @@ xfs_fs_remount( ...@@ -1342,15 +1363,7 @@ xfs_fs_remount(
* Fill out the reserve pool if it is empty. Use the stashed * Fill out the reserve pool if it is empty. Use the stashed
* value if it is non-zero, otherwise go with the default. * value if it is non-zero, otherwise go with the default.
*/ */
if (mp->m_resblks_save) { xfs_restore_resvblks(mp);
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 */ /* rw -> ro */
...@@ -1363,11 +1376,9 @@ xfs_fs_remount( ...@@ -1363,11 +1376,9 @@ xfs_fs_remount(
* so that if we get remounted rw, we can return it to the same * so that if we get remounted rw, we can return it to the same
* size. * size.
*/ */
__uint64_t resblks = 0;
xfs_quiesce_data(mp); xfs_quiesce_data(mp);
mp->m_resblks_save = mp->m_resblks; xfs_save_resvblks(mp);
xfs_reserve_blocks(mp, &resblks, NULL);
xfs_quiesce_attr(mp); xfs_quiesce_attr(mp);
mp->m_flags |= XFS_MOUNT_RDONLY; mp->m_flags |= XFS_MOUNT_RDONLY;
} }
...@@ -1386,10 +1397,21 @@ xfs_fs_freeze( ...@@ -1386,10 +1397,21 @@ xfs_fs_freeze(
{ {
struct xfs_mount *mp = XFS_M(sb); struct xfs_mount *mp = XFS_M(sb);
xfs_save_resvblks(mp);
xfs_quiesce_attr(mp); xfs_quiesce_attr(mp);
return -xfs_fs_log_dummy(mp); return -xfs_fs_log_dummy(mp);
} }
STATIC int
xfs_fs_unfreeze(
struct super_block *sb)
{
struct xfs_mount *mp = XFS_M(sb);
xfs_restore_resvblks(mp);
return 0;
}
STATIC int STATIC int
xfs_fs_show_options( xfs_fs_show_options(
struct seq_file *m, struct seq_file *m,
...@@ -1612,6 +1634,7 @@ static const struct super_operations xfs_super_operations = { ...@@ -1612,6 +1634,7 @@ static const struct super_operations xfs_super_operations = {
.put_super = xfs_fs_put_super, .put_super = xfs_fs_put_super,
.sync_fs = xfs_fs_sync_fs, .sync_fs = xfs_fs_sync_fs,
.freeze_fs = xfs_fs_freeze, .freeze_fs = xfs_fs_freeze,
.unfreeze_fs = xfs_fs_unfreeze,
.statfs = xfs_fs_statfs, .statfs = xfs_fs_statfs,
.remount_fs = xfs_fs_remount, .remount_fs = xfs_fs_remount,
.show_options = xfs_fs_show_options, .show_options = xfs_fs_show_options,
......
...@@ -1091,6 +1091,22 @@ xfs_mount_reset_sbqflags( ...@@ -1091,6 +1091,22 @@ xfs_mount_reset_sbqflags(
return xfs_trans_commit(tp, 0); return xfs_trans_commit(tp, 0);
} }
__uint64_t
xfs_default_resblks(xfs_mount_t *mp)
{
__uint64_t resblks;
/*
* We default to 5% or 1024 fsbs of space reserved, whichever is smaller.
* This may drive us straight to ENOSPC on mount, but that implies
* we were already there on the last unmount. Warn if this occurs.
*/
resblks = mp->m_sb.sb_dblocks;
do_div(resblks, 20);
resblks = min_t(__uint64_t, resblks, 1024);
return resblks;
}
/* /*
* This function does the following on an initial mount of a file system: * This function does the following on an initial mount of a file system:
* - reads the superblock from disk and init the mount struct * - reads the superblock from disk and init the mount struct
...@@ -1401,18 +1417,14 @@ xfs_mountfs( ...@@ -1401,18 +1417,14 @@ xfs_mountfs(
* when at ENOSPC. This is needed for operations like create with * when at ENOSPC. This is needed for operations like create with
* attr, unwritten extent conversion at ENOSPC, etc. Data allocations * attr, unwritten extent conversion at ENOSPC, etc. Data allocations
* are not allowed to use this reserved space. * are not allowed to use this reserved space.
*
* We default to 5% or 1024 fsbs of space reserved, whichever is smaller.
* This may drive us straight to ENOSPC on mount, but that implies
* we were already there on the last unmount. Warn if this occurs.
*/ */
resblks = mp->m_sb.sb_dblocks; if (!(mp->m_flags & XFS_MOUNT_RDONLY)) {
do_div(resblks, 20); resblks = xfs_default_resblks(mp);
resblks = min_t(__uint64_t, resblks, 1024);
error = xfs_reserve_blocks(mp, &resblks, NULL); error = xfs_reserve_blocks(mp, &resblks, NULL);
if (error) if (error)
cmn_err(CE_WARN, "XFS: Unable to allocate reserve blocks. " cmn_err(CE_WARN, "XFS: Unable to allocate reserve "
"Continuing without a reserve pool."); "blocks. Continuing without a reserve pool.");
}
return 0; return 0;
......
...@@ -421,6 +421,7 @@ typedef struct xfs_mod_sb { ...@@ -421,6 +421,7 @@ typedef struct xfs_mod_sb {
} xfs_mod_sb_t; } xfs_mod_sb_t;
extern int xfs_log_sbcount(xfs_mount_t *, uint); extern int xfs_log_sbcount(xfs_mount_t *, uint);
extern __uint64_t xfs_default_resblks(xfs_mount_t *mp);
extern int xfs_mountfs(xfs_mount_t *mp); extern int xfs_mountfs(xfs_mount_t *mp);
extern void xfs_unmountfs(xfs_mount_t *); extern void xfs_unmountfs(xfs_mount_t *);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册