diff options
author | Theodore Ts'o <tytso@mit.edu> | 2010-01-24 14:34:07 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2010-01-24 14:34:07 -0500 |
commit | 19f5fb7ad679bb361222c7916086435020c37cce (patch) | |
tree | 9e301163075c4faaf340cf50afd51855c76acd8c /fs/ext4/ext4.h | |
parent | d2eecb03936878ec574ade5532fa83df7d75dde7 (diff) |
ext4: Use bitops to read/modify EXT4_I(inode)->i_state
At several places we modify EXT4_I(inode)->i_state without holding
i_mutex (ext4_release_file, ext4_bmap, ext4_journalled_writepage,
ext4_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.
Cc: Jan Kara <jack@suse.cz>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/ext4.h')
-rw-r--r-- | fs/ext4/ext4.h | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 307ecd13a76..ffe1334c891 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -313,17 +313,6 @@ static inline __u32 ext4_mask_flags(umode_t mode, __u32 flags) | |||
313 | return flags & EXT4_OTHER_FLMASK; | 313 | return flags & EXT4_OTHER_FLMASK; |
314 | } | 314 | } |
315 | 315 | ||
316 | /* | ||
317 | * Inode dynamic state flags | ||
318 | */ | ||
319 | #define EXT4_STATE_JDATA 0x00000001 /* journaled data exists */ | ||
320 | #define EXT4_STATE_NEW 0x00000002 /* inode is newly created */ | ||
321 | #define EXT4_STATE_XATTR 0x00000004 /* has in-inode xattrs */ | ||
322 | #define EXT4_STATE_NO_EXPAND 0x00000008 /* No space for expansion */ | ||
323 | #define EXT4_STATE_DA_ALLOC_CLOSE 0x00000010 /* Alloc DA blks on close */ | ||
324 | #define EXT4_STATE_EXT_MIGRATE 0x00000020 /* Inode is migrating */ | ||
325 | #define EXT4_STATE_DIO_UNWRITTEN 0x00000040 /* need convert on dio done*/ | ||
326 | |||
327 | /* Used to pass group descriptor data when online resize is done */ | 316 | /* Used to pass group descriptor data when online resize is done */ |
328 | struct ext4_new_group_input { | 317 | struct ext4_new_group_input { |
329 | __u32 group; /* Group number for this data */ | 318 | __u32 group; /* Group number for this data */ |
@@ -631,7 +620,7 @@ struct ext4_inode_info { | |||
631 | * near to their parent directory's inode. | 620 | * near to their parent directory's inode. |
632 | */ | 621 | */ |
633 | ext4_group_t i_block_group; | 622 | ext4_group_t i_block_group; |
634 | __u32 i_state; /* Dynamic state flags for ext4 */ | 623 | unsigned long i_state_flags; /* Dynamic state flags */ |
635 | 624 | ||
636 | ext4_lblk_t i_dir_start_lookup; | 625 | ext4_lblk_t i_dir_start_lookup; |
637 | #ifdef CONFIG_EXT4_FS_XATTR | 626 | #ifdef CONFIG_EXT4_FS_XATTR |
@@ -1051,6 +1040,34 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino) | |||
1051 | (ino >= EXT4_FIRST_INO(sb) && | 1040 | (ino >= EXT4_FIRST_INO(sb) && |
1052 | ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)); | 1041 | ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count)); |
1053 | } | 1042 | } |
1043 | |||
1044 | /* | ||
1045 | * Inode dynamic state flags | ||
1046 | */ | ||
1047 | enum { | ||
1048 | EXT4_STATE_JDATA, /* journaled data exists */ | ||
1049 | EXT4_STATE_NEW, /* inode is newly created */ | ||
1050 | EXT4_STATE_XATTR, /* has in-inode xattrs */ | ||
1051 | EXT4_STATE_NO_EXPAND, /* No space for expansion */ | ||
1052 | EXT4_STATE_DA_ALLOC_CLOSE, /* Alloc DA blks on close */ | ||
1053 | EXT4_STATE_EXT_MIGRATE, /* Inode is migrating */ | ||
1054 | EXT4_STATE_DIO_UNWRITTEN, /* need convert on dio done*/ | ||
1055 | }; | ||
1056 | |||
1057 | static inline int ext4_test_inode_state(struct inode *inode, int bit) | ||
1058 | { | ||
1059 | return test_bit(bit, &EXT4_I(inode)->i_state_flags); | ||
1060 | } | ||
1061 | |||
1062 | static inline void ext4_set_inode_state(struct inode *inode, int bit) | ||
1063 | { | ||
1064 | set_bit(bit, &EXT4_I(inode)->i_state_flags); | ||
1065 | } | ||
1066 | |||
1067 | static inline void ext4_clear_inode_state(struct inode *inode, int bit) | ||
1068 | { | ||
1069 | clear_bit(bit, &EXT4_I(inode)->i_state_flags); | ||
1070 | } | ||
1054 | #else | 1071 | #else |
1055 | /* Assume that user mode programs are passing in an ext4fs superblock, not | 1072 | /* Assume that user mode programs are passing in an ext4fs superblock, not |
1056 | * a kernel struct super_block. This will allow us to call the feature-test | 1073 | * a kernel struct super_block. This will allow us to call the feature-test |