Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'ufs-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull more ufs fixes from Al Viro:
"More UFS fixes, unfortunately including build regression fix for the
64-bit s_dsize commit. Fixed in this pile:

- trivial bug in signedness of 32bit timestamps on ufs1

- ESTALE instead of ufs_error() when doing open-by-fhandle on
something deleted

- build regression on 32bit in ufs_new_fragments() - calculating that
many percents of u64 pulls libgcc stuff on some of those. Mea
culpa.

- fix hysteresis loop broken by typo in 2.4.14.7 (right next to the
location of previous bug).

- fix the insane limits of said hysteresis loop on filesystems with
very low percentage of reserved blocks. If it's 5% or less, just
use the OPTSPACE policy.

- calculate those limits once and mount time.

This tree does pass xfstests clean (both ufs1 and ufs2) and it _does_
survive cross-builds.

Again, my apologies for missing that, especially since I have noticed
a related percentage-of-64bit issue in earlier patches (when dealing
with amount of reserved blocks). Self-LART applied..."

* 'ufs-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
ufs: fix the logics for tail relocation
ufs_iget(): fail with -ESTALE on deleted inode
fix signedness of timestamps on ufs1

+28 -32
+6 -16
fs/ufs/balloc.c
··· 455 455 /* 456 456 * allocate new block and move data 457 457 */ 458 - switch (fs32_to_cpu(sb, usb1->fs_optim)) { 459 - case UFS_OPTSPACE: 458 + if (fs32_to_cpu(sb, usb1->fs_optim) == UFS_OPTSPACE) { 460 459 request = newcount; 461 - if (uspi->s_minfree < 5 || uspi->cs_total.cs_nffree 462 - > uspi->s_dsize * uspi->s_minfree / (2 * 100)) 463 - break; 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: 460 + if (uspi->cs_total.cs_nffree < uspi->s_space_to_time) 461 + usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); 462 + } else { 470 463 request = uspi->s_fpb; 471 - if (uspi->cs_total.cs_nffree < uspi->s_dsize * 472 - (uspi->s_minfree - 2) / 100) 473 - break; 474 - usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTTIME); 475 - break; 464 + if (uspi->cs_total.cs_nffree > uspi->s_time_to_space) 465 + usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTSPACE); 476 466 } 477 467 result = ufs_alloc_fragments (inode, cgno, goal, request, err); 478 468 if (result) {
+11 -16
fs/ufs/inode.c
··· 566 566 */ 567 567 inode->i_mode = mode = fs16_to_cpu(sb, ufs_inode->ui_mode); 568 568 set_nlink(inode, fs16_to_cpu(sb, ufs_inode->ui_nlink)); 569 - if (inode->i_nlink == 0) { 570 - ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", inode->i_ino); 571 - return -1; 572 - } 569 + if (inode->i_nlink == 0) 570 + return -ESTALE; 573 571 574 572 /* 575 573 * Linux now has 32-bit uid and gid, so we can support EFT. ··· 576 578 i_gid_write(inode, ufs_get_inode_gid(sb, ufs_inode)); 577 579 578 580 inode->i_size = fs64_to_cpu(sb, ufs_inode->ui_size); 579 - inode->i_atime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_atime.tv_sec); 580 - inode->i_ctime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_ctime.tv_sec); 581 - inode->i_mtime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_mtime.tv_sec); 581 + inode->i_atime.tv_sec = (signed)fs32_to_cpu(sb, ufs_inode->ui_atime.tv_sec); 582 + inode->i_ctime.tv_sec = (signed)fs32_to_cpu(sb, ufs_inode->ui_ctime.tv_sec); 583 + inode->i_mtime.tv_sec = (signed)fs32_to_cpu(sb, ufs_inode->ui_mtime.tv_sec); 582 584 inode->i_mtime.tv_nsec = 0; 583 585 inode->i_atime.tv_nsec = 0; 584 586 inode->i_ctime.tv_nsec = 0; ··· 612 614 */ 613 615 inode->i_mode = mode = fs16_to_cpu(sb, ufs2_inode->ui_mode); 614 616 set_nlink(inode, fs16_to_cpu(sb, ufs2_inode->ui_nlink)); 615 - if (inode->i_nlink == 0) { 616 - ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", inode->i_ino); 617 - return -1; 618 - } 617 + if (inode->i_nlink == 0) 618 + return -ESTALE; 619 619 620 620 /* 621 621 * Linux now has 32-bit uid and gid, so we can support EFT. ··· 653 657 struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; 654 658 struct buffer_head * bh; 655 659 struct inode *inode; 656 - int err; 660 + int err = -EIO; 657 661 658 662 UFSD("ENTER, ino %lu\n", ino); 659 663 ··· 688 692 err = ufs1_read_inode(inode, 689 693 ufs_inode + ufs_inotofsbo(inode->i_ino)); 690 694 } 691 - 695 + brelse(bh); 692 696 if (err) 693 697 goto bad_inode; 698 + 694 699 inode->i_version++; 695 700 ufsi->i_lastfrag = 696 701 (inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift; ··· 700 703 701 704 ufs_set_inode_ops(inode); 702 705 703 - brelse(bh); 704 - 705 706 UFSD("EXIT\n"); 706 707 unlock_new_inode(inode); 707 708 return inode; 708 709 709 710 bad_inode: 710 711 iget_failed(inode); 711 - return ERR_PTR(-EIO); 712 + return ERR_PTR(err); 712 713 } 713 714 714 715 static void ufs1_update_inode(struct inode *inode, struct ufs_inode *ufs_inode)
+9
fs/ufs/super.c
··· 1210 1210 1211 1211 uspi->s_root_blocks = mul_u64_u32_div(uspi->s_dsize, 1212 1212 uspi->s_minfree, 100); 1213 + if (uspi->s_minfree <= 5) { 1214 + uspi->s_time_to_space = ~0ULL; 1215 + uspi->s_space_to_time = 0; 1216 + usb1->fs_optim = cpu_to_fs32(sb, UFS_OPTSPACE); 1217 + } else { 1218 + uspi->s_time_to_space = (uspi->s_root_blocks / 2) + 1; 1219 + uspi->s_space_to_time = mul_u64_u32_div(uspi->s_dsize, 1220 + uspi->s_minfree - 2, 100) - 1; 1221 + } 1213 1222 1214 1223 /* 1215 1224 * Compute another frequently used values
+2
fs/ufs/ufs_fs.h
··· 792 792 __s32 fs_magic; /* filesystem magic */ 793 793 unsigned int s_dirblksize; 794 794 __u64 s_root_blocks; 795 + __u64 s_time_to_space; 796 + __u64 s_space_to_time; 795 797 }; 796 798 797 799 /*