diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2009-01-05 22:19:52 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2009-01-05 22:19:52 -0500 |
commit | 5d1b1b3f492f8696ea18950a454a141381b0f926 (patch) | |
tree | e6277cd3e01c074403b9da7390de1daa6b9f248f /fs/ext4/ext4.h | |
parent | b7be019e80da4db96d283734d55366014509911c (diff) |
ext4: fix BUG when calling ext4_error with locked block group
The mballoc code likes to call ext4_error while it is holding locked
block groups. This can causes a scheduling in atomic context BUG. We
can't just unlock the block group and relock it after/if ext4_error
returns since that might result in race conditions in the case where
the filesystem is set to continue after finding errors.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/ext4.h')
-rw-r--r-- | fs/ext4/ext4.h | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 8152b5603f0a..f0b1db6acf85 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -1126,6 +1126,9 @@ extern void ext4_abort(struct super_block *, const char *, const char *, ...) | |||
1126 | __attribute__ ((format (printf, 3, 4))); | 1126 | __attribute__ ((format (printf, 3, 4))); |
1127 | extern void ext4_warning(struct super_block *, const char *, const char *, ...) | 1127 | extern void ext4_warning(struct super_block *, const char *, const char *, ...) |
1128 | __attribute__ ((format (printf, 3, 4))); | 1128 | __attribute__ ((format (printf, 3, 4))); |
1129 | extern void ext4_grp_locked_error(struct super_block *, ext4_group_t, | ||
1130 | const char *, const char *, ...) | ||
1131 | __attribute__ ((format (printf, 4, 5))); | ||
1129 | extern void ext4_update_dynamic_rev(struct super_block *sb); | 1132 | extern void ext4_update_dynamic_rev(struct super_block *sb); |
1130 | extern int ext4_update_compat_feature(handle_t *handle, struct super_block *sb, | 1133 | extern int ext4_update_compat_feature(handle_t *handle, struct super_block *sb, |
1131 | __u32 compat); | 1134 | __u32 compat); |
@@ -1249,6 +1252,50 @@ static inline void ext4_update_i_disksize(struct inode *inode, loff_t newsize) | |||
1249 | return ; | 1252 | return ; |
1250 | } | 1253 | } |
1251 | 1254 | ||
1255 | struct ext4_group_info { | ||
1256 | unsigned long bb_state; | ||
1257 | struct rb_root bb_free_root; | ||
1258 | unsigned short bb_first_free; | ||
1259 | unsigned short bb_free; | ||
1260 | unsigned short bb_fragments; | ||
1261 | struct list_head bb_prealloc_list; | ||
1262 | #ifdef DOUBLE_CHECK | ||
1263 | void *bb_bitmap; | ||
1264 | #endif | ||
1265 | struct rw_semaphore alloc_sem; | ||
1266 | unsigned short bb_counters[]; | ||
1267 | }; | ||
1268 | |||
1269 | #define EXT4_GROUP_INFO_NEED_INIT_BIT 0 | ||
1270 | #define EXT4_GROUP_INFO_LOCKED_BIT 1 | ||
1271 | |||
1272 | #define EXT4_MB_GRP_NEED_INIT(grp) \ | ||
1273 | (test_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &((grp)->bb_state))) | ||
1274 | |||
1275 | static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group) | ||
1276 | { | ||
1277 | struct ext4_group_info *grinfo = ext4_get_group_info(sb, group); | ||
1278 | |||
1279 | bit_spin_lock(EXT4_GROUP_INFO_LOCKED_BIT, &(grinfo->bb_state)); | ||
1280 | } | ||
1281 | |||
1282 | static inline void ext4_unlock_group(struct super_block *sb, | ||
1283 | ext4_group_t group) | ||
1284 | { | ||
1285 | struct ext4_group_info *grinfo = ext4_get_group_info(sb, group); | ||
1286 | |||
1287 | bit_spin_unlock(EXT4_GROUP_INFO_LOCKED_BIT, &(grinfo->bb_state)); | ||
1288 | } | ||
1289 | |||
1290 | static inline int ext4_is_group_locked(struct super_block *sb, | ||
1291 | ext4_group_t group) | ||
1292 | { | ||
1293 | struct ext4_group_info *grinfo = ext4_get_group_info(sb, group); | ||
1294 | |||
1295 | return bit_spin_is_locked(EXT4_GROUP_INFO_LOCKED_BIT, | ||
1296 | &(grinfo->bb_state)); | ||
1297 | } | ||
1298 | |||
1252 | /* | 1299 | /* |
1253 | * Inodes and files operations | 1300 | * Inodes and files operations |
1254 | */ | 1301 | */ |