diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2017-06-17 15:44:06 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-06-17 17:22:42 -0400 |
commit | 77e9ce327d9b607cd6e57c0f4524a654dc59c4b1 (patch) | |
tree | cb2bc18c6c0e09e2af7f5bbc3ad007acc77c8ebf | |
parent | c0ef65d2928249e822b813beb41b6c1478c556ab (diff) |
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>
-rw-r--r-- | fs/ufs/balloc.c | 22 | ||||
-rw-r--r-- | fs/ufs/super.c | 9 | ||||
-rw-r--r-- | fs/ufs/ufs_fs.h | 2 |
3 files changed, 17 insertions, 16 deletions
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index 0315fea1d589..f80be4c5df9d 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c | |||
@@ -455,24 +455,14 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, | |||
455 | /* | 455 | /* |
456 | * allocate new block and move data | 456 | * allocate new block and move data |
457 | */ | 457 | */ |
458 | switch (fs32_to_cpu(sb, usb1->fs_optim)) { | 458 | if (fs32_to_cpu(sb, usb1->fs_optim) == UFS_OPTSPACE) { |
459 | case UFS_OPTSPACE: | ||
460 | request = newcount; | 459 | request = newcount; |
461 | if (uspi->s_minfree < 5 || uspi->cs_total.cs_nffree | 460 | if (uspi->cs_total.cs_nffree < uspi->s_space_to_time) |
462 | > uspi->s_dsize * uspi->s_minfree / (2 * 100)) | 461 | usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); |
463 | break; | 462 | } else { |
464 | usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); | ||
465 | break; | ||
466 | default: | ||
467 | usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); | ||
468 | |||
469 | case UFS_OPTTIME: | ||
470 | request = uspi->s_fpb; | 463 | request = uspi->s_fpb; |
471 | if (uspi->cs_total.cs_nffree < uspi->s_dsize * | 464 | if (uspi->cs_total.cs_nffree > uspi->s_time_to_space) |
472 | (uspi->s_minfree - 2) / 100) | 465 | usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTSPACE); |
473 | break; | ||
474 | usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); | ||
475 | break; | ||
476 | } | 466 | } |
477 | result = ufs_alloc_fragments (inode, cgno, goal, request, err); | 467 | result = ufs_alloc_fragments (inode, cgno, goal, request, err); |
478 | if (result) { | 468 | if (result) { |
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 34656c7a8e22..f211b662dd92 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
@@ -1211,6 +1211,15 @@ magic_found: | |||
1211 | 1211 | ||
1212 | uspi->s_root_blocks = mul_u64_u32_div(uspi->s_dsize, | 1212 | uspi->s_root_blocks = mul_u64_u32_div(uspi->s_dsize, |
1213 | uspi->s_minfree, 100); | 1213 | uspi->s_minfree, 100); |
1214 | if (uspi->s_minfree <= 5) { | ||
1215 | uspi->s_time_to_space = ~0ULL; | ||
1216 | uspi->s_space_to_time = 0; | ||
1217 | usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTSPACE); | ||
1218 | } else { | ||
1219 | uspi->s_time_to_space = (uspi->s_root_blocks / 2) + 1; | ||
1220 | uspi->s_space_to_time = mul_u64_u32_div(uspi->s_dsize, | ||
1221 | uspi->s_minfree - 2, 100) - 1; | ||
1222 | } | ||
1214 | 1223 | ||
1215 | /* | 1224 | /* |
1216 | * Compute another frequently used values | 1225 | * Compute another frequently used values |
diff --git a/fs/ufs/ufs_fs.h b/fs/ufs/ufs_fs.h index 823d55a37586..150eef6f1233 100644 --- a/fs/ufs/ufs_fs.h +++ b/fs/ufs/ufs_fs.h | |||
@@ -792,6 +792,8 @@ struct ufs_sb_private_info { | |||
792 | __s32 fs_magic; /* filesystem magic */ | 792 | __s32 fs_magic; /* filesystem magic */ |
793 | unsigned int s_dirblksize; | 793 | unsigned int s_dirblksize; |
794 | __u64 s_root_blocks; | 794 | __u64 s_root_blocks; |
795 | __u64 s_time_to_space; | ||
796 | __u64 s_space_to_time; | ||
795 | }; | 797 | }; |
796 | 798 | ||
797 | /* | 799 | /* |