mirror of https://gitee.com/openkylin/linux.git
ufs: fix the logics for tail relocation
* original hysteresis loop got broken by typo back in 2002; now it never switches out of OPTTIME state. Fixed. * critical levels for switching from OPTTIME to OPTSPACE and back ought to be calculated once, at mount time. * we should use mul_u64_u32_div() for those calculations, now that ->s_dsize is 64bit. * to quote Kirk McKusick (in 1995 FreeBSD commit message): The threshold for switching from time-space and space-time is too small when minfree is 5%...so make it stay at space in this case. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
c0ef65d292
commit
77e9ce327d
|
@ -455,24 +455,14 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
|
|||
/*
|
||||
* allocate new block and move data
|
||||
*/
|
||||
switch (fs32_to_cpu(sb, usb1->fs_optim)) {
|
||||
case UFS_OPTSPACE:
|
||||
if (fs32_to_cpu(sb, usb1->fs_optim) == UFS_OPTSPACE) {
|
||||
request = newcount;
|
||||
if (uspi->s_minfree < 5 || uspi->cs_total.cs_nffree
|
||||
> uspi->s_dsize * uspi->s_minfree / (2 * 100))
|
||||
break;
|
||||
usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME);
|
||||
break;
|
||||
default:
|
||||
usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME);
|
||||
|
||||
case UFS_OPTTIME:
|
||||
if (uspi->cs_total.cs_nffree < uspi->s_space_to_time)
|
||||
usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME);
|
||||
} else {
|
||||
request = uspi->s_fpb;
|
||||
if (uspi->cs_total.cs_nffree < uspi->s_dsize *
|
||||
(uspi->s_minfree - 2) / 100)
|
||||
break;
|
||||
usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME);
|
||||
break;
|
||||
if (uspi->cs_total.cs_nffree > uspi->s_time_to_space)
|
||||
usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTSPACE);
|
||||
}
|
||||
result = ufs_alloc_fragments (inode, cgno, goal, request, err);
|
||||
if (result) {
|
||||
|
|
|
@ -1211,6 +1211,15 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
|
|||
|
||||
uspi->s_root_blocks = mul_u64_u32_div(uspi->s_dsize,
|
||||
uspi->s_minfree, 100);
|
||||
if (uspi->s_minfree <= 5) {
|
||||
uspi->s_time_to_space = ~0ULL;
|
||||
uspi->s_space_to_time = 0;
|
||||
usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTSPACE);
|
||||
} else {
|
||||
uspi->s_time_to_space = (uspi->s_root_blocks / 2) + 1;
|
||||
uspi->s_space_to_time = mul_u64_u32_div(uspi->s_dsize,
|
||||
uspi->s_minfree - 2, 100) - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute another frequently used values
|
||||
|
|
|
@ -792,6 +792,8 @@ struct ufs_sb_private_info {
|
|||
__s32 fs_magic; /* filesystem magic */
|
||||
unsigned int s_dirblksize;
|
||||
__u64 s_root_blocks;
|
||||
__u64 s_time_to_space;
|
||||
__u64 s_space_to_time;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue