diff options
author | Dmitry Monakhov <dmonakhov@openvz.org> | 2010-06-05 11:51:27 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2010-06-05 11:51:27 -0400 |
commit | 84a8dce2710cc425089a2b92acc354d4fbb5788d (patch) | |
tree | 2d83f638d52326b6a8080a26aa1423fa28b38ff1 /fs/ext4 | |
parent | 1f5a81e41f8b1a782c68d3843e9ec1bfaadf7d72 (diff) |
ext4: Fix remaining racy updates of EXT4_I(inode)->i_flags
A few functions were still modifying i_flags in a racy manner.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/inode.c | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 19df61c321fd..42272d67955a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -4942,20 +4942,26 @@ void ext4_set_inode_flags(struct inode *inode) | |||
4942 | /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */ | 4942 | /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */ |
4943 | void ext4_get_inode_flags(struct ext4_inode_info *ei) | 4943 | void ext4_get_inode_flags(struct ext4_inode_info *ei) |
4944 | { | 4944 | { |
4945 | unsigned int flags = ei->vfs_inode.i_flags; | 4945 | unsigned int vfs_fl; |
4946 | 4946 | unsigned long old_fl, new_fl; | |
4947 | ei->i_flags &= ~(EXT4_SYNC_FL|EXT4_APPEND_FL| | 4947 | |
4948 | EXT4_IMMUTABLE_FL|EXT4_NOATIME_FL|EXT4_DIRSYNC_FL); | 4948 | do { |
4949 | if (flags & S_SYNC) | 4949 | vfs_fl = ei->vfs_inode.i_flags; |
4950 | ei->i_flags |= EXT4_SYNC_FL; | 4950 | old_fl = ei->i_flags; |
4951 | if (flags & S_APPEND) | 4951 | new_fl = old_fl & ~(EXT4_SYNC_FL|EXT4_APPEND_FL| |
4952 | ei->i_flags |= EXT4_APPEND_FL; | 4952 | EXT4_IMMUTABLE_FL|EXT4_NOATIME_FL| |
4953 | if (flags & S_IMMUTABLE) | 4953 | EXT4_DIRSYNC_FL); |
4954 | ei->i_flags |= EXT4_IMMUTABLE_FL; | 4954 | if (vfs_fl & S_SYNC) |
4955 | if (flags & S_NOATIME) | 4955 | new_fl |= EXT4_SYNC_FL; |
4956 | ei->i_flags |= EXT4_NOATIME_FL; | 4956 | if (vfs_fl & S_APPEND) |
4957 | if (flags & S_DIRSYNC) | 4957 | new_fl |= EXT4_APPEND_FL; |
4958 | ei->i_flags |= EXT4_DIRSYNC_FL; | 4958 | if (vfs_fl & S_IMMUTABLE) |
4959 | new_fl |= EXT4_IMMUTABLE_FL; | ||
4960 | if (vfs_fl & S_NOATIME) | ||
4961 | new_fl |= EXT4_NOATIME_FL; | ||
4962 | if (vfs_fl & S_DIRSYNC) | ||
4963 | new_fl |= EXT4_DIRSYNC_FL; | ||
4964 | } while (cmpxchg(&ei->i_flags, old_fl, new_fl) != old_fl); | ||
4959 | } | 4965 | } |
4960 | 4966 | ||
4961 | static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode, | 4967 | static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode, |
@@ -5191,7 +5197,7 @@ static int ext4_inode_blocks_set(handle_t *handle, | |||
5191 | */ | 5197 | */ |
5192 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); | 5198 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); |
5193 | raw_inode->i_blocks_high = 0; | 5199 | raw_inode->i_blocks_high = 0; |
5194 | ei->i_flags &= ~EXT4_HUGE_FILE_FL; | 5200 | ext4_clear_inode_flag(inode, EXT4_INODE_HUGE_FILE); |
5195 | return 0; | 5201 | return 0; |
5196 | } | 5202 | } |
5197 | if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) | 5203 | if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) |
@@ -5204,9 +5210,9 @@ static int ext4_inode_blocks_set(handle_t *handle, | |||
5204 | */ | 5210 | */ |
5205 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); | 5211 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); |
5206 | raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32); | 5212 | raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32); |
5207 | ei->i_flags &= ~EXT4_HUGE_FILE_FL; | 5213 | ext4_clear_inode_flag(inode, EXT4_INODE_HUGE_FILE); |
5208 | } else { | 5214 | } else { |
5209 | ei->i_flags |= EXT4_HUGE_FILE_FL; | 5215 | ext4_set_inode_flag(inode, EXT4_INODE_HUGE_FILE); |
5210 | /* i_block is stored in file system block size */ | 5216 | /* i_block is stored in file system block size */ |
5211 | i_blocks = i_blocks >> (inode->i_blkbits - 9); | 5217 | i_blocks = i_blocks >> (inode->i_blkbits - 9); |
5212 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); | 5218 | raw_inode->i_blocks_lo = cpu_to_le32(i_blocks); |