Skip to content

Commit 473043d

Browse files
dhowellsLinus Torvalds
authored andcommitted
iget: stop EXT3 from using iget() and read_inode()
Stop the EXT3 filesystem from using iget() and read_inode(). Replace ext3_read_inode() with ext3_iget(), and call that instead of iget(). ext3_iget() then uses iget_locked() directly and returns a proper error code instead of an inode in the event of an error. ext3_fill_super() returns any error incurred when getting the root inode instead of EINVAL. [[email protected]: coding-style fixes] Signed-off-by: David Howells <[email protected]> Acked-by: "Theodore Ts'o" <[email protected]> Acked-by: Jan Kara <[email protected]> Cc: <[email protected]> Acked-by: Christoph Hellwig <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 52fcf70 commit 473043d

File tree

6 files changed

+89
-72
lines changed

6 files changed

+89
-72
lines changed

fs/ext3/ialloc.c

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -642,14 +642,15 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino)
642642
unsigned long max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count);
643643
unsigned long block_group;
644644
int bit;
645-
struct buffer_head *bitmap_bh = NULL;
645+
struct buffer_head *bitmap_bh;
646646
struct inode *inode = NULL;
647+
long err = -EIO;
647648

648649
/* Error cases - e2fsck has already cleaned up for us */
649650
if (ino > max_ino) {
650651
ext3_warning(sb, __FUNCTION__,
651652
"bad orphan ino %lu! e2fsck was run?", ino);
652-
goto out;
653+
goto error;
653654
}
654655

655656
block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb);
@@ -658,38 +659,49 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino)
658659
if (!bitmap_bh) {
659660
ext3_warning(sb, __FUNCTION__,
660661
"inode bitmap error for orphan %lu", ino);
661-
goto out;
662+
goto error;
662663
}
663664

664665
/* Having the inode bit set should be a 100% indicator that this
665666
* is a valid orphan (no e2fsck run on fs). Orphans also include
666667
* inodes that were being truncated, so we can't check i_nlink==0.
667668
*/
668-
if (!ext3_test_bit(bit, bitmap_bh->b_data) ||
669-
!(inode = iget(sb, ino)) || is_bad_inode(inode) ||
670-
NEXT_ORPHAN(inode) > max_ino) {
671-
ext3_warning(sb, __FUNCTION__,
672-
"bad orphan inode %lu! e2fsck was run?", ino);
673-
printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n",
674-
bit, (unsigned long long)bitmap_bh->b_blocknr,
675-
ext3_test_bit(bit, bitmap_bh->b_data));
676-
printk(KERN_NOTICE "inode=%p\n", inode);
677-
if (inode) {
678-
printk(KERN_NOTICE "is_bad_inode(inode)=%d\n",
679-
is_bad_inode(inode));
680-
printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n",
681-
NEXT_ORPHAN(inode));
682-
printk(KERN_NOTICE "max_ino=%lu\n", max_ino);
683-
}
669+
if (!ext3_test_bit(bit, bitmap_bh->b_data))
670+
goto bad_orphan;
671+
672+
inode = ext3_iget(sb, ino);
673+
if (IS_ERR(inode))
674+
goto iget_failed;
675+
676+
if (NEXT_ORPHAN(inode) > max_ino)
677+
goto bad_orphan;
678+
brelse(bitmap_bh);
679+
return inode;
680+
681+
iget_failed:
682+
err = PTR_ERR(inode);
683+
inode = NULL;
684+
bad_orphan:
685+
ext3_warning(sb, __FUNCTION__,
686+
"bad orphan inode %lu! e2fsck was run?", ino);
687+
printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n",
688+
bit, (unsigned long long)bitmap_bh->b_blocknr,
689+
ext3_test_bit(bit, bitmap_bh->b_data));
690+
printk(KERN_NOTICE "inode=%p\n", inode);
691+
if (inode) {
692+
printk(KERN_NOTICE "is_bad_inode(inode)=%d\n",
693+
is_bad_inode(inode));
694+
printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n",
695+
NEXT_ORPHAN(inode));
696+
printk(KERN_NOTICE "max_ino=%lu\n", max_ino);
684697
/* Avoid freeing blocks if we got a bad deleted inode */
685-
if (inode && inode->i_nlink == 0)
698+
if (inode->i_nlink == 0)
686699
inode->i_blocks = 0;
687700
iput(inode);
688-
inode = NULL;
689701
}
690-
out:
691702
brelse(bitmap_bh);
692-
return inode;
703+
error:
704+
return ERR_PTR(err);
693705
}
694706

695707
unsigned long ext3_count_free_inodes (struct super_block * sb)

fs/ext3/inode.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2654,21 +2654,31 @@ void ext3_get_inode_flags(struct ext3_inode_info *ei)
26542654
ei->i_flags |= EXT3_DIRSYNC_FL;
26552655
}
26562656

