diff options
Diffstat (limited to 'fs/ext4/resize.c')
-rw-r--r-- | fs/ext4/resize.c | 36 |
1 files changed, 18 insertions, 18 deletions
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 546c7dd869e1..27eb289eea37 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | 16 | ||
17 | #include "ext4_jbd2.h" | 17 | #include "ext4_jbd2.h" |
18 | #include "group.h" | ||
19 | 18 | ||
20 | #define outside(b, first, last) ((b) < (first) || (b) >= (last)) | 19 | #define outside(b, first, last) ((b) < (first) || (b) >= (last)) |
21 | #define inside(b, first, last) ((b) >= (first) && (b) < (last)) | 20 | #define inside(b, first, last) ((b) >= (first) && (b) < (last)) |
@@ -193,7 +192,7 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
193 | if (IS_ERR(handle)) | 192 | if (IS_ERR(handle)) |
194 | return PTR_ERR(handle); | 193 | return PTR_ERR(handle); |
195 | 194 | ||
196 | lock_super(sb); | 195 | mutex_lock(&sbi->s_resize_lock); |
197 | if (input->group != sbi->s_groups_count) { | 196 | if (input->group != sbi->s_groups_count) { |
198 | err = -EBUSY; | 197 | err = -EBUSY; |
199 | goto exit_journal; | 198 | goto exit_journal; |
@@ -302,7 +301,7 @@ exit_bh: | |||
302 | brelse(bh); | 301 | brelse(bh); |
303 | 302 | ||
304 | exit_journal: | 303 | exit_journal: |
305 | unlock_super(sb); | 304 | mutex_unlock(&sbi->s_resize_lock); |
306 | if ((err2 = ext4_journal_stop(handle)) && !err) | 305 | if ((err2 = ext4_journal_stop(handle)) && !err) |
307 | err = err2; | 306 | err = err2; |
308 | 307 | ||
@@ -643,11 +642,12 @@ exit_free: | |||
643 | * important part is that the new block and inode counts are in the backup | 642 | * important part is that the new block and inode counts are in the backup |
644 | * superblocks, and the location of the new group metadata in the GDT backups. | 643 | * superblocks, and the location of the new group metadata in the GDT backups. |
645 | * | 644 | * |
646 | * We do not need lock_super() for this, because these blocks are not | 645 | * We do not need take the s_resize_lock for this, because these |
647 | * otherwise touched by the filesystem code when it is mounted. We don't | 646 | * blocks are not otherwise touched by the filesystem code when it is |
648 | * need to worry about last changing from sbi->s_groups_count, because the | 647 | * mounted. We don't need to worry about last changing from |
649 | * worst that can happen is that we do not copy the full number of backups | 648 | * sbi->s_groups_count, because the worst that can happen is that we |
650 | * at this time. The resize which changed s_groups_count will backup again. | 649 | * do not copy the full number of backups at this time. The resize |
650 | * which changed s_groups_count will backup again. | ||
651 | */ | 651 | */ |
652 | static void update_backups(struct super_block *sb, | 652 | static void update_backups(struct super_block *sb, |
653 | int blk_off, char *data, int size) | 653 | int blk_off, char *data, int size) |
@@ -809,7 +809,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
809 | goto exit_put; | 809 | goto exit_put; |
810 | } | 810 | } |
811 | 811 | ||
812 | lock_super(sb); | 812 | mutex_lock(&sbi->s_resize_lock); |
813 | if (input->group != sbi->s_groups_count) { | 813 | if (input->group != sbi->s_groups_count) { |
814 | ext4_warning(sb, __func__, | 814 | ext4_warning(sb, __func__, |
815 | "multiple resizers run on filesystem!"); | 815 | "multiple resizers run on filesystem!"); |
@@ -840,7 +840,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
840 | /* | 840 | /* |
841 | * OK, now we've set up the new group. Time to make it active. | 841 | * OK, now we've set up the new group. Time to make it active. |
842 | * | 842 | * |
843 | * Current kernels don't lock all allocations via lock_super(), | 843 | * We do not lock all allocations via s_resize_lock |
844 | * so we have to be safe wrt. concurrent accesses the group | 844 | * so we have to be safe wrt. concurrent accesses the group |
845 | * data. So we need to be careful to set all of the relevant | 845 | * data. So we need to be careful to set all of the relevant |
846 | * group descriptor data etc. *before* we enable the group. | 846 | * group descriptor data etc. *before* we enable the group. |
@@ -900,12 +900,12 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
900 | * | 900 | * |
901 | * The precise rules we use are: | 901 | * The precise rules we use are: |
902 | * | 902 | * |
903 | * * Writers of s_groups_count *must* hold lock_super | 903 | * * Writers of s_groups_count *must* hold s_resize_lock |
904 | * AND | 904 | * AND |
905 | * * Writers must perform a smp_wmb() after updating all dependent | 905 | * * Writers must perform a smp_wmb() after updating all dependent |
906 | * data and before modifying the groups count | 906 | * data and before modifying the groups count |
907 | * | 907 | * |
908 | * * Readers must hold lock_super() over the access | 908 | * * Readers must hold s_resize_lock over the access |
909 | * OR | 909 | * OR |
910 | * * Readers must perform an smp_rmb() after reading the groups count | 910 | * * Readers must perform an smp_rmb() after reading the groups count |
911 | * and before reading any dependent data. | 911 | * and before reading any dependent data. |
@@ -948,7 +948,7 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) | |||
948 | sb->s_dirt = 1; | 948 | sb->s_dirt = 1; |
949 | 949 | ||
950 | exit_journal: | 950 | exit_journal: |
951 | unlock_super(sb); | 951 | mutex_unlock(&sbi->s_resize_lock); |
952 | if ((err2 = ext4_journal_stop(handle)) && !err) | 952 | if ((err2 = ext4_journal_stop(handle)) && !err) |
953 | err = err2; | 953 | err = err2; |
954 | if (!err) { | 954 | if (!err) { |
@@ -986,7 +986,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
986 | 986 | ||
987 | /* We don't need to worry about locking wrt other resizers just | 987 | /* We don't need to worry about locking wrt other resizers just |
988 | * yet: we're going to revalidate es->s_blocks_count after | 988 | * yet: we're going to revalidate es->s_blocks_count after |
989 | * taking lock_super() below. */ | 989 | * taking the s_resize_lock below. */ |
990 | o_blocks_count = ext4_blocks_count(es); | 990 | o_blocks_count = ext4_blocks_count(es); |
991 | o_groups_count = EXT4_SB(sb)->s_groups_count; | 991 | o_groups_count = EXT4_SB(sb)->s_groups_count; |
992 | 992 | ||
@@ -1056,11 +1056,11 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
1056 | goto exit_put; | 1056 | goto exit_put; |
1057 | } | 1057 | } |
1058 | 1058 | ||
1059 | lock_super(sb); | 1059 | mutex_lock(&EXT4_SB(sb)->s_resize_lock); |
1060 | if (o_blocks_count != ext4_blocks_count(es)) { | 1060 | if (o_blocks_count != ext4_blocks_count(es)) { |
1061 | ext4_warning(sb, __func__, | 1061 | ext4_warning(sb, __func__, |
1062 | "multiple resizers run on filesystem!"); | 1062 | "multiple resizers run on filesystem!"); |
1063 | unlock_super(sb); | 1063 | mutex_unlock(&EXT4_SB(sb)->s_resize_lock); |
1064 | ext4_journal_stop(handle); | 1064 | ext4_journal_stop(handle); |
1065 | err = -EBUSY; | 1065 | err = -EBUSY; |
1066 | goto exit_put; | 1066 | goto exit_put; |
@@ -1070,14 +1070,14 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, | |||
1070 | EXT4_SB(sb)->s_sbh))) { | 1070 | EXT4_SB(sb)->s_sbh))) { |
1071 | ext4_warning(sb, __func__, | 1071 | ext4_warning(sb, __func__, |
1072 | "error %d on journal write access", err); | 1072 | "error %d on journal write access", err); |
1073 | unlock_super(sb); | 1073 | mutex_unlock(&EXT4_SB(sb)->s_resize_lock); |
1074 | ext4_journal_stop(handle); | 1074 | ext4_journal_stop(handle); |
1075 | goto exit_put; | 1075 | goto exit_put; |
1076 | } | 1076 | } |
1077 | ext4_blocks_count_set(es, o_blocks_count + add); | 1077 | ext4_blocks_count_set(es, o_blocks_count + add); |
1078 | ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh); | 1078 | ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh); |
1079 | sb->s_dirt = 1; | 1079 | sb->s_dirt = 1; |
1080 | unlock_super(sb); | 1080 | mutex_unlock(&EXT4_SB(sb)->s_resize_lock); |
1081 | ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count, | 1081 | ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count, |
1082 | o_blocks_count + add); | 1082 | o_blocks_count + add); |
1083 | /* We add the blocks to the bitmap and set the group need init bit */ | 1083 | /* We add the blocks to the bitmap and set the group need init bit */ |