diff options
author | Dmitry Monakhov <dmonakhov@openvz.org> | 2010-05-16 22:00:00 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2010-05-16 22:00:00 -0400 |
commit | 12e9b892002d9af057655d35b44db8ee9243b0dc (patch) | |
tree | c5831b4bcf98eebdd39158d08dab97c198f5c683 /fs/ext4/namei.c | |
parent | 24676da469f50f433baa347845639662c561d1f6 (diff) |
ext4: Use bitops to read/modify i_flags in struct ext4_inode_info
At several places we modify EXT4_I(inode)->i_flags without holding
i_mutex (ext4_do_update_inode, ...). These modifications are racy and
we can lose updates to i_flags. So convert handling of i_flags to use
bitops which are atomic.
https://bugzilla.kernel.org/show_bug.cgi?id=15792
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/namei.c')
-rw-r--r-- | fs/ext4/namei.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index bff77b04f0d1..7b4bf8feae4e 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -656,7 +656,7 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash, | |||
656 | dxtrace(printk(KERN_DEBUG "In htree_fill_tree, start hash: %x:%x\n", | 656 | dxtrace(printk(KERN_DEBUG "In htree_fill_tree, start hash: %x:%x\n", |
657 | start_hash, start_minor_hash)); | 657 | start_hash, start_minor_hash)); |
658 | dir = dir_file->f_path.dentry->d_inode; | 658 | dir = dir_file->f_path.dentry->d_inode; |
659 | if (!(EXT4_I(dir)->i_flags & EXT4_INDEX_FL)) { | 659 | if (!(ext4_test_inode_flag(dir, EXT4_INODE_INDEX))) { |
660 | hinfo.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version; | 660 | hinfo.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version; |
661 | if (hinfo.hash_version <= DX_HASH_TEA) | 661 | if (hinfo.hash_version <= DX_HASH_TEA) |
662 | hinfo.hash_version += | 662 | hinfo.hash_version += |
@@ -801,7 +801,7 @@ static void ext4_update_dx_flag(struct inode *inode) | |||
801 | { | 801 | { |
802 | if (!EXT4_HAS_COMPAT_FEATURE(inode->i_sb, | 802 | if (!EXT4_HAS_COMPAT_FEATURE(inode->i_sb, |
803 | EXT4_FEATURE_COMPAT_DIR_INDEX)) | 803 | EXT4_FEATURE_COMPAT_DIR_INDEX)) |
804 | EXT4_I(inode)->i_flags &= ~EXT4_INDEX_FL; | 804 | ext4_clear_inode_flag(inode, EXT4_INODE_INDEX); |
805 | } | 805 | } |
806 | 806 | ||
807 | /* | 807 | /* |
@@ -1416,7 +1416,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, | |||
1416 | brelse(bh); | 1416 | brelse(bh); |
1417 | return retval; | 1417 | return retval; |
1418 | } | 1418 | } |
1419 | EXT4_I(dir)->i_flags |= EXT4_INDEX_FL; | 1419 | ext4_set_inode_flag(dir, EXT4_INODE_INDEX); |
1420 | data1 = bh2->b_data; | 1420 | data1 = bh2->b_data; |
1421 | 1421 | ||
1422 | memcpy (data1, de, len); | 1422 | memcpy (data1, de, len); |
@@ -1489,7 +1489,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry, | |||
1489 | retval = ext4_dx_add_entry(handle, dentry, inode); | 1489 | retval = ext4_dx_add_entry(handle, dentry, inode); |
1490 | if (!retval || (retval != ERR_BAD_DX_DIR)) | 1490 | if (!retval || (retval != ERR_BAD_DX_DIR)) |
1491 | return retval; | 1491 | return retval; |
1492 | EXT4_I(dir)->i_flags &= ~EXT4_INDEX_FL; | 1492 | ext4_clear_inode_flag(dir, EXT4_INODE_INDEX); |
1493 | dx_fallback++; | 1493 | dx_fallback++; |
1494 | ext4_mark_inode_dirty(handle, dir); | 1494 | ext4_mark_inode_dirty(handle, dir); |
1495 | } | 1495 | } |
@@ -2294,7 +2294,7 @@ retry: | |||
2294 | } | 2294 | } |
2295 | } else { | 2295 | } else { |
2296 | /* clear the extent format for fast symlink */ | 2296 | /* clear the extent format for fast symlink */ |
2297 | EXT4_I(inode)->i_flags &= ~EXT4_EXTENTS_FL; | 2297 | ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS); |
2298 | inode->i_op = &ext4_fast_symlink_inode_operations; | 2298 | inode->i_op = &ext4_fast_symlink_inode_operations; |
2299 | memcpy((char *)&EXT4_I(inode)->i_data, symname, l); | 2299 | memcpy((char *)&EXT4_I(inode)->i_data, symname, l); |
2300 | inode->i_size = l-1; | 2300 | inode->i_size = l-1; |