2657-
void ext3_read_inode(struct inode * inode)
2657+
struct inode *ext3_iget(struct super_block *sb, unsigned long ino)
26582658
{
26592659
struct ext3_iloc iloc;
26602660
struct ext3_inode *raw_inode;
2661-
struct ext3_inode_info *ei = EXT3_I(inode);
2661+
struct ext3_inode_info *ei;
26622662
struct buffer_head *bh;
2663+
struct inode *inode;
2664+
long ret;
26632665
int block;
26642666

2667+
inode = iget_locked(sb, ino);
2668+
if (!inode)
2669+
return ERR_PTR(-ENOMEM);
2670+
if (!(inode->i_state & I_NEW))
2671+
return inode;
2672+
2673+
ei = EXT3_I(inode);
26652674
#ifdef CONFIG_EXT3_FS_POSIX_ACL
26662675
ei->i_acl = EXT3_ACL_NOT_CACHED;
26672676
ei->i_default_acl = EXT3_ACL_NOT_CACHED;
26682677
#endif
26692678
ei->i_block_alloc_info = NULL;
26702679

2671-
if (__ext3_get_inode_loc(inode, &iloc, 0))
2680+
ret = __ext3_get_inode_loc(inode, &iloc, 0);
2681+
if (ret < 0)
26722682
goto bad_inode;
26732683
bh = iloc.bh;
26742684
raw_inode = ext3_raw_inode(&iloc);
@@ -2699,6 +2709,7 @@ void ext3_read_inode(struct inode * inode)
26992709
!(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ORPHAN_FS)) {
27002710
/* this inode is deleted */
27012711
brelse (bh);
2712+
ret = -ESTALE;
27022713
goto bad_inode;
27032714
}
27042715
/* The only unlinked inodes we let through here have
@@ -2742,6 +2753,7 @@ void ext3_read_inode(struct inode * inode)
27422753
if (EXT3_GOOD_OLD_INODE_SIZE + ei->i_extra_isize >
27432754
EXT3_INODE_SIZE(inode->i_sb)) {
27442755
brelse (bh);
2756+
ret = -EIO;
27452757
goto bad_inode;
27462758
}
27472759
if (ei->i_extra_isize == 0) {
@@ -2783,11 +2795,12 @@ void ext3_read_inode(struct inode * inode)
27832795
}
27842796
brelse (iloc.bh);
27852797
ext3_set_inode_flags(inode);
2786-
return;
2798+
unlock_new_inode(inode);
2799+
return inode;
27872800

27882801
bad_inode:
2789-
make_bad_inode(inode);
2790-
return;
2802+
iget_failed(inode);
2803+
return ERR_PTR(ret);
27912804
}
27922805

27932806
/*

fs/ext3/namei.c

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,17 +1037,11 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, str
10371037
if (!ext3_valid_inum(dir->i_sb, ino)) {
10381038
ext3_error(dir->i_sb, "ext3_lookup",
10391039
"bad inode number: %lu", ino);
1040-
inode = NULL;
1041-
} else
1042-
inode = iget(dir->i_sb, ino);
1043-
1044-
if (!inode)
1045-
return ERR_PTR(-EACCES);
1046-
1047-
if (is_bad_inode(inode)) {
1048-
iput(inode);
1049-
return ERR_PTR(-ENOENT);
1040+
return ERR_PTR(-EIO);
10501041
}
1042+
inode = ext3_iget(dir->i_sb, ino);
1043+
if (IS_ERR(inode))
1044+
return ERR_CAST(inode);
10511045
}
10521046
return d_splice_alias(inode, dentry);
10531047
}
@@ -1076,18 +1070,13 @@ struct dentry *ext3_get_parent(struct dentry *child)
10761070
if (!ext3_valid_inum(child->d_inode->i_sb, ino)) {
10771071
ext3_error(child->d_inode->i_sb, "ext3_get_parent",
10781072
"bad inode number: %lu", ino);
1079-
inode = NULL;
1080-
} else
1081-
inode = iget(child->d_inode->i_sb, ino);
1082-
1083-
if (!inode)
1084-
return ERR_PTR(-EACCES);
1085-
1086-
if (is_bad_inode(inode)) {
1087-
iput(inode);
1088-
return ERR_PTR(-ENOENT);
1073+
return ERR_PTR(-EIO);
10891074
}
10901075

1076+
inode = ext3_iget(child->d_inode->i_sb, ino);
1077+
if (IS_ERR(inode))
1078+
return ERR_CAST(inode);
1079+
10911080
parent = d_alloc_anon(inode);
10921081
if (!parent) {
10931082
iput(inode);

fs/ext3/resize.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -795,12 +795,11 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
795795
"No reserved GDT blocks, can't resize");
796796
return -EPERM;
797797
}
798-
inode = iget(sb, EXT3_RESIZE_INO);
799-
if (!inode || is_bad_inode(inode)) {
798+
inode = ext3_iget(sb, EXT3_RESIZE_INO);
799+
if (IS_ERR(inode)) {
800800
ext3_warning(sb, __FUNCTION__,
801801
"Error opening resize inode");
802-
iput(inode);
803-
return -ENOENT;
802+
return PTR_ERR(inode);
804803
}
805804
}
806805

fs/ext3/super.c

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -649,11 +649,10 @@ static struct inode *ext3_nfs_get_inode(struct super_block *sb,
649649
* Currently we don't know the generation for parent directory, so
650650
* a generation of 0 means "accept any"
651651
*/
652-
inode = iget(sb, ino);
653-
if (inode == NULL)
654-
return ERR_PTR(-ENOMEM);
655-
if (is_bad_inode(inode) ||
656-
(generation && inode->i_generation != generation)) {
652+
inode = ext3_iget(sb, ino);
653+
if (IS_ERR(inode))
654+
return ERR_CAST(inode);
655+
if (generation && inode->i_generation != generation) {
657656
iput(inode);
658657
return ERR_PTR(-ESTALE);
659658
}
@@ -722,7 +721,6 @@ static struct quotactl_ops ext3_qctl_operations = {
722721
static const struct super_operations ext3_sops = {
723722
.alloc_inode = ext3_alloc_inode,
724723
.destroy_inode = ext3_destroy_inode,
725-
.read_inode = ext3_read_inode,
726724
.write_inode = ext3_write_inode,
727725
.dirty_inode = ext3_dirty_inode,
728726
.delete_inode = ext3_delete_inode,
@@ -1378,8 +1376,8 @@ static void ext3_orphan_cleanup (struct super_block * sb,
13781376
while (es->s_last_orphan) {
13791377
struct inode *inode;
13801378

1381-
if (!(inode =
1382-
ext3_orphan_get(sb, le32_to_cpu(es->s_last_orphan)))) {
1379+
inode = ext3_orphan_get(sb, le32_to_cpu(es->s_last_orphan));
1380+
if (IS_ERR(inode)) {
13831381
es->s_last_orphan = 0;
13841382
break;
13851383
}
@@ -1508,6 +1506,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
15081506
int db_count;
15091507
int i;
15101508
int needs_recovery;
1509+
int ret = -EINVAL;
15111510
__le32 features;
15121511
int err;
15131512

@@ -1877,19 +1876,24 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
18771876
* so we can safely mount the rest of the filesystem now.
18781877
*/
18791878

1880-
root = iget(sb, EXT3_ROOT_INO);
1881-
sb->s_root = d_alloc_root(root);
1882-
if (!sb->s_root) {
1879+
root = ext3_iget(sb, EXT3_ROOT_INO);
1880+
if (IS_ERR(root)) {
18831881
printk(KERN_ERR "EXT3-fs: get root inode failed\n");
1884-
iput(root);
1882+
ret = PTR_ERR(root);
18851883
goto failed_mount4;
18861884
}
18871885
if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
1888-
dput(sb->s_root);
1889-
sb->s_root = NULL;
1886+
iput(root);
18901887
printk(KERN_ERR "EXT3-fs: corrupt root inode, run e2fsck\n");
18911888
goto failed_mount4;
18921889
}
1890+
sb->s_root = d_alloc_root(root);
1891+
if (!sb->s_root) {
1892+
printk(KERN_ERR "EXT3-fs: get root dentry failed\n");
1893+
iput(root);
1894+
ret = -ENOMEM;
1895+
goto failed_mount4;
1896+
}
18931897

18941898
ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY);
18951899
/*
@@ -1941,7 +1945,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
19411945
sb->s_fs_info = NULL;
19421946
kfree(sbi);
19431947
lock_kernel();
1944-
return -EINVAL;
1948+
return ret;
19451949
}
19461950

19471951
/*
@@ -1977,8 +1981,8 @@ static journal_t *ext3_get_journal(struct super_block *sb,
19771981
* things happen if we iget() an unused inode, as the subsequent
19781982
* iput() will try to delete it. */
19791983

1980-
journal_inode = iget(sb, journal_inum);
1981-
if (!journal_inode) {
1984+
journal_inode = ext3_iget(sb, journal_inum);
1985+
if (IS_ERR(journal_inode)) {
19821986
printk(KERN_ERR "EXT3-fs: no journal found.\n");
19831987
return NULL;
19841988
}
@@ -1991,7 +1995,7 @@ static journal_t *ext3_get_journal(struct super_block *sb,
19911995

19921996
jbd_debug(2, "Journal inode found at %p: %Ld bytes\n",
19931997
journal_inode, journal_inode->i_size);
1994-
if (is_bad_inode(journal_inode) || !S_ISREG(journal_inode->i_mode)) {
1998+
if (!S_ISREG(journal_inode->i_mode)) {
19951999
printk(KERN_ERR "EXT3-fs: invalid journal inode.\n");
19962000
iput(journal_inode);
19972001
return NULL;

include/linux/ext3_fs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,7 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode,
823823
sector_t iblock, unsigned long maxblocks, struct buffer_head *bh_result,
824824
int create, int extend_disksize);
825825

826-
extern void ext3_read_inode (struct inode *);
826+
extern struct inode *ext3_iget(struct super_block *, unsigned long);
827827
extern int ext3_write_inode (struct inode *, int);
828828
extern int ext3_setattr (struct dentry *, struct iattr *);
829829
extern void ext3_delete_inode (struct inode *);

0 commit comments

Comments
 (0)