diff options
author | Filipe Manana <fdmanana@gmail.com> | 2014-06-25 17:36:02 -0400 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2014-07-03 10:03:23 -0400 |
commit | 3cc79392558f1789e5e1d2fce44b681980f403c3 (patch) | |
tree | f0f71bc0170de156ec9b772ab886fa53c458746d /fs/btrfs/ioctl.c | |
parent | 472b909ff6f4884d235ef7b9d3847fad5efafbff (diff) |
Btrfs: atomically set inode->i_flags in btrfs_update_iflags
This change is based on the corresponding recent change for ext4:
ext4: atomically set inode->i_flags in ext4_set_inode_flags()
That has the following commit message that applies to btrfs as well:
"Use cmpxchg() to atomically set i_flags instead of clearing out the
S_IMMUTABLE, S_APPEND, etc. flags and then setting them from the
EXT4_IMMUTABLE_FL, EXT4_APPEND_FL flags, since this opens up a race
where an immutable file has the immutable flag cleared for a brief
window of time."
Replacing EXT4_IMMUTABLE_FL and EXT4_APPEND_FL with BTRFS_INODE_IMMUTABLE
and BTRFS_INODE_APPEND, respectively.
Reviewed-by: David Sterba <dsterba@suse.cz>
Reviewed-by: Satoru Takeuchi <takeuchi_satoru@jp.fujitsu.com>
Signed-off-by: Filipe David Borba Manana <fdmanana@gmail.com>
Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 6ea15469c63f..02dc64bbf1cb 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -136,19 +136,22 @@ static unsigned int btrfs_flags_to_ioctl(unsigned int flags) | |||
136 | void btrfs_update_iflags(struct inode *inode) | 136 | void btrfs_update_iflags(struct inode *inode) |
137 | { | 137 | { |
138 | struct btrfs_inode *ip = BTRFS_I(inode); | 138 | struct btrfs_inode *ip = BTRFS_I(inode); |
139 | 139 | unsigned int new_fl = 0; | |
140 | inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); | ||
141 | 140 | ||
142 | if (ip->flags & BTRFS_INODE_SYNC) | 141 | if (ip->flags & BTRFS_INODE_SYNC) |
143 | inode->i_flags |= S_SYNC; | 142 | new_fl |= S_SYNC; |
144 | if (ip->flags & BTRFS_INODE_IMMUTABLE) | 143 | if (ip->flags & BTRFS_INODE_IMMUTABLE) |
145 | inode->i_flags |= S_IMMUTABLE; | 144 | new_fl |= S_IMMUTABLE; |
146 | if (ip->flags & BTRFS_INODE_APPEND) | 145 | if (ip->flags & BTRFS_INODE_APPEND) |
147 | inode->i_flags |= S_APPEND; | 146 | new_fl |= S_APPEND; |
148 | if (ip->flags & BTRFS_INODE_NOATIME) | 147 | if (ip->flags & BTRFS_INODE_NOATIME) |
149 | inode->i_flags |= S_NOATIME; | 148 | new_fl |= S_NOATIME; |
150 | if (ip->flags & BTRFS_INODE_DIRSYNC) | 149 | if (ip->flags & BTRFS_INODE_DIRSYNC) |
151 | inode->i_flags |= S_DIRSYNC; | 150 | new_fl |= S_DIRSYNC; |
151 | |||
152 | set_mask_bits(&inode->i_flags, | ||
153 | S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC, | ||
154 | new_fl); | ||
152 | } | 155 | } |
153 | 156 | ||
154 | /* | 157 | /* |