diff options
Diffstat (limited to 'fs/ext3')
-rw-r--r-- | fs/ext3/ialloc.c | 58 | ||||
-rw-r--r-- | fs/ext3/inode.c | 25 | ||||
-rw-r--r-- | fs/ext3/namei.c | 29 | ||||
-rw-r--r-- | fs/ext3/resize.c | 7 | ||||
-rw-r--r-- | fs/ext3/super.c | 40 |
5 files changed, 88 insertions, 71 deletions
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 1bc8cd89c51d..58ae2f943f12 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c | |||
@@ -642,14 +642,15 @@ struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino) | |||
642 | unsigned long max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count); | 642 | unsigned long max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count); |
643 | unsigned long block_group; | 643 | unsigned long block_group; |
644 | int bit; | 644 | int bit; |
645 | struct buffer_head *bitmap_bh = NULL; | 645 | struct buffer_head *bitmap_bh; |
646 | struct inode *inode = NULL; | 646 | struct inode *inode = NULL; |
647 | long err = -EIO; | ||
647 | 648 | ||
648 | /* Error cases - e2fsck has already cleaned up for us */ | 649 | /* Error cases - e2fsck has already cleaned up for us */ |
649 | if (ino > max_ino) { | 650 | if (ino > max_ino) { |
650 | ext3_warning(sb, __FUNCTION__, | 651 | ext3_warning(sb, __FUNCTION__, |
651 | "bad orphan ino %lu! e2fsck was run?", ino); | 652 | "bad orphan ino %lu! e2fsck was run?", ino); |
652 | goto out; | 653 | goto error; |
653 | } | 654 | } |
654 | 655 | ||
655 | block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb); | 656 | 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) | |||
658 | if (!bitmap_bh) { | 659 | if (!bitmap_bh) { |
659 | ext3_warning(sb, __FUNCTION__, | 660 | ext3_warning(sb, __FUNCTION__, |
660 | "inode bitmap error for orphan %lu", ino); | 661 | "inode bitmap error for orphan %lu", ino); |
661 | goto out; | 662 | goto error; |
662 | } | 663 | } |
663 | 664 | ||
664 | /* Having the inode bit set should be a 100% indicator that this | 665 | /* Having the inode bit set should be a 100% indicator that this |
665 | * is a valid orphan (no e2fsck run on fs). Orphans also include | 666 | * is a valid orphan (no e2fsck run on fs). Orphans also include |
666 | * inodes that were being truncated, so we can't check i_nlink==0. | 667 | * inodes that were being truncated, so we can't check i_nlink==0. |
667 | */ | 668 | */ |
668 | if (!ext3_test_bit(bit, bitmap_bh->b_data) || | 669 | if (!ext3_test_bit(bit, bitmap_bh->b_data)) |
669 | !(inode = iget(sb, ino)) || is_bad_inode(inode) || | 670 | goto bad_orphan; |
670 | NEXT_ORPHAN(inode) > max_ino) { | 671 | |
671 | ext3_warning(sb, __FUNCTION__, | 672 | inode = ext3_iget(sb, ino); |
672 | "bad orphan inode %lu! e2fsck was run?", ino); | 673 | if (IS_ERR(inode)) |
673 | printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n", | 674 | goto iget_failed; |
674 | bit, (unsigned long long)bitmap_bh->b_blocknr, | 675 | |
675 | ext3_test_bit(bit, bitmap_bh->b_data)); | 676 | if (NEXT_ORPHAN(inode) > max_ino) |
676 | printk(KERN_NOTICE "inode=%p\n", inode); | 677 | goto bad_orphan; |
677 | if (inode) { | 678 | brelse(bitmap_bh); |
678 | printk(KERN_NOTICE "is_bad_inode(inode)=%d\n", | 679 | return inode; |
679 | is_bad_inode(inode)); | 680 | |
680 | printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n", | 681 | iget_failed: |
681 | NEXT_ORPHAN(inode)); | 682 | err = PTR_ERR(inode); |
682 | printk(KERN_NOTICE "max_ino=%lu\n", max_ino); | 683 | inode = NULL; |
683 | } | 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); | ||
684 | /* Avoid freeing blocks if we got a bad deleted inode */ | 697 | /* Avoid freeing blocks if we got a bad deleted inode */ |
685 | if (inode && inode->i_nlink == 0) | 698 | if (inode->i_nlink == 0) |
686 | inode->i_blocks = 0; | 699 | inode->i_blocks = 0; |
687 | iput(inode); | 700 | iput(inode); |
688 | inode = NULL; | ||
689 | } | 701 | } |
690 | out: | ||
691 | brelse(bitmap_bh); | 702 | brelse(bitmap_bh); |
692 | return inode; | 703 | error: |
704 | return ERR_PTR(err); | ||
693 | } | 705 | } |
694 | 706 | ||
695 | unsigned long ext3_count_free_inodes (struct super_block * sb) | 707 | unsigned long ext3_count_free_inodes (struct super_block * sb) |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 8a9ce2d09bde..eb95670a27eb 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -2654,21 +2654,31 @@ void ext3_get_inode_flags(struct ext3_inode_info *ei) | |||
2654 | ei->i_flags |= EXT3_DIRSYNC_FL; | 2654 | ei->i_flags |= EXT3_DIRSYNC_FL; |
2655 | } | 2655 | } |
2656 | 2656 | ||
2657 | void ext3_read_inode(struct inode * inode) | 2657 | struct inode *ext3_iget(struct super_block *sb, unsigned long ino) |
2658 | { | 2658 | { |
2659 | struct ext3_iloc iloc; | 2659 | struct ext3_iloc iloc; |
2660 | struct ext3_inode *raw_inode; | 2660 | struct ext3_inode *raw_inode; |
2661 | struct ext3_inode_info *ei = EXT3_I(inode); | 2661 | struct ext3_inode_info *ei; |
2662 | struct buffer_head *bh; | 2662 | struct buffer_head *bh; |
2663 | struct inode *inode; | ||
2664 | long ret; | ||
2663 | int block; | 2665 | int block; |
2664 | 2666 | ||
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); | ||
2665 | #ifdef CONFIG_EXT3_FS_POSIX_ACL | 2674 | #ifdef CONFIG_EXT3_FS_POSIX_ACL |
2666 | ei->i_acl = EXT3_ACL_NOT_CACHED; | 2675 | ei->i_acl = EXT3_ACL_NOT_CACHED; |
2667 | ei->i_default_acl = EXT3_ACL_NOT_CACHED; | 2676 | ei->i_default_acl = EXT3_ACL_NOT_CACHED; |
2668 | #endif | 2677 | #endif |
2669 | ei->i_block_alloc_info = NULL; | 2678 | ei->i_block_alloc_info = NULL; |
2670 | 2679 | ||
2671 | if (__ext3_get_inode_loc(inode, &iloc, 0)) | 2680 | ret = __ext3_get_inode_loc(inode, &iloc, 0); |
2681 | if (ret < 0) | ||
2672 | goto bad_inode; | 2682 | goto bad_inode; |
2673 | bh = iloc.bh; | 2683 | bh = iloc.bh; |
2674 | raw_inode = ext3_raw_inode(&iloc); | 2684 | raw_inode = ext3_raw_inode(&iloc); |
@@ -2699,6 +2709,7 @@ void ext3_read_inode(struct inode * inode) | |||
2699 | !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ORPHAN_FS)) { | 2709 | !(EXT3_SB(inode->i_sb)->s_mount_state & EXT3_ORPHAN_FS)) { |
2700 | /* this inode is deleted */ | 2710 | /* this inode is deleted */ |
2701 | brelse (bh); | 2711 | brelse (bh); |
2712 | ret = -ESTALE; | ||
2702 | goto bad_inode; | 2713 | goto bad_inode; |
2703 | } | 2714 | } |
2704 | /* The only unlinked inodes we let through here have | 2715 | /* The only unlinked inodes we let through here have |
@@ -2742,6 +2753,7 @@ void ext3_read_inode(struct inode * inode) | |||
2742 | if (EXT3_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > | 2753 | if (EXT3_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > |
2743 | EXT3_INODE_SIZE(inode->i_sb)) { | 2754 | EXT3_INODE_SIZE(inode->i_sb)) { |
2744 | brelse (bh); | 2755 | brelse (bh); |
2756 | ret = -EIO; | ||
2745 | goto bad_inode; | 2757 | goto bad_inode; |
2746 | } | 2758 | } |
2747 | if (ei->i_extra_isize == 0) { | 2759 | if (ei->i_extra_isize == 0) { |
@@ -2783,11 +2795,12 @@ void ext3_read_inode(struct inode * inode) | |||
2783 | } | 2795 | } |
2784 | brelse (iloc.bh); | 2796 | brelse (iloc.bh); |
2785 | ext3_set_inode_flags(inode); | 2797 | ext3_set_inode_flags(inode); |
2786 | return; | 2798 | unlock_new_inode(inode); |
2799 | return inode; | ||
2787 | 2800 | ||
2788 | bad_inode: | 2801 | bad_inode: |
2789 | make_bad_inode(inode); | 2802 | iget_failed(inode); |
2790 | return; | 2803 | return ERR_PTR(ret); |
2791 | } | 2804 | } |
2792 | 2805 | ||
2793 | /* | 2806 | /* |
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 92b83b004dd8..dec3e0d88ab1 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -1037,17 +1037,11 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, str | |||
1037 | if (!ext3_valid_inum(dir->i_sb, ino)) { | 1037 | if (!ext3_valid_inum(dir->i_sb, ino)) { |
1038 | ext3_error(dir->i_sb, "ext3_lookup", | 1038 | ext3_error(dir->i_sb, "ext3_lookup", |
1039 | "bad inode number: %lu", ino); | 1039 | "bad inode number: %lu", ino); |
1040 | inode = NULL; | 1040 | return ERR_PTR(-EIO); |
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); | ||
1050 | } | 1041 | } |
1042 | inode = ext3_iget(dir->i_sb, ino); | ||
1043 | if (IS_ERR(inode)) | ||
1044 | return ERR_CAST(inode); | ||
1051 | } | 1045 | } |
1052 | return d_splice_alias(inode, dentry); | 1046 | return d_splice_alias(inode, dentry); |
1053 | } | 1047 | } |
@@ -1076,18 +1070,13 @@ struct dentry *ext3_get_parent(struct dentry *child) | |||
1076 | if (!ext3_valid_inum(child->d_inode->i_sb, ino)) { | 1070 | if (!ext3_valid_inum(child->d_inode->i_sb, ino)) { |
1077 | ext3_error(child->d_inode->i_sb, "ext3_get_parent", | 1071 | ext3_error(child->d_inode->i_sb, "ext3_get_parent", |
1078 | "bad inode number: %lu", ino); | 1072 | "bad inode number: %lu", ino); |
1079 | inode = NULL; | 1073 | return ERR_PTR(-EIO); |
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); | ||
1089 | } | 1074 | } |
1090 | 1075 | ||
1076 | inode = ext3_iget(child->d_inode->i_sb, ino); | ||
1077 | if (IS_ERR(inode)) | ||
1078 | return ERR_CAST(inode); | ||
1079 | |||
1091 | parent = d_alloc_anon(inode); | 1080 | parent = d_alloc_anon(inode); |
1092 | if (!parent) { | 1081 | if (!parent) { |
1093 | iput(inode); | 1082 | iput(inode); |
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index 44de1453c301..ebc05af7343a 100644 --- a/fs/ext3/resize.c +++ b/fs/ext3/resize.c | |||
@@ -795,12 +795,11 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input) | |||
795 | "No reserved GDT blocks, can't resize"); | 795 | "No reserved GDT blocks, can't resize"); |
796 | return -EPERM; | 796 | return -EPERM; |
797 | } | 797 | } |
798 | inode = iget(sb, EXT3_RESIZE_INO); | 798 | inode = ext3_iget(sb, EXT3_RESIZE_INO); |
799 | if (!inode || is_bad_inode(inode)) { | 799 | if (IS_ERR(inode)) { |
800 | ext3_warning(sb, __FUNCTION__, | 800 | ext3_warning(sb, __FUNCTION__, |
801 | "Error opening resize inode"); | 801 | "Error opening resize inode"); |
802 | iput(inode); | 802 | return PTR_ERR(inode); |
803 | return -ENOENT; | ||
804 | } | 803 | } |
805 | } | 804 | } |
806 | 805 | ||
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 343677e8c350..cf2a2c3660ec 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -649,11 +649,10 @@ static struct inode *ext3_nfs_get_inode(struct super_block *sb, | |||
649 | * Currently we don't know the generation for parent directory, so | 649 | * Currently we don't know the generation for parent directory, so |
650 | * a generation of 0 means "accept any" | 650 | * a generation of 0 means "accept any" |
651 | */ | 651 | */ |
652 | inode = iget(sb, ino); | 652 | inode = ext3_iget(sb, ino); |
653 | if (inode == NULL) | 653 | if (IS_ERR(inode)) |
654 | return ERR_PTR(-ENOMEM); | 654 | return ERR_CAST(inode); |
655 | if (is_bad_inode(inode) || | 655 | if (generation && inode->i_generation != generation) { |
656 | (generation && inode->i_generation != generation)) { | ||
657 | iput(inode); | 656 | iput(inode); |
658 | return ERR_PTR(-ESTALE); | 657 | return ERR_PTR(-ESTALE); |
659 | } | 658 | } |
@@ -722,7 +721,6 @@ static struct quotactl_ops ext3_qctl_operations = { | |||
722 | static const struct super_operations ext3_sops = { | 721 | static const struct super_operations ext3_sops = { |
723 | .alloc_inode = ext3_alloc_inode, | 722 | .alloc_inode = ext3_alloc_inode, |
724 | .destroy_inode = ext3_destroy_inode, | 723 | .destroy_inode = ext3_destroy_inode, |
725 | .read_inode = ext3_read_inode, | ||
726 | .write_inode = ext3_write_inode, | 724 | .write_inode = ext3_write_inode, |
727 | .dirty_inode = ext3_dirty_inode, | 725 | .dirty_inode = ext3_dirty_inode, |
728 | .delete_inode = ext3_delete_inode, | 726 | .delete_inode = ext3_delete_inode, |
@@ -1378,8 +1376,8 @@ static void ext3_orphan_cleanup (struct super_block * sb, | |||
1378 | while (es->s_last_orphan) { | 1376 | while (es->s_last_orphan) { |
1379 | struct inode *inode; | 1377 | struct inode *inode; |
1380 | 1378 | ||
1381 | if (!(inode = | 1379 | inode = ext3_orphan_get(sb, le32_to_cpu(es->s_last_orphan)); |
1382 | ext3_orphan_get(sb, le32_to_cpu(es->s_last_orphan)))) { | 1380 | if (IS_ERR(inode)) { |
1383 | es->s_last_orphan = 0; | 1381 | es->s_last_orphan = 0; |
1384 | break; | 1382 | break; |
1385 | } | 1383 | } |
@@ -1508,6 +1506,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1508 | int db_count; | 1506 | int db_count; |
1509 | int i; | 1507 | int i; |
1510 | int needs_recovery; | 1508 | int needs_recovery; |
1509 | int ret = -EINVAL; | ||
1511 | __le32 features; | 1510 | __le32 features; |
1512 | int err; | 1511 | int err; |
1513 | 1512 | ||
@@ -1877,19 +1876,24 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1877 | * so we can safely mount the rest of the filesystem now. | 1876 | * so we can safely mount the rest of the filesystem now. |
1878 | */ | 1877 | */ |
1879 | 1878 | ||
1880 | root = iget(sb, EXT3_ROOT_INO); | 1879 | root = ext3_iget(sb, EXT3_ROOT_INO); |
1881 | sb->s_root = d_alloc_root(root); | 1880 | if (IS_ERR(root)) { |
1882 | if (!sb->s_root) { | ||
1883 | printk(KERN_ERR "EXT3-fs: get root inode failed\n"); | 1881 | printk(KERN_ERR "EXT3-fs: get root inode failed\n"); |
1884 | iput(root); | 1882 | ret = PTR_ERR(root); |
1885 | goto failed_mount4; | 1883 | goto failed_mount4; |
1886 | } | 1884 | } |
1887 | if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { | 1885 | if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { |
1888 | dput(sb->s_root); | 1886 | iput(root); |
1889 | sb->s_root = NULL; | ||
1890 | printk(KERN_ERR "EXT3-fs: corrupt root inode, run e2fsck\n"); | 1887 | printk(KERN_ERR "EXT3-fs: corrupt root inode, run e2fsck\n"); |
1891 | goto failed_mount4; | 1888 | goto failed_mount4; |
1892 | } | 1889 | } |
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 | } | ||
1893 | 1897 | ||
1894 | ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY); | 1898 | ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY); |
1895 | /* | 1899 | /* |
@@ -1941,7 +1945,7 @@ out_fail: | |||
1941 | sb->s_fs_info = NULL; | 1945 | sb->s_fs_info = NULL; |
1942 | kfree(sbi); | 1946 | kfree(sbi); |
1943 | lock_kernel(); | 1947 | lock_kernel(); |
1944 | return -EINVAL; | 1948 | return ret; |
1945 | } | 1949 | } |
1946 | 1950 | ||
1947 | /* | 1951 | /* |
@@ -1977,8 +1981,8 @@ static journal_t *ext3_get_journal(struct super_block *sb, | |||
1977 | * things happen if we iget() an unused inode, as the subsequent | 1981 | * things happen if we iget() an unused inode, as the subsequent |
1978 | * iput() will try to delete it. */ | 1982 | * iput() will try to delete it. */ |
1979 | 1983 | ||
1980 | journal_inode = iget(sb, journal_inum); | 1984 | journal_inode = ext3_iget(sb, journal_inum); |
1981 | if (!journal_inode) { | 1985 | if (IS_ERR(journal_inode)) { |
1982 | printk(KERN_ERR "EXT3-fs: no journal found.\n"); | 1986 | printk(KERN_ERR "EXT3-fs: no journal found.\n"); |
1983 | return NULL; | 1987 | return NULL; |
1984 | } | 1988 | } |
@@ -1991,7 +1995,7 @@ static journal_t *ext3_get_journal(struct super_block *sb, | |||
1991 | 1995 | ||
1992 | jbd_debug(2, "Journal inode found at %p: %Ld bytes\n", | 1996 | jbd_debug(2, "Journal inode found at %p: %Ld bytes\n", |
1993 | journal_inode, journal_inode->i_size); | 1997 | 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)) { |
1995 | printk(KERN_ERR "EXT3-fs: invalid journal inode.\n"); | 1999 | printk(KERN_ERR "EXT3-fs: invalid journal inode.\n"); |
1996 | iput(journal_inode); | 2000 | iput(journal_inode); |
1997 | return NULL; | 2001 | return NULL; |