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 /fs/ext3/xattr.c | |
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 'fs/ext3/xattr.c')
-rw-r--r-- | fs/ext3/xattr.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index 66895ccf76c7..2d2fb2a85961 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c | |||
@@ -274,7 +274,7 @@ ext3_xattr_ibody_get(struct inode *inode, int name_index, const char *name, | |||
274 | void *end; | 274 | void *end; |
275 | int error; | 275 | int error; |
276 | 276 | ||
277 | if (!(EXT3_I(inode)->i_state & EXT3_STATE_XATTR)) | 277 | if (!ext3_test_inode_state(inode, EXT3_STATE_XATTR)) |
278 | return -ENODATA; | 278 | return -ENODATA; |
279 | error = ext3_get_inode_loc(inode, &iloc); | 279 | error = ext3_get_inode_loc(inode, &iloc); |
280 | if (error) | 280 | if (error) |
@@ -403,7 +403,7 @@ ext3_xattr_ibody_list(struct dentry *dentry, char *buffer, size_t buffer_size) | |||
403 | void *end; | 403 | void *end; |
404 | int error; | 404 | int error; |
405 | 405 | ||
406 | if (!(EXT3_I(inode)->i_state & EXT3_STATE_XATTR)) | 406 | if (!ext3_test_inode_state(inode, EXT3_STATE_XATTR)) |
407 | return 0; | 407 | return 0; |
408 | error = ext3_get_inode_loc(inode, &iloc); | 408 | error = ext3_get_inode_loc(inode, &iloc); |
409 | if (error) | 409 | if (error) |
@@ -882,7 +882,7 @@ ext3_xattr_ibody_find(struct inode *inode, struct ext3_xattr_info *i, | |||
882 | is->s.base = is->s.first = IFIRST(header); | 882 | is->s.base = is->s.first = IFIRST(header); |
883 | is->s.here = is->s.first; | 883 | is->s.here = is->s.first; |
884 | is->s.end = (void *)raw_inode + EXT3_SB(inode->i_sb)->s_inode_size; | 884 | is->s.end = (void *)raw_inode + EXT3_SB(inode->i_sb)->s_inode_size; |
885 | if (EXT3_I(inode)->i_state & EXT3_STATE_XATTR) { | 885 | if (ext3_test_inode_state(inode, EXT3_STATE_XATTR)) { |
886 | error = ext3_xattr_check_names(IFIRST(header), is->s.end); | 886 | error = ext3_xattr_check_names(IFIRST(header), is->s.end); |
887 | if (error) | 887 | if (error) |
888 | return error; | 888 | return error; |
@@ -914,10 +914,10 @@ ext3_xattr_ibody_set(handle_t *handle, struct inode *inode, | |||
914 | header = IHDR(inode, ext3_raw_inode(&is->iloc)); | 914 | header = IHDR(inode, ext3_raw_inode(&is->iloc)); |
915 | if (!IS_LAST_ENTRY(s->first)) { | 915 | if (!IS_LAST_ENTRY(s->first)) { |
916 | header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC); | 916 | header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC); |
917 | EXT3_I(inode)->i_state |= EXT3_STATE_XATTR; | 917 | ext3_set_inode_state(inode, EXT3_STATE_XATTR); |
918 | } else { | 918 | } else { |
919 | header->h_magic = cpu_to_le32(0); | 919 | header->h_magic = cpu_to_le32(0); |
920 | EXT3_I(inode)->i_state &= ~EXT3_STATE_XATTR; | 920 | ext3_clear_inode_state(inode, EXT3_STATE_XATTR); |
921 | } | 921 | } |
922 | return 0; | 922 | return 0; |
923 | } | 923 | } |
@@ -967,10 +967,10 @@ ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index, | |||
967 | if (error) | 967 | if (error) |
968 | goto cleanup; | 968 | goto cleanup; |
969 | 969 | ||
970 | if (EXT3_I(inode)->i_state & EXT3_STATE_NEW) { | 970 | if (ext3_test_inode_state(inode, EXT3_STATE_NEW)) { |
971 | struct ext3_inode *raw_inode = ext3_raw_inode(&is.iloc); | 971 | struct ext3_inode *raw_inode = ext3_raw_inode(&is.iloc); |
972 | memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size); | 972 | memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size); |
973 | EXT3_I(inode)->i_state &= ~EXT3_STATE_NEW; | 973 | ext3_clear_inode_state(inode, EXT3_STATE_NEW); |
974 | } | 974 | } |
975 | 975 | ||
976 | error = ext3_xattr_ibody_find(inode, &i, &is); | 976 | error = ext3_xattr_ibody_find(inode, &i, &is); |