diff options
Diffstat (limited to 'fs/ext3')
| -rw-r--r-- | fs/ext3/inode.c | 8 | ||||
| -rw-r--r-- | fs/ext3/namei.c | 28 | ||||
| -rw-r--r-- | fs/ext3/resize.c | 35 | ||||
| -rw-r--r-- | fs/ext3/super.c | 19 |
4 files changed, 40 insertions, 50 deletions
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index ad14227f509e..455e6e6e5cb9 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
| @@ -970,7 +970,7 @@ static int ext3_get_block(struct inode *inode, sector_t iblock, | |||
| 970 | if (max_blocks > DIO_MAX_BLOCKS) | 970 | if (max_blocks > DIO_MAX_BLOCKS) |
| 971 | max_blocks = DIO_MAX_BLOCKS; | 971 | max_blocks = DIO_MAX_BLOCKS; |
| 972 | handle = ext3_journal_start(inode, DIO_CREDITS + | 972 | handle = ext3_journal_start(inode, DIO_CREDITS + |
| 973 | 2 * EXT3_QUOTA_TRANS_BLOCKS(inode->i_sb)); | 973 | EXT3_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb)); |
| 974 | if (IS_ERR(handle)) { | 974 | if (IS_ERR(handle)) { |
| 975 | ret = PTR_ERR(handle); | 975 | ret = PTR_ERR(handle); |
| 976 | goto out; | 976 | goto out; |
| @@ -3146,8 +3146,8 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 3146 | 3146 | ||
| 3147 | /* (user+group)*(old+new) structure, inode write (sb, | 3147 | /* (user+group)*(old+new) structure, inode write (sb, |
| 3148 | * inode block, ? - but truncate inode update has it) */ | 3148 | * inode block, ? - but truncate inode update has it) */ |
| 3149 | handle = ext3_journal_start(inode, 2*(EXT3_QUOTA_INIT_BLOCKS(inode->i_sb)+ | 3149 | handle = ext3_journal_start(inode, EXT3_MAXQUOTAS_INIT_BLOCKS(inode->i_sb)+ |
| 3150 | EXT3_QUOTA_DEL_BLOCKS(inode->i_sb))+3); | 3150 | EXT3_MAXQUOTAS_DEL_BLOCKS(inode->i_sb)+3); |
| 3151 | if (IS_ERR(handle)) { | 3151 | if (IS_ERR(handle)) { |
| 3152 | error = PTR_ERR(handle); | 3152 | error = PTR_ERR(handle); |
| 3153 | goto err_out; | 3153 | goto err_out; |
| @@ -3239,7 +3239,7 @@ static int ext3_writepage_trans_blocks(struct inode *inode) | |||
| 3239 | #ifdef CONFIG_QUOTA | 3239 | #ifdef CONFIG_QUOTA |
| 3240 | /* We know that structure was already allocated during vfs_dq_init so | 3240 | /* We know that structure was already allocated during vfs_dq_init so |
| 3241 | * we will be updating only the data blocks + inodes */ | 3241 | * we will be updating only the data blocks + inodes */ |
| 3242 | ret += 2*EXT3_QUOTA_TRANS_BLOCKS(inode->i_sb); | 3242 | ret += EXT3_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb); |
| 3243 | #endif | 3243 | #endif |
| 3244 | 3244 | ||
| 3245 | return ret; | 3245 | return ret; |
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index aad6400c9b77..7b0e44f7d66f 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
| @@ -1699,7 +1699,7 @@ static int ext3_create (struct inode * dir, struct dentry * dentry, int mode, | |||
| 1699 | retry: | 1699 | retry: |
| 1700 | handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + | 1700 | handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + |
| 1701 | EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + | 1701 | EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + |
| 1702 | 2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb)); | 1702 | EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb)); |
| 1703 | if (IS_ERR(handle)) | 1703 | if (IS_ERR(handle)) |
| 1704 | return PTR_ERR(handle); | 1704 | return PTR_ERR(handle); |
| 1705 | 1705 | ||
| @@ -1733,7 +1733,7 @@ static int ext3_mknod (struct inode * dir, struct dentry *dentry, | |||
| 1733 | retry: | 1733 | retry: |
| 1734 | handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + | 1734 | handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + |
| 1735 | EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + | 1735 | EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + |
| 1736 | 2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb)); | 1736 | EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb)); |
| 1737 | if (IS_ERR(handle)) | 1737 | if (IS_ERR(handle)) |
| 1738 | return PTR_ERR(handle); | 1738 | return PTR_ERR(handle); |
| 1739 | 1739 | ||
| @@ -1769,7 +1769,7 @@ static int ext3_mkdir(struct inode * dir, struct dentry * dentry, int mode) | |||
| 1769 | retry: | 1769 | retry: |
| 1770 | handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + | 1770 | handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + |
| 1771 | EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + | 1771 | EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 + |
| 1772 | 2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb)); | 1772 | EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb)); |
| 1773 | if (IS_ERR(handle)) | 1773 | if (IS_ERR(handle)) |
| 1774 | return PTR_ERR(handle); | 1774 | return PTR_ERR(handle); |
| 1775 | 1775 | ||
| @@ -1920,7 +1920,7 @@ int ext3_orphan_add(handle_t *handle, struct inode *inode) | |||
| 1920 | struct ext3_iloc iloc; | 1920 | struct ext3_iloc iloc; |
| 1921 | int err = 0, rc; | 1921 | int err = 0, rc; |
| 1922 | 1922 | ||
| 1923 | lock_super(sb); | 1923 | mutex_lock(&EXT3_SB(sb)->s_orphan_lock); |
| 1924 | if (!list_empty(&EXT3_I(inode)->i_orphan)) | 1924 | if (!list_empty(&EXT3_I(inode)->i_orphan)) |
| 1925 | goto out_unlock; | 1925 | goto out_unlock; |
| 1926 | 1926 | ||
| @@ -1929,9 +1929,13 @@ int ext3_orphan_add(handle_t *handle, struct inode *inode) | |||
| 1929 | 1929 | ||
| 1930 | /* @@@ FIXME: Observation from aviro: | 1930 | /* @@@ FIXME: Observation from aviro: |
| 1931 | * I think I can trigger J_ASSERT in ext3_orphan_add(). We block | 1931 | * I think I can trigger J_ASSERT in ext3_orphan_add(). We block |
| 1932 | * here (on lock_super()), so race with ext3_link() which might bump | 1932 | * here (on s_orphan_lock), so race with ext3_link() which might bump |
| 1933 | * ->i_nlink. For, say it, character device. Not a regular file, | 1933 | * ->i_nlink. For, say it, character device. Not a regular file, |
| 1934 | * not a directory, not a symlink and ->i_nlink > 0. | 1934 | * not a directory, not a symlink and ->i_nlink > 0. |
| 1935 | * | ||
| 1936 | * tytso, 4/25/2009: I'm not sure how that could happen; | ||
| 1937 | * shouldn't the fs core protect us from these sort of | ||
| 1938 | * unlink()/link() races? | ||
| 1935 | */ | 1939 | */ |
| 1936 | J_ASSERT ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | 1940 | J_ASSERT ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || |
| 1937 | S_ISLNK(inode->i_mode)) || inode->i_nlink == 0); | 1941 | S_ISLNK(inode->i_mode)) || inode->i_nlink == 0); |
| @@ -1968,7 +1972,7 @@ int ext3_orphan_add(handle_t *handle, struct inode *inode) | |||
| 1968 | jbd_debug(4, "orphan inode %lu will point to %d\n", | 1972 | jbd_debug(4, "orphan inode %lu will point to %d\n", |
| 1969 | inode->i_ino, NEXT_ORPHAN(inode)); | 1973 | inode->i_ino, NEXT_ORPHAN(inode)); |
| 1970 | out_unlock: | 1974 | out_unlock: |
| 1971 | unlock_super(sb); | 1975 | mutex_unlock(&EXT3_SB(sb)->s_orphan_lock); |
| 1972 | ext3_std_error(inode->i_sb, err); | 1976 | ext3_std_error(inode->i_sb, err); |
| 1973 | return err; | 1977 | return err; |
| 1974 | } | 1978 | } |
| @@ -1986,11 +1990,9 @@ int ext3_orphan_del(handle_t *handle, struct inode *inode) | |||
| 1986 | struct ext3_iloc iloc; | 1990 | struct ext3_iloc iloc; |
| 1987 | int err = 0; | 1991 | int err = 0; |
| 1988 | 1992 | ||
| 1989 | lock_super(inode->i_sb); | 1993 | mutex_lock(&EXT3_SB(inode->i_sb)->s_orphan_lock); |
| 1990 | if (list_empty(&ei->i_orphan)) { | 1994 | if (list_empty(&ei->i_orphan)) |
| 1991 | unlock_super(inode->i_sb); | 1995 | goto out; |
| 1992 | return 0; | ||
| 1993 | } | ||
| 1994 | 1996 | ||
| 1995 | ino_next = NEXT_ORPHAN(inode); | 1997 | ino_next = NEXT_ORPHAN(inode); |
| 1996 | prev = ei->i_orphan.prev; | 1998 | prev = ei->i_orphan.prev; |
| @@ -2040,7 +2042,7 @@ int ext3_orphan_del(handle_t *handle, struct inode *inode) | |||
| 2040 | out_err: | 2042 | out_err: |
| 2041 | ext3_std_error(inode->i_sb, err); | 2043 | ext3_std_error(inode->i_sb, err); |
| 2042 | out: | 2044 | out: |
| 2043 | unlock_super(inode->i_sb); | 2045 | mutex_unlock(&EXT3_SB(inode->i_sb)->s_orphan_lock); |
| 2044 | return err; | 2046 | return err; |
| 2045 | 2047 | ||
| 2046 | out_brelse: | 2048 | out_brelse: |
| @@ -2175,7 +2177,7 @@ static int ext3_symlink (struct inode * dir, | |||
| 2175 | retry: | 2177 | retry: |
| 2176 | handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + | 2178 | handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) + |
| 2177 | EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5 + | 2179 | EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5 + |
| 2178 | 2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb)); | 2180 | EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb)); |
| 2179 | if (IS_ERR(handle)) | 2181 | if (IS_ERR(handle)) |
| 2180 | return PTR_ERR(handle); | 2182 | return PTR_ERR(handle); |
| 2181 | 2183 | ||
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index 5f83b6179178..54351ac7cef9 100644 --- a/fs/ext3/resize.c +++ b/fs/ext3/resize.c | |||
| @@ -209,7 +209,7 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
| 209 | if (IS_ERR(handle)) | 209 | if (IS_ERR(handle)) |
| 210 | return PTR_ERR(handle); | 210 | return PTR_ERR(handle); |
| 211 | 211 | ||
| 212 | lock_super(sb); | 212 | mutex_lock(&sbi->s_resize_lock); |
| 213 | if (input->group != sbi->s_groups_count) { | 213 | if (input->group != sbi->s_groups_count) { |
| 214 | err = -EBUSY; | 214 | err = -EBUSY; |
| 215 | goto exit_journal; | 215 | goto exit_journal; |
| @@ -324,7 +324,7 @@ exit_bh: | |||
| 324 | brelse(bh); | 324 | brelse(bh); |
| 325 | 325 | ||
| 326 | exit_journal: | 326 | exit_journal: |
| 327 | unlock_super(sb); | 327 | mutex_unlock(&sbi->s_resize_lock); |
| 328 | if ((err2 = ext3_journal_stop(handle)) && !err) | 328 | if ((err2 = ext3_journal_stop(handle)) && !err) |
| 329 | err = err2; | 329 | err = err2; |
| 330 | 330 | ||
| @@ -662,11 +662,12 @@ exit_free: | |||
| 662 | * important part is that the new block and inode counts are in the backup | 662 | * important part is that the new block and inode counts are in the backup |
| 663 | * superblocks, and the location of the new group metadata in the GDT backups. | 663 | * superblocks, and the location of the new group metadata in the GDT backups. |
| 664 | * | 664 | * |
| 665 | * We do not need lock_super() for this, because these blocks are not | 665 | * We do not need take the s_resize_lock for this, because these |
| 666 | * otherwise touched by the filesystem code when it is mounted. We don't | 666 | * blocks are not otherwise touched by the filesystem code when it is |
| 667 | * need to worry about last changing from sbi->s_groups_count, because the | 667 | * mounted. We don't need to worry about last changing from |
| 668 | * worst that can happen is that we do not copy the full number of backups | 668 | * sbi->s_groups_count, because the worst that can happen is that we |
| 669 | * at this time. The resize which changed s_groups_count will backup again. | 669 | * do not copy the full number of backups at this time. The resize |
| 670 | * which changed s_groups_count will backup again. | ||
| 670 | */ | 671 | */ |
| 671 | static void update_backups(struct super_block *sb, | 672 | static void update_backups(struct super_block *sb, |
| 672 | int blk_off, char *data, int size) | 673 | int blk_off, char *data, int size) |
| @@ -825,7 +826,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input) | |||
| 825 | goto exit_put; | 826 | goto exit_put; |
| 826 | } | 827 | } |
| 827 | 828 | ||
| 828 | lock_super(sb); | 829 | mutex_lock(&sbi->s_resize_lock); |
| 829 | if (input->group != sbi->s_groups_count) { | 830 | if (input->group != sbi->s_groups_count) { |
| 830 | ext3_warning(sb, __func__, | 831 | ext3_warning(sb, __func__, |
| 831 | "multiple resizers run on filesystem!"); | 832 | "multiple resizers run on filesystem!"); |
| @@ -856,7 +857,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input) | |||
| 856 | /* | 857 | /* |
| 857 | * OK, now we've set up the new group. Time to make it active. | 858 | * OK, now we've set up the new group. Time to make it active. |
| 858 | * | 859 | * |
| 859 | * Current kernels don't lock all allocations via lock_super(), | 860 | * We do not lock all allocations via s_resize_lock |
| 860 | * so we have to be safe wrt. concurrent accesses the group | 861 | * so we have to be safe wrt. concurrent accesses the group |
| 861 | * data. So we need to be careful to set all of the relevant | 862 | * data. So we need to be careful to set all of the relevant |
| 862 | * group descriptor data etc. *before* we enable the group. | 863 | * group descriptor data etc. *before* we enable the group. |
| @@ -900,12 +901,12 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input) | |||
| 900 | * | 901 | * |
| 901 | * The precise rules we use are: | 902 | * The precise rules we use are: |
| 902 | * | 903 | * |
| 903 | * * Writers of s_groups_count *must* hold lock_super | 904 | * * Writers of s_groups_count *must* hold s_resize_lock |
| 904 | * AND | 905 | * AND |
| 905 | * * Writers must perform a smp_wmb() after updating all dependent | 906 | * * Writers must perform a smp_wmb() after updating all dependent |
| 906 | * data and before modifying the groups count | 907 | * data and before modifying the groups count |
| 907 | * | 908 | * |
| 908 | * * Readers must hold lock_super() over the access | 909 | * * Readers must hold s_resize_lock over the access |
| 909 | * OR | 910 | * OR |
| 910 | * * Readers must perform an smp_rmb() after reading the groups count | 911 | * * Readers must perform an smp_rmb() after reading the groups count |
| 911 | * and before reading any dependent data. | 912 | * and before reading any dependent data. |
| @@ -936,7 +937,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input) | |||
| 936 | ext3_journal_dirty_metadata(handle, sbi->s_sbh); | 937 | ext3_journal_dirty_metadata(handle, sbi->s_sbh); |
| 937 | 938 | ||
| 938 | exit_journal: | 939 | exit_journal: |
| 939 | unlock_super(sb); | 940 | mutex_unlock(&sbi->s_resize_lock); |
| 940 | if ((err2 = ext3_journal_stop(handle)) && !err) | 941 | if ((err2 = ext3_journal_stop(handle)) && !err) |
| 941 | err = err2; | 942 | err = err2; |
| 942 | if (!err) { | 943 | if (!err) { |
| @@ -973,7 +974,7 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es, | |||
| 973 | 974 | ||
| 974 | /* We don't need to worry about locking wrt other resizers just | 975 | /* We don't need to worry about locking wrt other resizers just |
| 975 | * yet: we're going to revalidate es->s_blocks_count after | 976 | * yet: we're going to revalidate es->s_blocks_count after |
| 976 | * taking lock_super() below. */ | 977 | * taking the s_resize_lock below. */ |
| 977 | o_blocks_count = le32_to_cpu(es->s_blocks_count); | 978 | o_blocks_count = le32_to_cpu(es->s_blocks_count); |
| 978 | o_groups_count = EXT3_SB(sb)->s_groups_count; | 979 | o_groups_count = EXT3_SB(sb)->s_groups_count; |
| 979 | 980 | ||
| @@ -1045,11 +1046,11 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es, | |||
| 1045 | goto exit_put; | 1046 | goto exit_put; |
| 1046 | } | 1047 | } |
| 1047 | 1048 | ||
| 1048 | lock_super(sb); | 1049 | mutex_lock(&EXT3_SB(sb)->s_resize_lock); |
| 1049 | if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) { | 1050 | if (o_blocks_count != le32_to_cpu(es->s_blocks_count)) { |
| 1050 | ext3_warning(sb, __func__, | 1051 | ext3_warning(sb, __func__, |
| 1051 | "multiple resizers run on filesystem!"); | 1052 | "multiple resizers run on filesystem!"); |
| 1052 | unlock_super(sb); | 1053 | mutex_unlock(&EXT3_SB(sb)->s_resize_lock); |
| 1053 | ext3_journal_stop(handle); | 1054 | ext3_journal_stop(handle); |
| 1054 | err = -EBUSY; | 1055 | err = -EBUSY; |
| 1055 | goto exit_put; | 1056 | goto exit_put; |
| @@ -1059,13 +1060,13 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es, | |||
| 1059 | EXT3_SB(sb)->s_sbh))) { | 1060 | EXT3_SB(sb)->s_sbh))) { |
| 1060 | ext3_warning(sb, __func__, | 1061 | ext3_warning(sb, __func__, |
| 1061 | "error %d on journal write access", err); | 1062 | "error %d on journal write access", err); |
| 1062 | unlock_super(sb); | 1063 | mutex_unlock(&EXT3_SB(sb)->s_resize_lock); |
| 1063 | ext3_journal_stop(handle); | 1064 | ext3_journal_stop(handle); |
| 1064 | goto exit_put; | 1065 | goto exit_put; |
| 1065 | } | 1066 | } |
| 1066 | es->s_blocks_count = cpu_to_le32(o_blocks_count + add); | 1067 | es->s_blocks_count = cpu_to_le32(o_blocks_count + add); |
| 1067 | ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); | 1068 | ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); |
| 1068 | unlock_super(sb); | 1069 | mutex_unlock(&EXT3_SB(sb)->s_resize_lock); |
| 1069 | ext3_debug("freeing blocks %lu through "E3FSBLK"\n", o_blocks_count, | 1070 | ext3_debug("freeing blocks %lu through "E3FSBLK"\n", o_blocks_count, |
| 1070 | o_blocks_count + add); | 1071 | o_blocks_count + add); |
| 1071 | ext3_free_blocks_sb(handle, sb, o_blocks_count, add, &freed_blocks); | 1072 | ext3_free_blocks_sb(handle, sb, o_blocks_count, add, &freed_blocks); |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 7ad1e8c30bd0..afa2b569da10 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
| @@ -1928,6 +1928,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
| 1928 | sb->dq_op = &ext3_quota_operations; | 1928 | sb->dq_op = &ext3_quota_operations; |
| 1929 | #endif | 1929 | #endif |
| 1930 | INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ | 1930 | INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ |
| 1931 | mutex_init(&sbi->s_orphan_lock); | ||
| 1932 | mutex_init(&sbi->s_resize_lock); | ||
| 1931 | 1933 | ||
| 1932 | sb->s_root = NULL; | 1934 | sb->s_root = NULL; |
| 1933 | 1935 | ||
| @@ -2014,14 +2016,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
| 2014 | } | 2016 | } |
| 2015 | 2017 | ||
| 2016 | ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY); | 2018 | ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY); |
| 2017 | /* | 2019 | |
| 2018 | * akpm: core read_super() calls in here with the superblock locked. | ||
| 2019 | * That deadlocks, because orphan cleanup needs to lock the superblock | ||
| 2020 | * in numerous places. Here we just pop the lock - it's relatively | ||
| 2021 | * harmless, because we are now ready to accept write_super() requests, | ||
| 2022 | * and aviro says that's the only reason for hanging onto the | ||
| 2023 | * superblock lock. | ||
| 2024 | */ | ||
| 2025 | EXT3_SB(sb)->s_mount_state |= EXT3_ORPHAN_FS; | 2020 | EXT3_SB(sb)->s_mount_state |= EXT3_ORPHAN_FS; |
| 2026 | ext3_orphan_cleanup(sb, es); | 2021 | ext3_orphan_cleanup(sb, es); |
| 2027 | EXT3_SB(sb)->s_mount_state &= ~EXT3_ORPHAN_FS; | 2022 | EXT3_SB(sb)->s_mount_state &= ~EXT3_ORPHAN_FS; |
| @@ -2403,13 +2398,11 @@ static void ext3_mark_recovery_complete(struct super_block * sb, | |||
| 2403 | if (journal_flush(journal) < 0) | 2398 | if (journal_flush(journal) < 0) |
| 2404 | goto out; | 2399 | goto out; |
| 2405 | 2400 | ||
| 2406 | lock_super(sb); | ||
| 2407 | if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) && | 2401 | if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) && |
| 2408 | sb->s_flags & MS_RDONLY) { | 2402 | sb->s_flags & MS_RDONLY) { |
| 2409 | EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); | 2403 | EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); |
| 2410 | ext3_commit_super(sb, es, 1); | 2404 | ext3_commit_super(sb, es, 1); |
| 2411 | } | 2405 | } |
| 2412 | unlock_super(sb); | ||
| 2413 | 2406 | ||
| 2414 | out: | 2407 | out: |
| 2415 | journal_unlock_updates(journal); | 2408 | journal_unlock_updates(journal); |
| @@ -2601,13 +2594,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data) | |||
| 2601 | (sbi->s_mount_state & EXT3_VALID_FS)) | 2594 | (sbi->s_mount_state & EXT3_VALID_FS)) |
| 2602 | es->s_state = cpu_to_le16(sbi->s_mount_state); | 2595 | es->s_state = cpu_to_le16(sbi->s_mount_state); |
| 2603 | 2596 | ||
| 2604 | /* | ||
| 2605 | * We have to unlock super so that we can wait for | ||
| 2606 | * transactions. | ||
| 2607 | */ | ||
| 2608 | unlock_super(sb); | ||
| 2609 | ext3_mark_recovery_complete(sb, es); | 2597 | ext3_mark_recovery_complete(sb, es); |
| 2610 | lock_super(sb); | ||
| 2611 | } else { | 2598 | } else { |
| 2612 | __le32 ret; | 2599 | __le32 ret; |
| 2613 | if ((ret = EXT3_HAS_RO_COMPAT_FEATURE(sb, | 2600 | if ((ret = EXT3_HAS_RO_COMPAT_FEATURE(sb, |
