aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/xattr.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2010-01-06 15:58:48 -0500
committerJan Kara <jack@suse.cz>2010-03-04 18:20:20 -0500
commit9df93939b735dd273e49cbee290b9f4738500ef4 (patch)
tree2840172239e13d1c0fea496755b8346a9b394336 /fs/ext3/xattr.c
parent26245c949c8473ea7352907b5a54bc34487eb87f (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.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index 66895ccf76c..2d2fb2a8596 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);