Skip to content

Commit 021f601

Browse files
committed
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
2 parents bd726c9 + 77e9ce3 commit 021f601

File tree

4 files changed

+28
-32
lines changed

4 files changed

+28
-32
lines changed

fs/ufs/balloc.c

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -455,24 +455,14 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment,
455455
/*
456456
* allocate new block and move data
457457
*/
458-
switch (fs32_to_cpu(sb, usb1->fs_optim)) {
459-
case UFS_OPTSPACE:
458+
if (fs32_to_cpu(sb, usb1->fs_optim) == UFS_OPTSPACE) {
460459
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 {
470463
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);
476466
}
477467
result = ufs_alloc_fragments (inode, cgno, goal, request, err);
478468
if (result) {

fs/ufs/inode.c

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -566,10 +566,8 @@ static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode)
566566
*/
567567
inode->i_mode = mode = fs16_to_cpu(sb, ufs_inode->ui_mode);
568568
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;
573571

574572
/*
575573
* Linux now has 32-bit uid and gid, so we can support EFT.
@@ -578,9 +576,9 @@ static int ufs1_read_inode(struct inode *inode, struct ufs_inode *ufs_inode)
578576
i_gid_write(inode, ufs_get_inode_gid(sb, ufs_inode));
579577

580578
inode->i_size = fs64_to_cpu(sb, ufs_inode->ui_size);
581-
inode->i_atime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_atime.tv_sec);
582-
inode->i_ctime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_ctime.tv_sec);
583-
inode->i_mtime.tv_sec = fs32_to_cpu(sb, ufs_inode->ui_mtime.tv_sec);
579+
inode->i_atime.tv_sec = (signed)fs32_to_cpu(sb, ufs_inode->ui_atime.tv_sec);
580+
inode->i_ctime.tv_sec = (signed)fs32_to_cpu(sb, ufs_inode->ui_ctime.tv_sec);
581+
inode->i_mtime.tv_sec = (signed)fs32_to_cpu(sb, ufs_inode->ui_mtime.tv_sec);
584582
inode->i_mtime.tv_nsec = 0;
585583
inode->i_atime.tv_nsec = 0;
586584
inode->i_ctime.tv_nsec = 0;
@@ -614,10 +612,8 @@ static int ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode)
614612
*/
615613
inode->i_mode = mode = fs16_to_cpu(sb, ufs2_inode->ui_mode);
616614
set_nlink(inode, fs16_to_cpu(sb, ufs2_inode->ui_nlink));
617-
if (inode->i_nlink == 0) {
618-
ufs_error (sb, "ufs_read_inode", "inode %lu has zero nlink\n", inode->i_ino);
619-
return -1;
620-
}
615+
if (inode->i_nlink == 0)
616+
return -ESTALE;
621617

622618
/*
623619
* Linux now has 32-bit uid and gid, so we can support EFT.
@@ -657,7 +653,7 @@ struct inode *ufs_iget(struct super_block *sb, unsigned long ino)
657653
struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
658654
struct buffer_head * bh;
659655
struct inode *inode;
660-
int err;
656+
int err = -EIO;
661657

662658
UFSD("ENTER, ino %lu\n", ino);
663659

@@ -692,9 +688,10 @@ struct inode *ufs_iget(struct super_block *sb, unsigned long ino)
692688
err = ufs1_read_inode(inode,
693689
ufs_inode + ufs_inotofsbo(inode->i_ino));
694690
}
695-
691+
brelse(bh);
696692
if (err)
697693
goto bad_inode;
694+
698695
inode->i_version++;
699696
ufsi->i_lastfrag =
700697
(inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift;
@@ -703,15 +700,13 @@ struct inode *ufs_iget(struct super_block *sb, unsigned long ino)
703700

704701
ufs_set_inode_ops(inode);
705702

706-
brelse(bh);
707-
708703
UFSD("EXIT\n");
709704
unlock_new_inode(inode);
710705
return inode;
711706

712707
bad_inode:
713708
iget_failed(inode);
714-
return ERR_PTR(-EIO);
709+
return ERR_PTR(err);
715710
}
716711

717712
static void ufs1_update_inode(struct inode *inode, struct ufs_inode *ufs_inode)

fs/ufs/super.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,6 +1210,15 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
12101210

12111211
uspi->s_root_blocks = mul_u64_u32_div(uspi->s_dsize,
12121212
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+
}
12131222

12141223
/*
12151224
* Compute another frequently used values

fs/ufs/ufs_fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,8 @@ struct ufs_sb_private_info {
792792
__s32 fs_magic; /* filesystem magic */
793793
unsigned int s_dirblksize;
794794
__u64 s_root_blocks;
795+
__u64 s_time_to_space;
796+
__u64 s_space_to_time;
795797
};
796798

797799
/*

0 commit comments

Comments
 (0)