diff options
author | Jan Kara <jack@suse.cz> | 2010-01-06 15:58:48 -0500 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2010-03-04 18:20:20 -0500 |
commit | 9df93939b735dd273e49cbee290b9f4738500ef4 (patch) | |
tree | 2840172239e13d1c0fea496755b8346a9b394336 /include | |
parent | 26245c949c8473ea7352907b5a54bc34487eb87f (diff) |
ext3: Use bitops to read/modify EXT3_I(inode)->i_state
At several places we modify EXT3_I(inode)->i_state without holding i_mutex
(ext3_release_file, ext3_bmap, ext3_journalled_writepage, ext3_do_update_inode,
...). These modifications are racy and we can lose updates to i_state. So
convert handling of i_state to use bitops which are atomic.
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/ext3_fs.h | 33 | ||||
-rw-r--r-- | include/linux/ext3_fs_i.h | 2 |
2 files changed, 26 insertions, 9 deletions
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index 6b049030fbe6..e6590f8f0b3c 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h | |||
@@ -202,14 +202,6 @@ static inline __u32 ext3_mask_flags(umode_t mode, __u32 flags) | |||
202 | return flags & EXT3_OTHER_FLMASK; | 202 | return flags & EXT3_OTHER_FLMASK; |
203 | } | 203 | } |
204 | 204 | ||
205 | /* | ||
206 | * Inode dynamic state flags | ||
207 | */ | ||
208 | #define EXT3_STATE_JDATA 0x00000001 /* journaled data exists */ | ||
209 | #define EXT3_STATE_NEW 0x00000002 /* inode is newly created */ | ||
210 | #define EXT3_STATE_XATTR 0x00000004 /* has in-inode xattrs */ | ||
211 | #define EXT3_STATE_FLUSH_ON_CLOSE 0x00000008 | ||
212 | |||
213 | /* Used to pass group descriptor data when online resize is done */ | 205 | /* Used to pass group descriptor data when online resize is done */ |
214 | struct ext3_new_group_input { | 206 | struct ext3_new_group_input { |
215 | __u32 group; /* Group number for this data */ | 207 | __u32 group; /* Group number for this data */ |
@@ -560,6 +552,31 @@ static inline int ext3_valid_inum(struct super_block *sb, unsigned long ino) | |||
560 | (ino >= EXT3_FIRST_INO(sb) && | 552 | (ino >= EXT3_FIRST_INO(sb) && |
561 | ino <= le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)); | 553 | ino <= le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)); |
562 | } | 554 | } |
555 | |||
556 | /* | ||
557 | * Inode dynamic state flags | ||
558 | */ | ||
559 | enum { | ||
560 | EXT3_STATE_JDATA, /* journaled data exists */ | ||
561 | EXT3_STATE_NEW, /* inode is newly created */ | ||
562 | EXT3_STATE_XATTR, /* has in-inode xattrs */ | ||
563 | EXT3_STATE_FLUSH_ON_CLOSE, /* flush dirty pages on close */ | ||
564 | }; | ||
565 | |||
566 | static inline int ext3_test_inode_state(struct inode *inode, int bit) | ||
567 | { | ||
568 | return test_bit(bit, &EXT3_I(inode)->i_state); | ||
569 | } | ||
570 | |||
571 | static inline void ext3_set_inode_state(struct inode *inode, int bit) | ||
572 | { | ||
573 | set_bit(bit, &EXT3_I(inode)->i_state); | ||
574 | } | ||
575 | |||
576 | static inline void ext3_clear_inode_state(struct inode *inode, int bit) | ||
577 | { | ||
578 | clear_bit(bit, &EXT3_I(inode)->i_state); | ||
579 | } | ||
563 | #else | 580 | #else |
564 | /* Assume that user mode programs are passing in an ext3fs superblock, not | 581 | /* Assume that user mode programs are passing in an ext3fs superblock, not |
565 | * a kernel struct super_block. This will allow us to call the feature-test | 582 | * a kernel struct super_block. This will allow us to call the feature-test |
diff --git a/include/linux/ext3_fs_i.h b/include/linux/ext3_fs_i.h index 93e7428156ba..7679acdb519a 100644 --- a/include/linux/ext3_fs_i.h +++ b/include/linux/ext3_fs_i.h | |||
@@ -87,7 +87,7 @@ struct ext3_inode_info { | |||
87 | * near to their parent directory's inode. | 87 | * near to their parent directory's inode. |
88 | */ | 88 | */ |
89 | __u32 i_block_group; | 89 | __u32 i_block_group; |
90 | __u32 i_state; /* Dynamic state flags for ext3 */ | 90 | unsigned long i_state; /* Dynamic state flags for ext3 */ |
91 | 91 | ||
92 | /* block reservation info */ | 92 | /* block reservation info */ |
93 | struct ext3_block_alloc_info *i_block_alloc_info; | 93 | struct ext3_block_alloc_info *i_block_alloc_info; |